Преглед изворни кода

Add coordinate_system object (#3547)

* Add coordinate_system object

* Replace coordinate_system with ThreeJS AxesHelper

* Add CoodinateSystem as example for a composed 3d object

* code review

---------

Co-authored-by: Andreas Voigt <andreas.voigt@optonic.com>
Co-authored-by: Falko Schindler <falko@zauberzeug.com>
Voigta пре 8 месеци
родитељ
комит
1934da0fc1

+ 3 - 0
nicegui/elements/scene.js

@@ -279,6 +279,9 @@ export default {
           undefined,
           undefined,
           (error) => console.error(error)
           (error) => console.error(error)
         );
         );
+      } else if (type == "axes_helper") {
+        mesh = new THREE.AxesHelper(args[0]);
+        mesh.material.transparent = true;
       } else {
       } else {
         let geometry;
         let geometry;
         const wireframe = args.pop();
         const wireframe = args.pop();

+ 1 - 0
nicegui/elements/scene.py

@@ -51,6 +51,7 @@ class Scene(Element,
                 'lib/tween/tween.umd.js',
                 'lib/tween/tween.umd.js',
             ]):
             ]):
     # pylint: disable=import-outside-toplevel
     # pylint: disable=import-outside-toplevel
+    from .scene_objects import AxesHelper as axes_helper
     from .scene_objects import Box as box
     from .scene_objects import Box as box
     from .scene_objects import Curve as curve
     from .scene_objects import Curve as curve
     from .scene_objects import Cylinder as cylinder
     from .scene_objects import Cylinder as cylinder

+ 18 - 0
nicegui/elements/scene_objects.py

@@ -335,3 +335,21 @@ class PointCloud(Object3D):
         self.args[0] = points
         self.args[0] = points
         self.args[1] = colors
         self.args[1] = colors
         self.scene.run_method('set_points', self.id, points, colors)
         self.scene.run_method('set_points', self.id, points, colors)
+
+
+class AxesHelper(Object3D):
+
+    def __init__(self,
+                 length: float = 1.0,
+                 ) -> None:
+        """Axes Helper
+
+        This element is based on Three.js' `AxesHelper <https://threejs.org/docs/#api/en/helpers/AxesHelper>`_ object.
+        It is used to visualize the XYZ axes:
+        The X axis is red.
+        The Y axis is green.
+        The Z axis is blue.
+
+        :param length: length of the the axes (default: 1.0)
+        """
+        super().__init__('axes_helper', length)

+ 34 - 1
website/documentation/content/scene_documentation.py

@@ -6,7 +6,8 @@ from . import doc
 @doc.demo(ui.scene)
 @doc.demo(ui.scene)
 def main_demo() -> None:
 def main_demo() -> None:
     with ui.scene().classes('w-full h-64') as scene:
     with ui.scene().classes('w-full h-64') as scene:
-        scene.sphere().material('#4488ff')
+        scene.axes_helper()
+        scene.sphere().material('#4488ff').move(2, 2)
         scene.cylinder(1, 0.5, 2, 20).material('#ff8800', opacity=0.5).move(-2, 1)
         scene.cylinder(1, 0.5, 2, 20).material('#ff8800', opacity=0.5).move(-2, 1)
         scene.extrusion([[0, 0], [0, 1], [1, 0.5]], 0.1).material('#ff8888').move(2, -1)
         scene.extrusion([[0, 0], [0, 1], [1, 0.5]], 0.1).material('#ff8888').move(2, -1)
 
 
@@ -235,4 +236,36 @@ def custom_grid() -> None:
         scene.sphere()
         scene.sphere()
 
 
 
 
+@doc.demo('Custom Composed 3D Objects', '''
+    This demo creates a custom class for visualizing a coordinate system with colored X, Y and Z axes.
+    This can be a nice alternative to the default `axes_helper` object.
+''')
+def custom_composed_objects() -> None:
+    import math
+
+    class CoordinateSystem(ui.scene.group):
+
+        def __init__(self, name: str, *, length: float = 1.0) -> None:
+            super().__init__()
+
+            with self:
+                for label, color, rx, ry, rz in [
+                    ('x', '#ff0000', 0, 0, -math.pi / 2),
+                    ('y', '#00ff00', 0, 0, 0),
+                    ('z', '#0000ff', math.pi / 2, 0, 0),
+                ]:
+                    with ui.scene.group().rotate(rx, ry, rz):
+                        ui.scene.cylinder(0.02 * length, 0.02 * length, 0.8 * length) \
+                            .move(y=0.4 * length).material(color)
+                        ui.scene.cylinder(0, 0.1 * length, 0.2 * length) \
+                            .move(y=0.9 * length).material(color)
+                        ui.scene.text(label, style=f'color: {color}') \
+                            .move(y=1.1 * length)
+                ui.scene.text(name, style='color: #808080')
+
+    with ui.scene().classes('w-full h-64'):
+        CoordinateSystem('origin')
+        CoordinateSystem('custom frame').move(-2, -2, 1).rotate(0.1, 0.2, 0.3)
+
+
 doc.reference(ui.scene)
 doc.reference(ui.scene)