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,202 +0,0 @@
1
- import { Html } from "@react-three/drei";
2
- import type { ThreeEvent } from "@react-three/fiber";
3
- import { useFrame } from "@react-three/fiber";
4
- import React from "react";
5
- import type { Group } from "three";
6
- import type { Group as Group_1 } from "../../abstract-3d.js";
7
- import { ImageMaterial } from "./react-image-material.js";
8
- import type { MaterialState } from "./react-material.js";
9
- import { ReactMaterial } from "./react-material.js";
10
- import { ReactMesh } from "./react-mesh.js";
11
- import type { ReactPopover } from "./react-types.js";
12
-
13
- export const ReactGroup = React.memo(ReactGroupBase, groupPropsEqual);
14
-
15
- function ReactGroupBase({
16
- g,
17
- materialStateImages,
18
- hoveredIdsExternal,
19
- selectedIds,
20
- relationsActive,
21
- activeComponents,
22
- useAlphaTest,
23
- id,
24
- rootData,
25
- hoveredParent,
26
- onClickGroup,
27
- onHoverGroup,
28
- onContextMenuGroup,
29
- createGroupKey,
30
- getTooltips,
31
- }: ReactGroupProps): React.JSX.Element {
32
- const ref = React.useRef<Group>(undefined!);
33
- useFrame(({ invalidate }, delta) => {
34
- if (g.animation) {
35
- invalidate();
36
- ref.current.rotation.x += (g.animation.transform.rot.x / g.animation.duration) * 1000 * delta;
37
- ref.current.rotation.y += (g.animation.transform.rot.y / g.animation.duration) * 1000 * delta;
38
- ref.current.rotation.z += (g.animation.transform.rot.z / g.animation.duration) * 1000 * delta;
39
- } else {
40
- ref.current.rotation.x = g.rot?.x ?? 0;
41
- ref.current.rotation.y = g.rot?.y ?? 0;
42
- ref.current.rotation.z = g.rot?.z ?? 0;
43
- ref.current.position.x = g.pos.x;
44
- ref.current.position.y = g.pos.y;
45
- ref.current.position.z = g.pos.z;
46
- }
47
- });
48
- const [hovered, setHovered] = React.useState<boolean>(false);
49
- // Stable so the memoized child groups below can skip rendering
50
- const onChildHoverGroup = React.useCallback<NonNullable<ReactGroupProps["onHoverGroup"]>>(
51
- (hId, rData, data, e) => {
52
- setHovered(hId !== undefined);
53
- onHoverGroup?.(hId, rData, data, e);
54
- },
55
- [onHoverGroup]
56
- );
57
- // oxlint-disable-next-line typescript/prefer-nullish-coalescing -- `id && ...includes(id)` can legitimately be `false`, which must fall through to hoveredParent
58
- const hoveredFinal = hovered || (id && hoveredIdsExternal?.includes(id)) || !!hoveredParent;
59
- const selected = selectedIds?.[id ?? ""];
60
-
61
- const materialState = activeComponents?.[id ?? ""];
62
- const disabled = relationsActive && materialState !== "Accept";
63
- return (
64
- <group
65
- rotation={[g.rot?.x ?? 0, g.rot?.y ?? 0, g.rot?.z ?? 0]}
66
- position={[g.pos.x, g.pos.y, g.pos.z]}
67
- ref={ref}
68
- {...(id &&
69
- !disabled && {
70
- onClick: (e) => {
71
- if (onClickGroup) {
72
- e.stopPropagation();
73
- onClickGroup(id, rootData, g.data, e);
74
- }
75
- },
76
- onPointerOver: (e) => {
77
- e.stopPropagation();
78
- document.body.style.cursor = "pointer";
79
- if (onHoverGroup) {
80
- onHoverGroup(id, rootData, g.data, e);
81
- }
82
- setHovered(true);
83
- },
84
- onPointerOut: (e) => {
85
- document.body.style.cursor = "auto";
86
- setHovered(false);
87
- if (onHoverGroup) {
88
- onHoverGroup(undefined, undefined, undefined, e);
89
- }
90
- },
91
- onContextMenu: (e) => {
92
- if (onContextMenuGroup) {
93
- e.stopPropagation();
94
- onContextMenuGroup(id, rootData, g.data, e.nativeEvent.x, e.nativeEvent.y, e);
95
- }
96
- },
97
- })}
98
- >
99
- {g.groups?.map((g, i) => (
100
- <ReactGroup
101
- key={createGroupKey ? createGroupKey(g, i, rootData, id ?? "") : i}
102
- g={g}
103
- selectedIds={selectedIds}
104
- relationsActive={relationsActive}
105
- activeComponents={activeComponents}
106
- materialStateImages={materialStateImages}
107
- hoveredIdsExternal={hoveredIdsExternal}
108
- hoveredParent={hoveredFinal}
109
- onClickGroup={onClickGroup}
110
- onHoverGroup={onChildHoverGroup}
111
- onContextMenuGroup={onContextMenuGroup}
112
- getTooltips={getTooltips}
113
- id={id}
114
- rootData={rootData}
115
- createGroupKey={createGroupKey}
116
- useAlphaTest={useAlphaTest}
117
- />
118
- ))}
119
- {g.meshes?.map((m, i) => (
120
- <ReactMesh key={i} mesh={m}>
121
- {m.geometry.type === "Image" ? (
122
- <ImageMaterial
123
- image={m.geometry.image}
124
- materialStateImages={materialStateImages}
125
- material={m.material}
126
- useAlphaTest={useAlphaTest}
127
- hovered={hoveredFinal}
128
- materialState={materialState}
129
- selected={selected}
130
- />
131
- ) : (
132
- <ReactMaterial
133
- material={m.material}
134
- selected={selected}
135
- isText={m.geometry.type === "Text"}
136
- hovered={hoveredFinal}
137
- disabled={disabled}
138
- materialState={materialState}
139
- />
140
- )}
141
- </ReactMesh>
142
- ))}
143
- {hovered &&
144
- id &&
145
- getTooltips &&
146
- getTooltips(id).map((p) => (
147
- <Html key={p.id} position={[p.pos.x, p.pos.y, p.pos.z]} center pointerEvents="none" style={{ pointerEvents: "none" }}>
148
- {p.content}
149
- </Html>
150
- ))}
151
- </group>
152
- );
153
- }
154
-
155
- export type ReactGroupProps = {
156
- readonly g: Group_1;
157
- readonly materialStateImages?: Record<string, string>;
158
- readonly hoveredIdsExternal: ReadonlyArray<string> | undefined;
159
- readonly hoveredParent?: boolean;
160
- readonly selectedIds: Record<string, boolean> | undefined;
161
- /** Relations are active, e.g. to pick one to insert a component on, so only the groups whose material state is Accept can be clicked */
162
- readonly relationsActive: boolean;
163
- readonly useAlphaTest?: boolean;
164
- readonly activeComponents: Record<string, MaterialState> | undefined;
165
- readonly id: string | undefined;
166
- readonly rootData: Record<string, string> | undefined;
167
- readonly onClickGroup?: (
168
- id: string | undefined,
169
- rootData: Record<string, string> | undefined,
170
- data: Record<string, string> | undefined,
171
- e: ThreeEvent<MouseEvent>
172
- ) => void;
173
- readonly onHoverGroup?: (
174
- id: string | undefined,
175
- rootData: Record<string, string> | undefined,
176
- data: Record<string, string> | undefined,
177
- e: ThreeEvent<MouseEvent>
178
- ) => void;
179
- readonly onContextMenuGroup?: (
180
- id: string,
181
- rootData: Record<string, string> | undefined,
182
- data: Record<string, string> | undefined,
183
- left: number,
184
- top: number,
185
- e: ThreeEvent<MouseEvent>
186
- ) => void;
187
- readonly getTooltips?: (id: string) => ReadonlyArray<ReactPopover>;
188
- readonly createGroupKey?: (g: Group_1, idx: number, rootData: Record<string, string> | undefined, id: string) => string;
189
- };
190
-
191
- /** Shallow compare, except that selectedIds and activeComponents are only read at the group's own id (nested groups share it). */
192
- export function groupPropsEqual(prev: ReactGroupProps, next: ReactGroupProps): boolean {
193
- const id = next.id ?? "";
194
- if (prev.selectedIds?.[id] !== next.selectedIds?.[id] || prev.activeComponents?.[id] !== next.activeComponents?.[id]) {
195
- return false;
196
- }
197
- const keys = Object.keys(next) as Array<keyof ReactGroupProps>;
198
- return (
199
- keys.length === Object.keys(prev).length &&
200
- keys.every((key) => key === "selectedIds" || key === "activeComponents" || Object.is(prev[key], next[key]))
201
- );
202
- }
@@ -1,139 +0,0 @@
1
- import { createSVG } from "abstract-image";
2
- import React from "react";
3
- import { suspend } from "suspend-react";
4
- import { CanvasTexture, DoubleSide, FrontSide, PlaneGeometry, SRGBColorSpace, type Texture, TextureLoader } from "three";
5
- import type { Material, Image as A3dImage } from "../../abstract-3d.js";
6
- import type { MaterialState } from "./react-material.js";
7
- import { ERROR_IMG_KEY, getColor, materialDefaults, selectMat } from "./react-material.js";
8
-
9
- export const planeGeometry = new PlaneGeometry();
10
-
11
- // oxlint-disable-next-line no-redeclare -- value + type share a name, the standard enum-replacement pattern (erasableSyntaxOnly forbids enum)
12
- export const MinificationFilter = {
13
- Nearest: 1003,
14
- Linear: 1006,
15
- LinearMipmap: 1008,
16
- } as const;
17
- export type MinificationFilter = (typeof MinificationFilter)[keyof typeof MinificationFilter];
18
-
19
- // oxlint-disable-next-line no-redeclare -- value + type share a name, the standard enum-replacement pattern (erasableSyntaxOnly forbids enum)
20
- export const MagnificationFilter = {
21
- Nearest: 1003,
22
- Linear: 1006,
23
- } as const;
24
- export type MagnificationFilter = (typeof MagnificationFilter)[keyof typeof MagnificationFilter];
25
-
26
- export type TextureFilter = {
27
- readonly min: MinificationFilter;
28
- readonly mag: MagnificationFilter;
29
- };
30
-
31
- const filter: TextureFilter = { min: MinificationFilter.LinearMipmap, mag: MagnificationFilter.Linear };
32
- const textureCache: Map<string, Texture | null> = new Map();
33
-
34
- export function ImageMaterial({
35
- image,
36
- materialStateImages,
37
- material,
38
- useAlphaTest,
39
- hovered,
40
- selected,
41
- materialState,
42
- }: {
43
- readonly image: A3dImage;
44
- readonly material: Material;
45
- readonly materialStateImages: Record<string, string> | undefined;
46
- readonly hovered: boolean;
47
- readonly selected: boolean | undefined;
48
- readonly useAlphaTest: boolean | undefined;
49
- readonly materialState: MaterialState | undefined;
50
- }): React.JSX.Element {
51
- const url =
52
- materialState === "Error" && materialStateImages?.[ERROR_IMG_KEY]
53
- ? materialStateImages[ERROR_IMG_KEY]
54
- : image.type === "AbstractImage"
55
- ? `data:image/svg+xml,${createSVG(image.image)}`
56
- : image.url;
57
- const texture = suspend(urlIsSvg(url) ? loadSvg(url, filter) : loadNormal(url, filter), [url]) as Texture | null;
58
-
59
- return (
60
- <meshBasicMaterial
61
- color={getColor(selected, hovered, material, selectMat)}
62
- side={material.backfaceCulling ? FrontSide : DoubleSide}
63
- alphaTest={(useAlphaTest ?? true) ? 0.8 : undefined}
64
- map={texture}
65
- {...(material.opacity !== undefined && material.opacity < 1 ? { opacity: material.opacity } : materialDefaults)}
66
- transparent
67
- />
68
- );
69
- }
70
-
71
- function urlIsSvg(url: string): boolean {
72
- return url.startsWith("data:image/svg+xml") || url.endsWith(".svg") || url.includes(".svg?");
73
- }
74
-
75
- function loadSvg(url: string, filter: TextureFilter): Promise<Texture | null> {
76
- if (textureCache.has(url)) {
77
- return Promise.resolve(textureCache.get(url) ?? null);
78
- }
79
-
80
- return new Promise((res) => {
81
- const maxSize = 512;
82
- const img = new Image();
83
-
84
- img.addEventListener("load", (): void => {
85
- const canvas = document.createElement("canvas");
86
- const imgW = img.naturalWidth;
87
- const imgH = img.naturalHeight;
88
- const width = imgW >= imgH ? maxSize : maxSize * (imgW / imgH);
89
- const height = imgH >= imgW ? maxSize : maxSize * (imgH / imgW);
90
-
91
- canvas.width = width;
92
- canvas.height = height;
93
-
94
- const ctx = canvas.getContext("2d");
95
- if (!ctx) {
96
- return res(null);
97
- }
98
-
99
- ctx.clearRect(0, 0, canvas.width, canvas.height);
100
- ctx.imageSmoothingEnabled = true;
101
- ctx.imageSmoothingQuality = "high";
102
- ctx.drawImage(img, 0, 0, width, height);
103
-
104
- const texture = new CanvasTexture(canvas);
105
- texture.colorSpace = SRGBColorSpace;
106
- texture.minFilter = filter.min;
107
- texture.magFilter = filter.mag;
108
- texture.generateMipmaps = filter.min === MinificationFilter.LinearMipmap;
109
- texture.anisotropy = 4;
110
- texture.needsUpdate = true;
111
-
112
- res(texture);
113
- textureCache.set(url, texture);
114
- });
115
-
116
- img.addEventListener("error", () => res(null));
117
- img.src = url;
118
- });
119
- }
120
-
121
- function loadNormal(url: string, filter: TextureFilter): Promise<Texture | null> {
122
- return new Promise((res) =>
123
- textureLoader.load(
124
- url,
125
- (data) => {
126
- data.colorSpace = SRGBColorSpace;
127
- data.minFilter = filter.min;
128
- data.magFilter = filter.mag;
129
- data.generateMipmaps = filter.min === MinificationFilter.LinearMipmap;
130
- data.anisotropy = 4;
131
- res(data);
132
- },
133
- undefined,
134
- () => res(null)
135
- )
136
- );
137
- }
138
-
139
- const textureLoader = new TextureLoader();
@@ -1,91 +0,0 @@
1
- import React from "react";
2
- import { BackSide, DoubleSide, FrontSide, type MaterialParameters } from "three";
3
- import type { Material } from "../../abstract-3d.js";
4
- import { shade } from "../../utils.js";
5
-
6
- const decreasedOpacity = 0.125;
7
-
8
- export type MaterialState = "Accept" | "Error" | "Warning";
9
- export const ERROR_IMG_KEY = "error";
10
-
11
- export function ReactMaterial({
12
- material,
13
- selected,
14
- hovered,
15
- disabled,
16
- materialState,
17
- isText,
18
- isRelation,
19
- drawBackOnly,
20
- }: {
21
- readonly material: Material;
22
- readonly hovered?: boolean | undefined;
23
- readonly selected?: boolean;
24
- readonly disabled?: boolean;
25
- readonly materialState?: MaterialState | undefined;
26
- readonly isText: boolean;
27
- readonly isRelation?: boolean;
28
- readonly drawBackOnly?: boolean;
29
- }): React.JSX.Element {
30
- const mat = !materialState ? material : materialState === "Accept" ? acceptMat : materialState === "Error" ? errorMar : warningMat;
31
-
32
- const opacity = material.opacity ?? materialDefaults.opacity!;
33
- if (isText) {
34
- return (
35
- <meshBasicMaterial
36
- key={`mesh_material_text`}
37
- color={getColor(selected, hovered, mat, textSelectMat)}
38
- side={FrontSide}
39
- transparent
40
- {...(opacity < 1 ? { opacity } : materialDefaults)}
41
- />
42
- );
43
- }
44
- if (isRelation) {
45
- return (
46
- <meshBasicMaterial
47
- key="mesh_material_relation"
48
- color={getColor(selected, hovered, mat, selectMat)}
49
- side={drawBackOnly === true ? BackSide : DoubleSide}
50
- depthTest={true}
51
- depthWrite={true}
52
- transparent={false}
53
- opacity={1.0}
54
- />
55
- );
56
- }
57
- return (
58
- <meshStandardMaterial
59
- key={`mesh_material_standard_${mat.normal}_${mat.metalness}_${mat.opacity}_${mat.roughness}_${material.backfaceCulling}`}
60
- color={getColor(selected, hovered, mat, selectMat)}
61
- roughness={mat.roughness}
62
- metalness={mat.metalness}
63
- side={material.backfaceCulling ? FrontSide : DoubleSide}
64
- {...(opacity < 1 || disabled
65
- ? {
66
- transparent: true,
67
- depthWrite: false,
68
- opacity: disabled ? opacity * decreasedOpacity : opacity,
69
- depthTest: true,
70
- }
71
- : materialDefaults)}
72
- />
73
- );
74
- }
75
-
76
- export const materialDefaults: MaterialParameters = {
77
- transparent: false,
78
- depthWrite: true,
79
- depthTest: true,
80
- opacity: 1.0,
81
- };
82
-
83
- const acceptMat: Material = { normal: "rgb(0,148,91)", opacity: 1.0, metalness: 0.5, roughness: 0.5 };
84
- export const selectMat: Material = { normal: "rgb(14,82,184)", opacity: 1.0, metalness: 0.5, roughness: 0.5 };
85
- const textSelectMat: Material = { normal: "rgb(0, 26, 65)", opacity: 1.0, metalness: 0.5, roughness: 0.5 };
86
- const errorMar: Material = { normal: "#b82f3a", opacity: 1.0, metalness: 0.5, roughness: 0.5 };
87
- const warningMat: Material = { normal: "rgb(240, 197, 48)", opacity: 1.0, metalness: 0.5, roughness: 0.5 };
88
-
89
- export function getColor(selected: boolean | undefined, hovered: boolean | undefined, mat: Material, selectedMat: Material): string | undefined {
90
- return selected ? (hovered ? shade(-0.4, selectedMat.normal) : selectedMat.normal) : hovered ? shade(-0.4, mat.normal) : mat.normal;
91
- }