scene_objects.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. import math
  2. from typing import List, Optional
  3. from .scene_object3d import Object3D
  4. class Group(Object3D):
  5. def __init__(self) -> None:
  6. """Group
  7. This element is based on Three.js' `Group <https://threejs.org/docs/index.html#api/en/objects/Group>`_ object.
  8. It is used to group objects together.
  9. """
  10. super().__init__('group')
  11. class Box(Object3D):
  12. def __init__(self,
  13. width: float = 1.0,
  14. height: float = 1.0,
  15. depth: float = 1.0,
  16. wireframe: bool = False,
  17. ) -> None:
  18. """Box
  19. This element is based on Three.js' `BoxGeometry <https://threejs.org/docs/index.html#api/en/geometries/BoxGeometry>`_ object.
  20. It is used to create a box-shaped mesh.
  21. :param width: width of the box (default: 1.0)
  22. :param height: height of the box (default: 1.0)
  23. :param depth: depth of the box (default: 1.0)
  24. :param wireframe: whether to display the box as a wireframe (default: `False`)
  25. """
  26. super().__init__('box', width, height, depth, wireframe)
  27. class Sphere(Object3D):
  28. def __init__(self,
  29. radius: float = 1.0,
  30. width_segments: int = 32,
  31. height_segments: int = 16,
  32. wireframe: bool = False,
  33. ) -> None:
  34. """Sphere
  35. This element is based on Three.js' `SphereGeometry <https://threejs.org/docs/index.html#api/en/geometries/SphereGeometry>`_ object.
  36. It is used to create a sphere-shaped mesh.
  37. :param radius: radius of the sphere (default: 1.0)
  38. :param width_segments: number of horizontal segments (default: 32)
  39. :param height_segments: number of vertical segments (default: 16)
  40. :param wireframe: whether to display the sphere as a wireframe (default: `False`)
  41. """
  42. super().__init__('sphere', radius, width_segments, height_segments, wireframe)
  43. class Cylinder(Object3D):
  44. def __init__(self,
  45. top_radius: float = 1.0,
  46. bottom_radius: float = 1.0,
  47. height: float = 1.0,
  48. radial_segments: int = 8,
  49. height_segments: int = 1,
  50. wireframe: bool = False,
  51. ) -> None:
  52. """Cylinder
  53. This element is based on Three.js' `CylinderGeometry <https://threejs.org/docs/index.html#api/en/geometries/CylinderGeometry>`_ object.
  54. It is used to create a cylinder-shaped mesh.
  55. :param top_radius: radius of the top (default: 1.0)
  56. :param bottom_radius: radius of the bottom (default: 1.0)
  57. :param height: height of the cylinder (default: 1.0)
  58. :param radial_segments: number of horizontal segments (default: 8)
  59. :param height_segments: number of vertical segments (default: 1)
  60. :param wireframe: whether to display the cylinder as a wireframe (default: `False`)
  61. """
  62. super().__init__('cylinder', top_radius, bottom_radius, height, radial_segments, height_segments, wireframe)
  63. class Ring(Object3D):
  64. def __init__(self,
  65. inner_radius: float = 0.5,
  66. outer_radius: float = 1.0,
  67. theta_segments: int = 8,
  68. phi_segments: int = 1,
  69. theta_start: float = 0,
  70. theta_length: float = 2 * math.pi,
  71. wireframe: bool = False,
  72. ) -> None:
  73. """Ring
  74. This element is based on Three.js' `RingGeometry <https://threejs.org/docs/index.html#api/en/geometries/RingGeometry>`_ object.
  75. It is used to create a ring-shaped mesh.
  76. :param inner_radius: inner radius of the ring (default: 0.5)
  77. :param outer_radius: outer radius of the ring (default: 1.0)
  78. :param theta_segments: number of horizontal segments (default: 8, higher means rounder)
  79. :param phi_segments: number of vertical segments (default: 1)
  80. :param theta_start: start angle in radians (default: 0)
  81. :param theta_length: central angle in radians (default: 2π)
  82. :param wireframe: whether to display the ring as a wireframe (default: `False`)
  83. """
  84. super().__init__('ring',
  85. inner_radius, outer_radius, theta_segments, phi_segments, theta_start, theta_length, wireframe)
  86. class QuadraticBezierTube(Object3D):
  87. def __init__(self,
  88. start: List[float],
  89. mid: List[float],
  90. end: List[float],
  91. tubular_segments: int = 64,
  92. radius: float = 1.0,
  93. radial_segments: int = 8,
  94. closed: bool = False,
  95. wireframe: bool = False,
  96. ) -> None:
  97. """Quadratic Bezier Tube
  98. This element is based on Three.js' `QuadraticBezierCurve3 <https://threejs.org/docs/index.html#api/en/extras/curves/QuadraticBezierCurve3>`_ object.
  99. It is used to create a tube-shaped mesh.
  100. :param start: start point of the curve
  101. :param mid: middle point of the curve
  102. :param end: end point of the curve
  103. :param tubular_segments: number of tubular segments (default: 64)
  104. :param radius: radius of the tube (default: 1.0)
  105. :param radial_segments: number of radial segments (default: 8)
  106. :param closed: whether the tube should be closed (default: `False`)
  107. :param wireframe: whether to display the tube as a wireframe (default: `False`)
  108. """
  109. super().__init__('quadratic_bezier_tube',
  110. start, mid, end, tubular_segments, radius, radial_segments, closed, wireframe)
  111. class Extrusion(Object3D):
  112. def __init__(self,
  113. outline: List[List[float]],
  114. height: float,
  115. wireframe: bool = False,
  116. ) -> None:
  117. """Extrusion
  118. This element is based on Three.js' `ExtrudeGeometry <https://threejs.org/docs/index.html#api/en/geometries/ExtrudeGeometry>`_ object.
  119. It is used to create a 3D shape by extruding a 2D shape to a given height.
  120. :param outline: list of points defining the outline of the 2D shape
  121. :param height: height of the extrusion
  122. :param wireframe: whether to display the extrusion as a wireframe (default: `False`)
  123. """
  124. super().__init__('extrusion', outline, height, wireframe)
  125. class Stl(Object3D):
  126. def __init__(self,
  127. url: str,
  128. wireframe: bool = False,
  129. ) -> None:
  130. """STL
  131. This element is used to create a mesh from an STL file.
  132. :param url: URL of the STL file
  133. :param wireframe: whether to display the STL as a wireframe (default: `False`)
  134. """
  135. super().__init__('stl', url, wireframe)
  136. class Line(Object3D):
  137. def __init__(self,
  138. start: List[float],
  139. end: List[float],
  140. ) -> None:
  141. """Line
  142. This element is based on Three.js' `Line <https://threejs.org/docs/index.html#api/en/objects/Line>`_ object.
  143. It is used to create a line segment.
  144. :param start: start point of the line
  145. :param end: end point of the line
  146. """
  147. super().__init__('line', start, end)
  148. class Curve(Object3D):
  149. def __init__(self,
  150. start: List[float],
  151. control1: List[float],
  152. control2: List[float],
  153. end: List[float],
  154. num_points: int = 20,
  155. ) -> None:
  156. """Curve
  157. This element is based on Three.js' `CubicBezierCurve3 <https://threejs.org/docs/index.html#api/en/extras/curves/CubicBezierCurve3>`_ object.
  158. :param start: start point of the curve
  159. :param control1: first control point of the curve
  160. :param control2: second control point of the curve
  161. :param end: end point of the curve
  162. :param num_points: number of points to use for the curve (default: 20)
  163. """
  164. super().__init__('curve', start, control1, control2, end, num_points)
  165. class Text(Object3D):
  166. def __init__(self,
  167. text: str,
  168. style: str = '',
  169. ) -> None:
  170. """Text
  171. This element is used to add 2D text to the scene.
  172. It can be moved like any other object, but always faces the camera.
  173. :param text: text to display
  174. :param style: CSS style (default: '')
  175. """
  176. super().__init__('text', text, style)
  177. class Text3d(Object3D):
  178. def __init__(self,
  179. text: str,
  180. style: str = '',
  181. ) -> None:
  182. """3D Text
  183. This element is used to add a 3D text mesh to the scene.
  184. It can be moved and rotated like any other object.
  185. :param text: text to display
  186. :param style: CSS style (default: '')
  187. """
  188. super().__init__('text3d', text, style)
  189. class Texture(Object3D):
  190. def __init__(self,
  191. url: str,
  192. coordinates: List[List[Optional[List[float]]]],
  193. ) -> None:
  194. """Texture
  195. This element is used to add a texture to a mesh.
  196. :param url: URL of the texture image
  197. :param coordinates: texture coordinates
  198. """
  199. super().__init__('texture', url, coordinates)
  200. def set_url(self, url: str) -> None:
  201. """Change the URL of the texture image."""
  202. self.args[0] = url
  203. self.scene.run_method('set_texture_url', self.id, url)
  204. def set_coordinates(self, coordinates: List[List[Optional[List[float]]]]) -> None:
  205. """Change the texture coordinates."""
  206. self.args[1] = coordinates
  207. self.scene.run_method('set_texture_coordinates', self.id, coordinates)
  208. class SpotLight(Object3D):
  209. def __init__(self,
  210. color: str = '#ffffff',
  211. intensity: float = 1.0,
  212. distance: float = 0.0,
  213. angle: float = math.pi / 3,
  214. penumbra: float = 0.0,
  215. decay: float = 1.0,
  216. ) -> None:
  217. """Spot Light
  218. This element is based on Three.js' `SpotLight <https://threejs.org/docs/index.html#api/en/lights/SpotLight>`_ object.
  219. It is used to add a spot light to the scene.
  220. :param color: CSS color string (default: '#ffffff')
  221. :param intensity: light intensity (default: 1.0)
  222. :param distance: maximum distance of light (default: 0.0)
  223. :param angle: maximum angle of light (default: π/2)
  224. :param penumbra: penumbra (default: 0.0)
  225. :param decay: decay (default: 2.0)
  226. """
  227. super().__init__('spot_light', color, intensity, distance, angle, penumbra, decay)
  228. class PointCloud(Object3D):
  229. def __init__(self,
  230. points: List[List[float]],
  231. colors: List[List[float]],
  232. point_size: float = 1.0,
  233. ) -> None:
  234. """Point Cloud
  235. This element is based on Three.js' `Points <https://threejs.org/docs/index.html#api/en/objects/Points>`_ object.
  236. :param points: list of points
  237. :param colors: list of colors (one per point)
  238. :param point_size: size of the points (default: 1.0)
  239. """
  240. super().__init__('point_cloud', points, colors, point_size)