abstract-3d 3.1.2 → 4.0.0-beta.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (236) hide show
  1. package/README.md +53 -1
  2. package/lib/abstract-3d.d.ts +27 -1
  3. package/lib/abstract-3d.d.ts.map +1 -1
  4. package/lib/abstract-3d.js +26 -2
  5. package/lib/abstract-3d.js.map +1 -1
  6. package/lib/renderers/dxf/dxf-encoding/dxf-build.d.ts.map +1 -1
  7. package/lib/renderers/dxf/dxf-encoding/dxf-build.js +1 -2
  8. package/lib/renderers/dxf/dxf-encoding/dxf-build.js.map +1 -1
  9. package/lib/renderers/ifc/ifc.test.d.ts +2 -0
  10. package/lib/renderers/ifc/ifc.test.d.ts.map +1 -0
  11. package/lib/renderers/ifc/ifc.test.js +380 -0
  12. package/lib/renderers/ifc/ifc.test.js.map +1 -0
  13. package/lib/renderers/index.d.ts +1 -0
  14. package/lib/renderers/index.d.ts.map +1 -1
  15. package/lib/renderers/index.js +1 -0
  16. package/lib/renderers/index.js.map +1 -1
  17. package/lib/renderers/react/index.d.ts +2 -5
  18. package/lib/renderers/react/index.d.ts.map +1 -1
  19. package/lib/renderers/react/index.js +1 -2
  20. package/lib/renderers/react/index.js.map +1 -1
  21. package/lib/renderers/react/react.d.ts +16 -42
  22. package/lib/renderers/react/react.d.ts.map +1 -1
  23. package/lib/renderers/react/react.js +56 -32
  24. package/lib/renderers/react/react.js.map +1 -1
  25. package/lib/renderers/three/appearance/appearance.d.ts +46 -0
  26. package/lib/renderers/three/appearance/appearance.d.ts.map +1 -0
  27. package/lib/renderers/three/appearance/appearance.js +102 -0
  28. package/lib/renderers/three/appearance/appearance.js.map +1 -0
  29. package/lib/renderers/three/appearance/appearance.test.d.ts +2 -0
  30. package/lib/renderers/three/appearance/appearance.test.d.ts.map +1 -0
  31. package/lib/renderers/three/appearance/appearance.test.js +97 -0
  32. package/lib/renderers/three/appearance/appearance.test.js.map +1 -0
  33. package/lib/renderers/three/appearance.d.ts +41 -0
  34. package/lib/renderers/three/appearance.d.ts.map +1 -0
  35. package/lib/renderers/three/appearance.js +100 -0
  36. package/lib/renderers/three/appearance.js.map +1 -0
  37. package/lib/renderers/three/build/build.d.ts +53 -0
  38. package/lib/renderers/three/build/build.d.ts.map +1 -0
  39. package/lib/renderers/three/build/build.js +181 -0
  40. package/lib/renderers/three/build/build.js.map +1 -0
  41. package/lib/renderers/three/build/build.test.d.ts +2 -0
  42. package/lib/renderers/three/build/build.test.d.ts.map +1 -0
  43. package/lib/renderers/three/build/build.test.js +120 -0
  44. package/lib/renderers/three/build/build.test.js.map +1 -0
  45. package/lib/renderers/three/build/materials.d.ts +20 -0
  46. package/lib/renderers/three/build/materials.d.ts.map +1 -0
  47. package/lib/renderers/three/build/materials.js +168 -0
  48. package/lib/renderers/three/build/materials.js.map +1 -0
  49. package/lib/renderers/three/build/parts.d.ts +65 -0
  50. package/lib/renderers/three/build/parts.d.ts.map +1 -0
  51. package/lib/renderers/three/build/parts.js +203 -0
  52. package/lib/renderers/three/build/parts.js.map +1 -0
  53. package/lib/renderers/three/build.d.ts +50 -0
  54. package/lib/renderers/three/build.d.ts.map +1 -0
  55. package/lib/renderers/three/build.js +210 -0
  56. package/lib/renderers/three/build.js.map +1 -0
  57. package/lib/renderers/three/camera/camera.d.ts +40 -0
  58. package/lib/renderers/three/camera/camera.d.ts.map +1 -0
  59. package/lib/renderers/three/camera/camera.js +51 -0
  60. package/lib/renderers/three/camera/camera.js.map +1 -0
  61. package/lib/renderers/three/camera/camera.test.d.ts +2 -0
  62. package/lib/renderers/three/camera/camera.test.d.ts.map +1 -0
  63. package/lib/renderers/three/camera/camera.test.js +46 -0
  64. package/lib/renderers/three/camera/camera.test.js.map +1 -0
  65. package/lib/renderers/three/camera/controls.d.ts +24 -0
  66. package/lib/renderers/three/camera/controls.d.ts.map +1 -0
  67. package/lib/renderers/three/camera/controls.js +39 -0
  68. package/lib/renderers/three/camera/controls.js.map +1 -0
  69. package/lib/renderers/three/camera/gizmo.d.ts +44 -0
  70. package/lib/renderers/three/camera/gizmo.d.ts.map +1 -0
  71. package/lib/renderers/three/camera/gizmo.js +43 -0
  72. package/lib/renderers/three/camera/gizmo.js.map +1 -0
  73. package/lib/renderers/three/camera.d.ts +63 -0
  74. package/lib/renderers/three/camera.d.ts.map +1 -0
  75. package/lib/renderers/three/camera.js +85 -0
  76. package/lib/renderers/three/camera.js.map +1 -0
  77. package/lib/renderers/three/compile/compile.d.ts +59 -0
  78. package/lib/renderers/three/compile/compile.d.ts.map +1 -0
  79. package/lib/renderers/three/compile/compile.js +88 -0
  80. package/lib/renderers/three/compile/compile.js.map +1 -0
  81. package/lib/renderers/three/compile/compile.test.d.ts +2 -0
  82. package/lib/renderers/three/compile/compile.test.d.ts.map +1 -0
  83. package/lib/renderers/three/compile/compile.test.js +93 -0
  84. package/lib/renderers/three/compile/compile.test.js.map +1 -0
  85. package/lib/renderers/three/compile.d.ts +58 -0
  86. package/lib/renderers/three/compile.d.ts.map +1 -0
  87. package/lib/renderers/three/compile.js +89 -0
  88. package/lib/renderers/three/compile.js.map +1 -0
  89. package/lib/renderers/three/controls.d.ts +27 -0
  90. package/lib/renderers/three/controls.d.ts.map +1 -0
  91. package/lib/renderers/three/controls.js +115 -0
  92. package/lib/renderers/three/controls.js.map +1 -0
  93. package/lib/renderers/three/environment/studio.d.ts +9 -0
  94. package/lib/renderers/three/environment/studio.d.ts.map +1 -0
  95. package/lib/renderers/three/environment/studio.js +15 -0
  96. package/lib/renderers/three/environment/studio.js.map +1 -0
  97. package/lib/renderers/three/geometry/geometry.d.ts +21 -0
  98. package/lib/renderers/three/geometry/geometry.d.ts.map +1 -0
  99. package/lib/renderers/three/geometry/geometry.js +141 -0
  100. package/lib/renderers/three/geometry/geometry.js.map +1 -0
  101. package/lib/renderers/three/geometry/geometry.test.d.ts +2 -0
  102. package/lib/renderers/three/geometry/geometry.test.d.ts.map +1 -0
  103. package/lib/renderers/three/geometry/geometry.test.js +80 -0
  104. package/lib/renderers/three/geometry/geometry.test.js.map +1 -0
  105. package/lib/renderers/three/geometry.d.ts +20 -0
  106. package/lib/renderers/three/geometry.d.ts.map +1 -0
  107. package/lib/renderers/three/geometry.js +164 -0
  108. package/lib/renderers/three/geometry.js.map +1 -0
  109. package/lib/renderers/three/gizmo.d.ts +49 -0
  110. package/lib/renderers/three/gizmo.d.ts.map +1 -0
  111. package/lib/renderers/three/gizmo.js +172 -0
  112. package/lib/renderers/three/gizmo.js.map +1 -0
  113. package/lib/renderers/three/index.d.ts +16 -0
  114. package/lib/renderers/three/index.d.ts.map +1 -0
  115. package/lib/renderers/three/index.js +6 -0
  116. package/lib/renderers/three/index.js.map +1 -0
  117. package/lib/renderers/three/input.d.ts +25 -0
  118. package/lib/renderers/three/input.d.ts.map +1 -0
  119. package/lib/renderers/three/input.js +71 -0
  120. package/lib/renderers/three/input.js.map +1 -0
  121. package/lib/renderers/three/lines.d.ts +16 -0
  122. package/lib/renderers/three/lines.d.ts.map +1 -0
  123. package/lib/renderers/three/lines.js +63 -0
  124. package/lib/renderers/three/lines.js.map +1 -0
  125. package/lib/renderers/three/materials.d.ts +15 -0
  126. package/lib/renderers/three/materials.d.ts.map +1 -0
  127. package/lib/renderers/three/materials.js +70 -0
  128. package/lib/renderers/three/materials.js.map +1 -0
  129. package/lib/renderers/three/options.d.ts +68 -0
  130. package/lib/renderers/three/options.d.ts.map +1 -0
  131. package/lib/renderers/three/options.js +64 -0
  132. package/lib/renderers/three/options.js.map +1 -0
  133. package/lib/renderers/three/overlays.d.ts +25 -0
  134. package/lib/renderers/three/overlays.d.ts.map +1 -0
  135. package/lib/renderers/three/overlays.js +57 -0
  136. package/lib/renderers/three/overlays.js.map +1 -0
  137. package/lib/renderers/three/quality/quality.d.ts +18 -0
  138. package/lib/renderers/three/quality/quality.d.ts.map +1 -0
  139. package/lib/renderers/three/quality/quality.js +28 -0
  140. package/lib/renderers/three/quality/quality.js.map +1 -0
  141. package/lib/renderers/three/quality/quality.test.d.ts +2 -0
  142. package/lib/renderers/three/quality/quality.test.d.ts.map +1 -0
  143. package/lib/renderers/three/quality/quality.test.js +23 -0
  144. package/lib/renderers/three/quality/quality.test.js.map +1 -0
  145. package/lib/renderers/three/quality.d.ts +24 -0
  146. package/lib/renderers/three/quality.d.ts.map +1 -0
  147. package/lib/renderers/three/quality.js +67 -0
  148. package/lib/renderers/three/quality.js.map +1 -0
  149. package/lib/renderers/three/shadow/key-light.d.ts +6 -0
  150. package/lib/renderers/three/shadow/key-light.d.ts.map +1 -0
  151. package/lib/renderers/three/shadow/key-light.js +39 -0
  152. package/lib/renderers/three/shadow/key-light.js.map +1 -0
  153. package/lib/renderers/three/shadow/shadow.d.ts +21 -0
  154. package/lib/renderers/three/shadow/shadow.d.ts.map +1 -0
  155. package/lib/renderers/three/shadow/shadow.js +120 -0
  156. package/lib/renderers/three/shadow/shadow.js.map +1 -0
  157. package/lib/renderers/three/text/text.d.ts +55 -0
  158. package/lib/renderers/three/text/text.d.ts.map +1 -0
  159. package/lib/renderers/three/text/text.js +90 -0
  160. package/lib/renderers/three/text/text.js.map +1 -0
  161. package/lib/renderers/three/text/text.test.d.ts +2 -0
  162. package/lib/renderers/three/text/text.test.d.ts.map +1 -0
  163. package/lib/renderers/three/text/text.test.js +70 -0
  164. package/lib/renderers/three/text/text.test.js.map +1 -0
  165. package/lib/renderers/three/text.d.ts +53 -0
  166. package/lib/renderers/three/text.d.ts.map +1 -0
  167. package/lib/renderers/three/text.js +151 -0
  168. package/lib/renderers/three/text.js.map +1 -0
  169. package/lib/renderers/three/viewer/options.d.ts +82 -0
  170. package/lib/renderers/three/viewer/options.d.ts.map +1 -0
  171. package/lib/renderers/three/viewer/options.js +34 -0
  172. package/lib/renderers/three/viewer/options.js.map +1 -0
  173. package/lib/renderers/three/viewer/options.test.d.ts +2 -0
  174. package/lib/renderers/three/viewer/options.test.d.ts.map +1 -0
  175. package/lib/renderers/three/viewer/options.test.js +38 -0
  176. package/lib/renderers/three/viewer/options.test.js.map +1 -0
  177. package/lib/renderers/three/viewer/overlays.d.ts +31 -0
  178. package/lib/renderers/three/viewer/overlays.d.ts.map +1 -0
  179. package/lib/renderers/three/viewer/overlays.js +43 -0
  180. package/lib/renderers/three/viewer/overlays.js.map +1 -0
  181. package/lib/renderers/three/viewer/viewer.d.ts +102 -0
  182. package/lib/renderers/three/viewer/viewer.d.ts.map +1 -0
  183. package/lib/renderers/three/viewer/viewer.js +488 -0
  184. package/lib/renderers/three/viewer/viewer.js.map +1 -0
  185. package/lib/renderers/three/viewer.d.ts +38 -0
  186. package/lib/renderers/three/viewer.d.ts.map +1 -0
  187. package/lib/renderers/three/viewer.js +435 -0
  188. package/lib/renderers/three/viewer.js.map +1 -0
  189. package/package.json +34 -16
  190. package/src/abstract-3d.ts +60 -2
  191. package/src/renderers/dxf/dxf-encoding/dxf-build.ts +1 -2
  192. package/src/renderers/ifc/ifc.test.ts +7 -5
  193. package/src/renderers/index.ts +1 -0
  194. package/src/renderers/react/index.ts +2 -5
  195. package/src/renderers/react/react.tsx +107 -181
  196. package/src/renderers/three/appearance/appearance.test.ts +153 -0
  197. package/src/renderers/three/appearance/appearance.ts +150 -0
  198. package/src/renderers/three/build/build.test.ts +149 -0
  199. package/src/renderers/three/build/build.ts +278 -0
  200. package/src/renderers/three/build/materials.ts +222 -0
  201. package/src/renderers/three/build/parts.ts +277 -0
  202. package/src/renderers/three/camera/camera.test.ts +53 -0
  203. package/src/renderers/three/camera/camera.ts +82 -0
  204. package/src/renderers/three/camera/controls.ts +65 -0
  205. package/src/renderers/three/camera/gizmo.ts +94 -0
  206. package/src/renderers/three/compile/compile.test.ts +126 -0
  207. package/src/renderers/three/compile/compile.ts +151 -0
  208. package/src/renderers/three/environment/studio.ts +18 -0
  209. package/src/renderers/three/geometry/geometry.test.ts +121 -0
  210. package/src/renderers/three/geometry/geometry.ts +189 -0
  211. package/src/renderers/three/index.ts +15 -0
  212. package/src/renderers/three/quality/quality.test.ts +37 -0
  213. package/src/renderers/three/quality/quality.ts +36 -0
  214. package/src/renderers/three/shadow/key-light.ts +43 -0
  215. package/src/renderers/three/shadow/shadow.ts +170 -0
  216. package/src/renderers/three/text/text.test.ts +79 -0
  217. package/src/renderers/three/text/text.ts +128 -0
  218. package/src/renderers/three/viewer/options.ts +112 -0
  219. package/src/renderers/three/viewer/overlays.ts +71 -0
  220. package/src/renderers/three/viewer/viewer.ts +596 -0
  221. package/lib/renderers/react/react-hotspot.d.ts +0 -27
  222. package/lib/renderers/react/react-hotspot.d.ts.map +0 -1
  223. package/lib/renderers/react/react-hotspot.js +0 -37
  224. package/lib/renderers/react/react-hotspot.js.map +0 -1
  225. package/src/custom_typings/react-three-fiber.d.ts +0 -9
  226. package/src/custom_typings/react-three-postprocessing.d.ts +0 -1
  227. package/src/renderers/react/react-camera.tsx +0 -391
  228. package/src/renderers/react/react-dimension.tsx +0 -122
  229. package/src/renderers/react/react-group.test.ts +0 -56
  230. package/src/renderers/react/react-group.tsx +0 -202
  231. package/src/renderers/react/react-image-material.tsx +0 -139
  232. package/src/renderers/react/react-material.tsx +0 -91
  233. package/src/renderers/react/react-mesh.tsx +0 -512
  234. package/src/renderers/react/react-relation.tsx +0 -86
  235. package/src/renderers/react/react-scene.tsx +0 -111
  236. package/src/renderers/react/react-types.ts +0 -9
