scene.py 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. from typing import Callable
  2. import traceback
  3. from .element import Element
  4. from .custom_view import CustomView
  5. from .page import Page
  6. from .scene_object3d import Object3D
  7. from ..globals import view_stack
  8. class SceneView(CustomView):
  9. def __init__(self, *, width: int, height: int, on_click: Callable):
  10. dependencies = ['three.min.js', 'OrbitControls.js', 'STLLoader.js']
  11. super().__init__('scene', __file__, dependencies, width=width, height=height)
  12. self.on_click = on_click
  13. self.allowed_events = ['onConnect', 'onClick']
  14. self.initialize(temp=False, onConnect=self.handle_connect, onClick=self.handle_click)
  15. self.objects = {}
  16. def handle_connect(self, msg):
  17. try:
  18. for object in self.objects.values():
  19. object.send_to(msg.websocket)
  20. except:
  21. traceback.print_exc()
  22. def handle_click(self, msg):
  23. try:
  24. for hit in msg.hits:
  25. hit.object = self.objects.get(hit.object_id)
  26. if self.on_click is not None:
  27. return self.on_click(msg)
  28. return False
  29. except:
  30. traceback.print_exc()
  31. class Scene(Element):
  32. from .scene_objects import Group as group
  33. from .scene_objects import Box as box
  34. from .scene_objects import Sphere as sphere
  35. from .scene_objects import Cylinder as cylinder
  36. from .scene_objects import Extrusion as extrusion
  37. from .scene_objects import Stl as stl
  38. from .scene_objects import Line as line
  39. from .scene_objects import Curve as curve
  40. from .scene_objects import Texture as texture
  41. def __init__(self, width: int = 400, height: int = 300, on_click: Callable = None):
  42. """3D Scene
  43. Display a 3d scene using `three.js <https://threejs.org/>`_.
  44. Currently NiceGUI supports boxes, spheres, cylinders/cones, extrusions, straight lines, curves and textured meshes.
  45. Objects can be translated, rotated and displayed with different color, opacity or as wireframes.
  46. They can also be grouped to apply joint movements.
  47. :param width: width of the canvas
  48. :param height: height of the canvas
  49. :param on_click: callback to execute when a 3d object is clicked
  50. """
  51. super().__init__(SceneView(width=width, height=height, on_click=on_click))
  52. def __enter__(self):
  53. view_stack.append(self.view)
  54. scene = self.view.objects.get('scene', SceneObject(self.view, self.page))
  55. Object3D.stack.clear()
  56. Object3D.stack.append(scene)
  57. return self
  58. def __exit__(self, *_):
  59. view_stack.pop()
  60. class SceneObject:
  61. def __init__(self, view: SceneView, page: Page):
  62. self.id = 'scene'
  63. self.view = view
  64. self.page = page