Source code for Karana.KUtils.vizutils._axes

# Copyright (c) 2024-2026 Karana Dynamics Pty Ltd. All rights reserved.
#
# NOTICE TO USER:
#
# This source code and/or documentation (the "Licensed Materials") is
# the confidential and proprietary information of Karana Dynamics Inc.
# Use of these Licensed Materials is governed by the terms and conditions
# of a separate software license agreement between Karana Dynamics and the
# Licensee ("License Agreement"). Unless expressly permitted under that
# agreement, any reproduction, modification, distribution, or disclosure
# of the Licensed Materials, in whole or in part, to any third party
# without the prior written consent of Karana Dynamics is strictly prohibited.
#
# THE LICENSED MATERIALS ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND.
# KARANA DYNAMICS DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
# BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY, NON-INFRINGEMENT, AND
# FITNESS FOR A PARTICULAR PURPOSE.
#
# IN NO EVENT SHALL KARANA DYNAMICS BE LIABLE FOR ANY DAMAGES WHATSOEVER,
# INCLUDING BUT NOT LIMITED TO LOSS OF PROFITS, DATA, OR USE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, WHETHER IN CONTRACT, TORT,
# OR OTHERWISE ARISING OUT OF OR IN CONNECTION WITH THE LICENSED MATERIALS.
#
# U.S. Government End Users: The Licensed Materials are a "commercial item"
# as defined at 48 C.F.R. 2.101, and are provided to the U.S. Government
# only as a commercial end item under the terms of this license.
#
# Any use of the Licensed Materials in individual or commercial software must
# include, in the user documentation and internal source code comments,
# this Notice, Disclaimer, and U.S. Government Use Provision.

import Karana.Scene as ks
import Karana.Math as km
import Karana.Core as kc


[docs] class Axes3d: """Create a 3d axes visualization.""" @property def name(self) -> str: """Get the name of the Axes3d. Returns ------- str The name """ return self._name @property def node(self) -> ks.ProxySceneNode: """Get the base node of the axes. Returns ------- ks.ProxySceneNode The node """ if nd := self._node(): return nd else: raise ValueError("The underlying ProxySceneNode has been removed.") def __init__(self, name: str, scene: ks.ProxyScene, length: float = 1.0, radius: float = 0.1): """Create an Axes3d. Parameters ---------- name: str Name of the Axes3d scene: ks.ProxyScene Scene to create the parts in. length: float Length of each axis. Defaults to 1. radius: float Radius of each axis. Defaults to 0.1. """ self._name = name node = ks.ProxySceneNode(f"{name}_node", scene) self._node = kc.CppWeakRef(node) # Create geometries cone_length = radius cylinder_length = length - cone_length cylinder = ks.CylinderGeometry(radius=0.5 * radius, height=cylinder_length) cone = ks.ConeGeometry(radius=radius, height=cone_length) # Create rgb emissive materials mat_info = ks.PhongMaterialInfo() mat_info.color = ks.Color.BLACK mat_info.ambient_color = ks.Color.BLACK # add some shininess mat_info.specular_color = ks.Color.fromHex("444444") mat_info.emissive_color = ks.Color.RED red = ks.PhongMaterial(mat_info) mat_info.emissive_color = ks.Color.GREEN green = ks.PhongMaterial(mat_info) mat_info.emissive_color = ks.Color.BLUE blue = ks.PhongMaterial(mat_info) # Quaternions to reorient parts y2x = km.UnitQuaternion([0, 1, 0], [1, 0, 0]) y2z = km.UnitQuaternion([0, 1, 0], [0, 0, 1]) # Offsets to position part centers relative to parent cyl_offset = cylinder_length / 2 cone_offset = cylinder_length + cone_length / 2 # x cylinder part x_cyl = ks.ProxyScenePart(f"{name}_xcyl", scene, cylinder, red, layers=ks.LAYER_ORNAMENTAL) x_cyl.attachTo(node) x_cyl.setUnitQuaternion(y2x) x_cyl.setTranslation([cyl_offset, 0, 0]) # x cone part x_cone = ks.ProxyScenePart(f"{name}_xcone", scene, cone, red, layers=ks.LAYER_ORNAMENTAL) x_cone.attachTo(node) x_cone.setUnitQuaternion(y2x) x_cone.setTranslation([cone_offset, 0, 0]) # y cylinder part y_cyl = ks.ProxyScenePart( f"{name}_ycyl", scene, cylinder, green, layers=ks.LAYER_ORNAMENTAL ) y_cyl.attachTo(node) y_cyl.setTranslation([0, cyl_offset, 0]) # y cone part y_cone = ks.ProxyScenePart(f"{name}_ycone", scene, cone, green, layers=ks.LAYER_ORNAMENTAL) y_cone.attachTo(node) y_cone.setTranslation([0, cone_offset, 0]) # z cylinder part z_cyl = ks.ProxyScenePart(f"{name}_zcyl", scene, cylinder, blue, layers=ks.LAYER_ORNAMENTAL) z_cyl.attachTo(node) z_cyl.setUnitQuaternion(y2z) z_cyl.setTranslation([0, 0, cyl_offset]) # z cone part z_cone = ks.ProxyScenePart(f"{name}_zcone", scene, cone, blue, layers=ks.LAYER_ORNAMENTAL) z_cone.attachTo(node) z_cone.setUnitQuaternion(y2z) z_cone.setTranslation([0, 0, cone_offset])