@@ -1,512 +0,0 @@
1
- import { Text, Line } from "@react-three/drei";
2
- import { extend, useThree } from "@react-three/fiber";
3
- import React, { useMemo } from "react";
4
- import {
5
- BoxGeometry,
6
- BufferAttribute,
7
- BufferGeometry,
8
- CatmullRomCurve3,
9
- Color,
10
- ConeGeometry,
11
- CylinderGeometry,
12
- Euler,
13
- ExtrudeGeometry,
14
- Float32BufferAttribute,
15
- FrontSide,
16
- Path,
17
- PlaneGeometry,
18
- Quaternion,
19
- Shape,
20
- SphereGeometry,
21
- TubeGeometry,
22
- Vector2,
23
- Vector3,
24
- } from "three";
25
- import type { Mesh, Box, Plane, Shape as Shape_1, Cylinder, Polygon as A3dPolygon, Tube as A3dTube } from "../../abstract-3d.js";
26
- import { vec2Scale, isZero } from "../../abstract-3d.js";
27
- import { addHoles, CircleCurve, CYLINDER_SEGMENTS, cylinderCutPositions, nonZeroHoles } from "../shared/three-geometry.js";
28
- import { planeGeometry } from "./react-image-material.js";
29
-
30
- extend({
31
- SphereGeometry,
32
- PlaneGeometry,
33
- ConeGeometry,
34
- Quaternion,
35
- Vector3,
36
- Euler,
37
- BoxGeometry,
38
- Path,
39
- Shape,
40
- TubeGeometry,
41
- CatmullRomCurve3,
42
- BufferAttribute,
43
- ExtrudeGeometry,
44
- CylinderGeometry,
45
- });
46
-
47
- const boxGeometry = new BoxGeometry();
48
- const cylinderGeometries = new Map<string, BufferGeometry>();
49
- const coneGeometry = new ConeGeometry(1, 1, 16, 1);
50
- const sphereGeometry = new SphereGeometry(1, 12, 12);
51
- export const euler = new Euler();
52
- export const vector3 = new Vector3();
53
- export const quaternion = new Quaternion();
54
-
55
- export function ReactMesh({ mesh, children }: { readonly mesh: Mesh; readonly children?: React.JSX.Element }): React.JSX.Element {
56
- const culledLineGeometry = useMemo(() => {
57
- const g = new BufferGeometry();
58
-
59
- g.setAttribute("position", new Float32BufferAttribute([0, -1, 0, 0, 1, 0, 1, -1, 0, 1, 1, 0], 3));
60
-
61
- g.setIndex([0, 2, 1, 2, 3, 1]);
62
-
63
- return g;
64
- }, []);
65
- const { camera, size } = useThree();
66
-
67
- switch (mesh.geometry.type) {
68
- case "Box": {
69
- const { pos, size, rot, holes } = mesh.geometry;
70
- return nonZeroHoles(holes).length === 0 ? (
71
- <mesh
72
- geometry={boxGeometry}
73
- scale={[size.x, size.y, size.z]}
74
- position={[pos.x, pos.y, pos.z]}
75
- rotation={[rot?.x ?? 0, rot?.y ?? 0, rot?.z ?? 0]}
76
- castShadow
77
- receiveShadow
78
- >
79
- {children}
80
- </mesh>
81
- ) : (
82
- <ExcrudeBoxPlane geo={mesh.geometry} sizeZ={size.z}>
83
- {children}
84
- </ExcrudeBoxPlane>
85
- );
86
- }
87
- case "Cone": {
88
- const { pos, radius, rot, length } = mesh.geometry;
89
- return (
90
- <mesh
91
- geometry={coneGeometry}
92
- scale={[radius, length, radius]}
93
- position={[pos.x, pos.y, pos.z]}
94
- rotation={[rot?.x ?? 0, rot?.y ?? 0, rot?.z ?? 0]}
95
- castShadow
96
- receiveShadow
97
- >
98
- {children}
99
- </mesh>
100
- );
101
- }
102
- case "Cylinder": {
103
- const { pos, radius, radiusEnd = radius, rot, length, holes, open, angleStart = 0, angleLength = Math.PI * 2 } = mesh.geometry;
104
- const isWhole = isZero(Math.PI * 2 - angleLength);
105
- // Holes are extruded along the length, which can't taper
106
- if (isWhole && radiusEnd === radius && nonZeroHoles(holes).length > 0) {
107
- return <ExcrudeCylinder cyl={mesh.geometry}>{children}</ExcrudeCylinder>;
108
- }
109
- // Unit geometry scaled by the largest radius, so only the radius ratio needs its own geometry
110
- const maxRadius = Math.max(radius, radiusEnd);
111
- const unitTop = radiusEnd / (maxRadius || 1);
112
- const unitBottom = radius / (maxRadius || 1);
113
- const transform = {
114
- scale: [maxRadius, length, maxRadius],
115
- position: [pos.x, pos.y, pos.z],
116
- rotation: [rot?.x ?? 0, rot?.y ?? 0, rot?.z ?? 0],
117
- } as const;
118
- return isWhole ? (
119
- <mesh geometry={getCylinderGeometry(unitTop, unitBottom, open ?? false, 0, Math.PI * 2)} {...transform} castShadow receiveShadow>
120
- {children}
121
- </mesh>
122
- ) : (
123
- <mesh {...transform}>
124
- <mesh geometry={getCylinderGeometry(unitTop, unitBottom, false, angleStart, angleLength)} castShadow receiveShadow>
125
- {children}
126
- </mesh>
127
- <mesh geometry={getCylinderCutGeometry(unitTop, unitBottom, angleStart, angleLength)} castShadow receiveShadow>
128
- {children}
129
- </mesh>
130
- </mesh>
131
- );
132
- }
133
- case "Image":
134
- return (
135
- <React.Suspense fallback={null}>
136
- <mesh
137
- geometry={planeGeometry}
138
- scale={[mesh.geometry.size.x, mesh.geometry.size.y, 1]}
139
- position={[mesh.geometry.pos.x, mesh.geometry.pos.y, mesh.geometry.pos.z]}
140
- rotation={[mesh.geometry.rot?.x ?? 0, mesh.geometry.rot?.y ?? 0, mesh.geometry.rot?.z ?? 0]}
141
- castShadow
142
- receiveShadow
143
- >
144
- {children}
145
- </mesh>
146
- </React.Suspense>
147
- );
148
- case "Plane": {
149
- const { pos, size, rot, holes } = mesh.geometry;
150
- return nonZeroHoles(holes).length === 0 ? (
151
- <mesh
152
- geometry={planeGeometry}
153
- scale={[size.x, size.y, 1]}
154
- position={[pos.x, pos.y, pos.z]}
155
- rotation={[rot?.x ?? 0, rot?.y ?? 0, rot?.z ?? 0]}
156
- castShadow
157
- receiveShadow
158
- >
159
- {children}
160
- </mesh>
161
- ) : (
162
- <ExcrudeBoxPlane geo={mesh.geometry} sizeZ={0}>
163
- {children}
164
- </ExcrudeBoxPlane>
165
- );
166
- }
167
- case "Sphere": {
168
- const { pos, radius } = mesh.geometry;
169
- return (
170
- <mesh geometry={sphereGeometry} scale={radius} position={[pos.x, pos.y, pos.z]} castShadow receiveShadow>
171
- {children}
172
- </mesh>
173
- );
174
- }
175
- case "Shape":
176
- return <ExcrudeShape s={mesh.geometry}>{children}</ExcrudeShape>;
177
- case "Text": {
178
- const { pos, rot, text, fontSize } = mesh.geometry;
179
- return (
180
- <React.Suspense fallback={null}>
181
- <Text
182
- position={[pos.x, pos.y, pos.z]}
183
- rotation={[rot?.x ?? 0, rot?.y ?? 0, rot?.z ?? 0]}
184
- fontSize={fontSize}
185
- textAlign="center"
186
- letterSpacing={0.001}
187
- lineHeight={1.5}
188
- // outlineColor="rgb(255,255,255)"
189
- // depthOffset={10}
190
- // outlineWidth={3}
191
- // outlineOpacity={1}
192
- >
193
- {children}
194
- {text}
195
- </Text>
196
- </React.Suspense>
197
- );
198
- }
199
- case "Line": {
200
- const { start, end, thickness } = mesh.geometry;
201
- return (
202
- <Line
203
- points={[
204
- [start.x, start.y, start.z],
205
- [end.x, end.y, end.z],
206
- ]}
207
- lineWidth={thickness}
208
- color={mesh.material.normal}
209
- >
210
- {children}
211
- </Line>
212
- );
213
- }
214
- case "CulledLine": {
215
- const { start, end, normal, thickness } = mesh.geometry;
216
- const color = mesh.material.normal;
217
-
218
- return (
219
- <mesh geometry={culledLineGeometry} frustumCulled={false}>
220
- <shaderMaterial
221
- side={FrontSide}
222
- uniforms={{
223
- lineStart: { value: new Vector3(start.x, start.y, start.z) },
224
- lineEnd: { value: new Vector3(end.x, end.y, end.z) },
225
- lineNormal: { value: new Vector3(normal.x, normal.y, normal.z) },
226
- thickness: { value: thickness },
227
- viewport: { value: new Vector2(size.width, size.height) },
228
- nearPlane: { value: camera.near },
229
- color: { value: new Color(color) },
230
- }}
231
- vertexShader={culledLineVertexShader}
232
- fragmentShader={culledLineFragmentShader}
233
- />
234
- </mesh>
235
- );
236
- }
237
- case "Polygon":
238
- return <Polygon polygon={mesh.geometry}>{children}</Polygon>;
239
- case "Tube":
240
- return <Tube tube={mesh.geometry}>{children}</Tube>;
241
- default:
242
- return <group />;
243
- }
244
- }
245
-
246
- function ExcrudeBoxPlane({
247
- geo,
248
- sizeZ,
249
- children,
250
- }: {
251
- readonly geo: Box | Plane;
252
- readonly sizeZ: number;
253
- readonly children?: React.JSX.Element;
254
- }): React.JSX.Element {
255
- const half = vec2Scale(geo.size, 0.5);
256
-
257
- const excrudeGeometry = React.useMemo(() => {
258
- const shape = new Shape();
259
- shape.moveTo(-half.x, -half.y).lineTo(-half.x, half.y).lineTo(half.x, half.y).lineTo(half.x, -half.y).closePath();
260
- addHoles(geo.holes, shape);
261
- return new ExtrudeGeometry(shape, { depth: sizeZ, bevelEnabled: false });
262
- }, [geo, half.x, half.y, sizeZ]);
263
-
264
- return (
265
- // Doesn't seem to adjust for excrude z size directly???
266
- <mesh rotation={[geo.rot?.x ?? 0, geo.rot?.y ?? 0, geo.rot?.z ?? 0]} position={[geo.pos.x, geo.pos.y, geo.pos.z]}>
267
- <mesh geometry={excrudeGeometry} position-z={-sizeZ / 2} castShadow receiveShadow>
268
- {children}
269
- </mesh>
270
- </mesh>
271
- );
272
- }
273
-
274
- function ExcrudeShape({ s, children }: { readonly s: Shape_1; readonly children?: React.JSX.Element }): React.JSX.Element {
275
- const excrudeGeometry = React.useMemo(() => {
276
- const shape = new Shape();
277
- if (s.points.length > 0) {
278
- const p = s.points[0]!;
279
- shape.moveTo(p.x, p.y);
280
- }
281
- for (let i = 1; i < s.points.length; i++) {
282
- const p = s.points[i]!;
283
- shape.lineTo(p.x, p.y);
284
- }
285
- shape.closePath();
286
- addHoles(s.holes, shape);
287
- return new ExtrudeGeometry(shape, { depth: s.thickness, bevelEnabled: false });
288
- }, [s]);
289
-
290
- // Doesn't seem to adjust for excrude z size directly???
291
- return (
292
- <mesh rotation={[s.rot?.x ?? 0, s.rot?.y ?? 0, s.rot?.z ?? 0]} position={[s.pos.x, s.pos.y, s.pos.z]}>
293
- <mesh geometry={excrudeGeometry} position-z={-s.thickness / 2} castShadow receiveShadow>
294
- {children}
295
- </mesh>
296
- </mesh>
297
- );
298
- }
299
-
300
- function cachedCylinderGeometry(key: string, create: () => BufferGeometry): BufferGeometry {
301
- const cached = cylinderGeometries.get(key);
302
- if (cached) {
303
- return cached;
304
- }
305
- const geometry = create();
306
- cylinderGeometries.set(key, geometry);
307
- return geometry;
308
- }
309
-
310
- function getCylinderGeometry(top: number, bottom: number, open: boolean, angleStart: number, angleLength: number): BufferGeometry {
311
- return cachedCylinderGeometry(
312
- `cyl_${top}_${bottom}_${open}_${angleStart}_${angleLength}`,
313
- () => new CylinderGeometry(top, bottom, 1, CYLINDER_SEGMENTS, 1, open, angleStart, angleLength)
314
- );
315
- }
316
-
317
- /** The two walls closing an angled cylinder, from the axis out to the rim at angleStart and angleEnd */
318
- function getCylinderCutGeometry(top: number, bottom: number, angleStart: number, angleLength: number): BufferGeometry {
319
- return cachedCylinderGeometry(`cut_${top}_${bottom}_${angleStart}_${angleLength}`, () => {
320
- const g = new BufferGeometry();
321
- g.setAttribute("position", new Float32BufferAttribute(cylinderCutPositions(top, bottom, 1, angleStart, angleLength), 3));
322
- g.computeVertexNormals();
323
- return g;
324
- });
325
- }
326
-
327
- function ExcrudeCylinder({ cyl, children }: { readonly cyl: Cylinder; readonly children?: React.JSX.Element }): React.JSX.Element {
328
- const excrudeGeometry = React.useMemo(() => {
329
- const shape = new Shape();
330
- shape.moveTo(0, cyl.radius).absellipse(0, 0, cyl.radius, cyl.radius, 0, Math.PI * 2, true);
331
- addHoles(cyl.holes, shape);
332
- return new ExtrudeGeometry(shape, { depth: cyl.length, bevelEnabled: false });
333
- }, [cyl]);
334
-
335
- return (
336
- // Doesn't seem to adjust for excrude z size directly???
337
- <mesh rotation={[cyl.rot?.x ?? 0, cyl.rot?.y ?? 0, cyl.rot?.z ?? 0]} position={[cyl.pos.x, cyl.pos.y, cyl.pos.z]}>
338
- <mesh geometry={excrudeGeometry} rotation-x={Math.PI / 2} position-y={cyl.length / 2} castShadow receiveShadow>
339
- {children}
340
- </mesh>
341
- </mesh>
342
- );
343
- }
344
-
345
- function Polygon({ polygon, children }: { readonly polygon: A3dPolygon; readonly children?: React.JSX.Element }): React.JSX.Element {
346
- const vertices = React.useMemo(() => {
347
- if (polygon.points.length === 4) {
348
- const [v0, v1, v2, v3] = polygon.points;
349
- return new Float32Array([
350
- v0!.x,
351
- v0!.y,
352
- v0!.z,
353
- v1!.x,
354
- v1!.y,
355
- v1!.z,
356
- v2!.x,
357
- v2!.y,
358
- v2!.z,
359
- v2!.x,
360
- v2!.y,
361
- v2!.z,
362
- v3!.x,
363
- v3!.y,
364
- v3!.z,
365
- v0!.x,
366
- v0!.y,
367
- v0!.z,
368
- ]);
369
- }
370
-
371
- const flattenedPoints: Array<number> = [];
372
- for (const point of polygon.points) {
373
- flattenedPoints.push(point.x, point.y, point.z);
374
- }
375
- const vertexCount = Math.floor(flattenedPoints.length / 3) * 3;
376
- const vertices = new Float32Array(vertexCount);
377
- for (let i = 0; i < vertexCount; i++) {
378
- vertices[i] = flattenedPoints[i] ?? 0.0;
379
- }
380
- return vertices;
381
- }, [polygon]);
382
-
383
- return (
384
- <mesh
385
- rotation={[polygon.rot?.x ?? 0, polygon.rot?.y ?? 0, polygon.rot?.z ?? 0]}
386
- position={[polygon.pos.x, polygon.pos.y, polygon.pos.z]}
387
- castShadow
388
- receiveShadow
389
- >
390
- <bufferGeometry key={vertices.join("")} attach="geometry" onUpdate={(self) => self.computeVertexNormals()}>
391
- <bufferAttribute attach="attributes-position" needsUpdate={true} args={fakeArgs} array={vertices} count={vertices.length / 3} itemSize={3} />
392
- </bufferGeometry>
393
- {children}
394
- </mesh>
395
- );
396
- }
397
-
398
- const fakeArgs = [] as unknown as ConstructorParameters<typeof BufferAttribute>;
399
-
400
- function Tube({ tube, children }: { readonly tube: A3dTube; readonly children?: React.JSX.Element }): React.JSX.Element {
401
- const tubeGeometry = React.useMemo(() => {
402
- return new TubeGeometry(
403
- tube.curve.type === "SplineCurve"
404
- ? new CatmullRomCurve3(tube.curve.points.map((p) => new Vector3(p.x, p.y, p.z)))
405
- : new CircleCurve(tube.curve),
406
- 9,
407
- tube.radius,
408
- 9,
409
- false
410
- );
411
- }, [tube]);
412
-
413
- return (
414
- <mesh
415
- rotation={[tube.rot?.x ?? 0, tube.rot?.y ?? 0, tube.rot?.z ?? 0]}
416
- position={[tube.pos.x, tube.pos.y, tube.pos.z]}
417
- geometry={tubeGeometry}
418
- castShadow
419
- receiveShadow
420
- >
421
- {children}
422
- </mesh>
423
- );
424
- }
425
-
426
- const culledLineVertexShader = `
427
- uniform vec3 lineStart;
428
- uniform vec3 lineEnd;
429
- uniform vec3 lineNormal;
430
-
431
- uniform float thickness;
432
- uniform float nearPlane;
433
- uniform vec2 viewport;
434
-
435
- void main() {
436
- vec3 a = (modelViewMatrix * vec4(lineStart, 1.0)).xyz;
437
- vec3 b = (modelViewMatrix * vec4(lineEnd, 1.0)).xyz;
438
-
439
- vec3 n = normalize(mat3(modelViewMatrix) * lineNormal);
440
-
441
- // camera is at (0,0,0) in view space.
442
- vec3 mid = (a + b) * 0.5;
443
- vec3 toCamera = normalize(-mid);
444
-
445
- bool frontFacing = dot(n, toCamera) > 0.0;
446
-
447
- if(!frontFacing) {
448
- // collapse all 4 vertices to one point.
449
- gl_Position = vec4(0.0);
450
- return;
451
- }
452
-
453
- // ---- near-plane clipping ----
454
-
455
- float nearZ = -nearPlane;
456
-
457
- bool aBehind = a.z > nearZ;
458
- bool bBehind = b.z > nearZ;
459
-
460
- if(aBehind && bBehind) {
461
- gl_Position = vec4(0.0);
462
- return;
463
- }
464
-
465
- if(aBehind) {
466
- float t = (nearZ - a.z) / (b.z - a.z);
467
- a = mix(a, b, t);
468
- }
469
-
470
- if(bBehind) {
471
- float t = (nearZ - b.z) / (a.z - b.z);
472
- b = mix(b, a, t);
473
- }
474
-
475
- vec4 ca = projectionMatrix * vec4(a, 1.0);
476
- vec4 cb = projectionMatrix * vec4(b, 1.0);
477
-
478
- vec2 aNdc = ca.xy / ca.w;
479
- vec2 bNdc = cb.xy / cb.w;
480
-
481
- vec2 aPx = aNdc * viewport * 0.5;
482
- vec2 bPx = bNdc * viewport * 0.5;
483
-
484
- vec2 delta = bPx - aPx;
485
- float len = length(delta);
486
-
487
- if(len < 0.0001) {
488
- gl_Position = vec4(0.0);
489
- return;
490
- }
491
-
492
- vec2 dir = delta / len;
493
- vec2 perp = vec2(-dir.y, dir.x);
494
-
495
- float endpoint = position.x;
496
- float side = position.y;
497
-
498
- vec4 clip = mix(ca, cb, endpoint);
499
-
500
- vec2 offsetNdc = perp * side * (thickness * 0.5) * (2.0 / viewport);
501
- clip.xy += offsetNdc * clip.w;
502
- gl_Position = clip;
503
- }
504
- `;
505
-
506
- const culledLineFragmentShader = `
507
- uniform vec3 color;
508
-
509
- void main() {
510
- gl_FragColor = vec4(color, 1.0);
511
- }
512
- `;
@@ -1,86 +0,0 @@
1
- import type { ThreeEvent } from "@react-three/fiber";
2
- import React from "react";
3
- import type { Group, Relation } from "../../abstract-3d.js";
4
- import { vec3Scale } from "../../abstract-3d.js";
5
- import { ReactMaterial } from "./react-material.js";
6
- import { ReactMesh } from "./react-mesh.js";
7
-
8
- const outlineMat = { normal: "rgb(0, 0, 0)", opacity: 1.0 };
9
-
10
- /** The shape of each active relation, e.g. where a component can be inserted on an air relation, clickable and darker when hovered */
11
- export const ReactRelations = React.memo(
12
- ({
13
- relations,
14
- activeRelations,
15
- onClickRelation,
16
- }: {
17
- readonly relations: ReadonlyArray<Relation> | undefined;
18
- readonly activeRelations: ReadonlyArray<string> | undefined;
19
- readonly onClickRelation?: (relation: Relation, e: ThreeEvent<MouseEvent>) => void;
20
- }): React.JSX.Element => (
21
- <>
22
- {relations
23
- ?.filter((r) => activeRelations?.includes(r.id))
24
- .map((r) => (
25
- <ReactRelation key={r.id} relation={r} onClickRelation={onClickRelation} />
26
- ))}
27
- </>
28
- )
29
- );
30
-
31
- function ReactRelation({
32
- relation,
33
- onClickRelation,
34
- }: {
35
- readonly relation: Relation;
36
- readonly onClickRelation?: (relation: Relation, e: ThreeEvent<MouseEvent>) => void;
37
- }): React.JSX.Element {
38
- const [hovered, setHovered] = React.useState<boolean>(false);
39
- return (
40
- <group
41
- onClick={(e) => {
42
- if (onClickRelation) {
43
- e.stopPropagation();
44
- onClickRelation(relation, e);
45
- }
46
- }}
47
- onPointerOver={(e) => {
48
- e.stopPropagation();
49
- document.body.style.cursor = "pointer";
50
- setHovered(true);
51
- }}
52
- onPointerOut={() => {
53
- document.body.style.cursor = "auto";
54
- setHovered(false);
55
- }}
56
- onContextMenu={(e) => e.stopPropagation()}
57
- >
58
- {relation.groups?.map((g, i) => (
59
- <ReactRelationGroup key={i} g={g} hovered={hovered} />
60
- ))}
61
- </group>
62
- );
63
- }
64
-
65
- /** A group of a relation's shape, unlit, with a black outline around its boxes */
66
- function ReactRelationGroup({ g, hovered }: { readonly g: Group; readonly hovered: boolean }): React.JSX.Element {
67
- return (
68
- <group position={[g.pos.x, g.pos.y, g.pos.z]} rotation={[g.rot?.x ?? 0, g.rot?.y ?? 0, g.rot?.z ?? 0]}>
69
- {g.meshes?.map((m, i) => (
70
- <React.Fragment key={i}>
71
- <ReactMesh mesh={m}>
72
- <ReactMaterial isText={false} isRelation={true} material={m.material} hovered={hovered} />
73
- </ReactMesh>
74
- {m.geometry.type === "Box" && (
75
- <ReactMesh mesh={{ ...m, geometry: { ...m.geometry, size: vec3Scale(m.geometry.size, 1.0125) } }}>
76
- <ReactMaterial isText={false} isRelation={true} drawBackOnly={true} material={outlineMat} hovered={hovered} />
77
- </ReactMesh>
78
- )}
79
- </React.Fragment>
80
- ))}
81
- {g.groups?.map((c, i) => (
82
- <ReactRelationGroup key={i} g={c} hovered={hovered} />
83
- ))}
84
- </group>
85
- );
86
- }
@@ -1,111 +0,0 @@
1
- import { Html } from "@react-three/drei";
2
- import type { ThreeEvent } from "@react-three/fiber";
3
- import React from "react";
4
- import type { Scene, Group, Relation } from "../../abstract-3d.js";
5
- import { ReactDimensions } from "./react-dimension.js";
6
- import { ReactGroup } from "./react-group.js";
7
- import type { MaterialState } from "./react-material.js";
8
- import { ReactRelations } from "./react-relation.js";
9
- import type { ReactPopover } from "./react-types.js";
10
-
11
- export type SceneMouseEvent = ThreeEvent<MouseEvent>;
12
-
13
- export function ReactScene({
14
- scene,
15
- selectedIds,
16
- hoveredIdsExternal,
17
- activeRelations,
18
- activeComponents,
19
- showDimensions,
20
- useAlphaTest,
21
- materialStateImages,
22
- reactPopovers,
23
- onClickGroup,
24
- onHoverGroup,
25
- onContextMenuGroup,
26
- getTooltips,
27
- onClickRelation,
28
- createGroupKey,
29
- createGroupId,
30
- }: {
31
- readonly scene: Scene;
32
- readonly selectedIds: Record<string, boolean> | undefined;
33
- readonly hoveredIdsExternal: ReadonlyArray<string> | undefined;
34
- readonly activeRelations: ReadonlyArray<string> | undefined;
35
- readonly activeComponents: Record<string, MaterialState> | undefined;
36
- readonly showDimensions: boolean;
37
- readonly useAlphaTest?: boolean;
38
- readonly materialStateImages?: Record<string, string>;
39
- readonly reactPopovers?: ReadonlyArray<ReactPopover>;
40
- readonly onClickGroup?: (
41
- id: string | undefined,
42
- rootData: Record<string, string> | undefined,
43
- data: Record<string, string> | undefined,
44
- e: SceneMouseEvent
45
- ) => void;
46
- readonly onHoverGroup?: (
47
- id: string | undefined,
48
- rootData: Record<string, string> | undefined,
49
- data: Record<string, string> | undefined,
50
- e: SceneMouseEvent
51
- ) => void;
52
- readonly onContextMenuGroup?: (
53
- id: string,
54
- rootData: Record<string, string> | undefined,
55
- data: Record<string, string> | undefined,
56
- left: number,
57
- top: number,
58
- e: SceneMouseEvent
59
- ) => void;
60
- readonly getTooltips?: (id: string) => ReadonlyArray<ReactPopover>;
61
- readonly onClickRelation?: (relation: Relation, e: SceneMouseEvent) => void;
62
- readonly createGroupKey?: (g: Group, idx: number, rootData: Record<string, string> | undefined, id: string) => string;
63
- readonly createGroupId?: (g: Group) => string;
64
- }): React.JSX.Element {
65
- return (
66
- <group
67
- rotation={[scene.rotation_deprecated?.x ?? 0, scene.rotation_deprecated?.y ?? 0, scene.rotation_deprecated?.z ?? 0]}
68
- position={[-(scene.center_deprecated?.x ?? 0), -(scene.center_deprecated?.y ?? 0), -(scene.center_deprecated?.z ?? 0)]}
69
- >
70
- {scene.groups.map((g, i) => {
71
- const id = createGroupId ? createGroupId(g) : "";
72
- return (
73
- <ReactGroup
74
- key={createGroupKey ? createGroupKey(g, 0, g.data, id) : i}
75
- g={g}
76
- selectedIds={selectedIds}
77
- relationsActive={activeRelations !== undefined}
78
- activeComponents={activeComponents}
79
- materialStateImages={materialStateImages}
80
- hoveredIdsExternal={hoveredIdsExternal}
81
- onClickGroup={onClickGroup}
82
- onHoverGroup={onHoverGroup}
83
- onContextMenuGroup={onContextMenuGroup}
84
- getTooltips={getTooltips}
85
- createGroupKey={createGroupKey}
86
- id={id}
87
- useAlphaTest={useAlphaTest}
88
- rootData={g.data}
89
- />
90
- );
91
- })}
92
- <ReactDimensions
93
- dimensions={scene.dimensions_deprecated}
94
- showDimensions={showDimensions}
95
- sceneRotation={scene.rotation_deprecated}
96
- sceneCenter={scene.center_deprecated}
97
- selectedIds={selectedIds}
98
- relationsActive={activeRelations !== undefined}
99
- onClickGroup={onClickGroup}
100
- onHoverGroup={onHoverGroup}
101
- onContextMenuGroup={onContextMenuGroup}
102
- />
103
- <ReactRelations relations={scene.relations} activeRelations={activeRelations} onClickRelation={onClickRelation} />
104
- {reactPopovers?.map((p) => (
105
- <Html key={p.id} position={[p.pos.x, p.pos.y, p.pos.z]} center pointerEvents="none" style={{ pointerEvents: "none" }}>
106
- {p.content}
107
- </Html>
108
- ))}
109
- </group>
110
- );
111
- }