Bladeren bron

scale method for 3d objects

Falko Schindler 3 jaren geleden
bovenliggende
commit
ae51c46355
3 gewijzigde bestanden met toevoegingen van 31 en 5 verwijderingen
  1. 6 4
      main.py
  2. 4 1
      nicegui/elements/scene.js
  3. 21 0
      nicegui/elements/scene_object3d.py

+ 6 - 4
main.py

@@ -275,7 +275,7 @@ with example(ui.scene):
     with ui.scene(width=200, height=200) as scene:
         scene.sphere().material('#4488ff')
         scene.cylinder(1, 0.5, 2, 20).material('#ff8800', opacity=0.5).move(-2, 1)
-        scene.extrusion([[0, 0], [1, 0], [1, 1], [0, 1]], 0.1).material('#ff8888').move(-2, -2)
+        scene.extrusion([[0, 0], [0, 1], [1, 0.5]], 0.1).material('#ff8888').move(-2, -2)
 
         with scene.group().move(z=2):
             box1 = scene.box().move(x=2)
@@ -285,9 +285,11 @@ with example(ui.scene):
         scene.line([-4, 0, 0], [-4, 2, 0]).material('#ff0000')
         scene.curve([-4, -2, 0], [-4, -1, 0], [-3, -1, 0], [-3, 0, 0]).material('#008800')
 
-        scene.texture("https://avatars.githubusercontent.com/u/2843826",
-                      [[[0, 3, 0], [3, 3, 0]],
-                       [[0, 0, 0], [3, 0, 0]]]).move(1, -2)
+        logo = "https://avatars.githubusercontent.com/u/2843826"
+        scene.texture(logo, [[[0, 3, 0], [3, 3, 0]], [[0, 0, 0], [3, 0, 0]]]).move(1, -2)
+
+        teapot = 'https://upload.wikimedia.org/wikipedia/commons/9/93/Utah_teapot_(solid).stl'
+        scene.stl(teapot).scale(0.2).move(-3, 4)
 
 with example(ui.joystick):
 

+ 4 - 1
nicegui/elements/scene.js

@@ -191,7 +191,7 @@ Vue.component("scene", {
         }
         if (type == "stl") {
           const url = args[0];
-          geometry = new THREE.BoxGeometry();
+          geometry = new THREE.BufferGeometry();
           stl_loader.load(url, (geometry) => (mesh.geometry = geometry));
         }
         let material;
@@ -218,6 +218,9 @@ Vue.component("scene", {
     move(object_id, x, y, z) {
       objects.get(object_id).position.set(x, y, z);
     },
+    scale(object_id, sx, sy, sz) {
+      objects.get(object_id).scale.set(sx, sy, sz);
+    },
     rotate(object_id, R) {
       const R4 = new THREE.Matrix4().makeBasis(
         new THREE.Vector3(...R[0]),

+ 21 - 0
nicegui/elements/scene_object3d.py

@@ -1,5 +1,6 @@
 from __future__ import annotations
 import asyncio
+from typing import Optional
 import uuid
 import numpy as np
 from justpy.htmlcomponents import WebPage
@@ -22,6 +23,9 @@ class Object3D:
         self.y = 0
         self.z = 0
         self.R = [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
+        self.sx = 1
+        self.sy = 1
+        self.sz = 1
         self.run_command(self._create_command)
         self.view.objects[self.id] = self
 
@@ -39,6 +43,7 @@ class Object3D:
         self.run_command(self._material_command, socket)
         self.run_command(self._move_command, socket)
         self.run_command(self._rotate_command, socket)
+        self.run_command(self._scale_command, socket)
 
     def __enter__(self):
         self.stack.append(self)
@@ -63,6 +68,10 @@ class Object3D:
     def _rotate_command(self):
         return f'rotate("{self.id}", {self.R})'
 
+    @property
+    def _scale_command(self):
+        return f'scale("{self.id}", {self.sx}, {self.sy}, {self.sz})'
+
     @property
     def _delete_command(self):
         return f'delete("{self.id}")'
@@ -92,6 +101,18 @@ class Object3D:
             self.run_command(self._rotate_command)
         return self
 
+    def scale(self, sx: float = 1.0, sy: Optional[float] = None, sz: Optional[float] = None):
+        if sy is None:
+            sy = sx
+        if sz is None:
+            sz = sx
+        if self.sx != sx or self.sy != sy or self.sz != sz:
+            self.sx = sx
+            self.sy = sy
+            self.sz = sz
+            self.run_command(self._scale_command)
+        return self
+
     def delete(self):
         del self.view.objects[self.id]
         self.run_command(self._delete_command)