sdl-mcp 0.12.2 → 0.12.3

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 (276) hide show
  1. package/README.md +10 -0
  2. package/config/sdlmcp.config.example.json +53 -8
  3. package/config/sdlmcp.config.schema.json +530 -106
  4. package/dist/.tsbuildinfo +1 -1
  5. package/dist/benchmark/external-manifest.d.ts +162 -0
  6. package/dist/benchmark/external-manifest.d.ts.map +1 -0
  7. package/dist/benchmark/external-manifest.js +336 -0
  8. package/dist/benchmark/external-manifest.js.map +1 -0
  9. package/dist/benchmark/external-runner.d.ts +100 -0
  10. package/dist/benchmark/external-runner.d.ts.map +1 -0
  11. package/dist/benchmark/external-runner.js +1171 -0
  12. package/dist/benchmark/external-runner.js.map +1 -0
  13. package/dist/benchmark/output-file.d.ts +3 -0
  14. package/dist/benchmark/output-file.d.ts.map +1 -0
  15. package/dist/benchmark/output-file.js +8 -0
  16. package/dist/benchmark/output-file.js.map +1 -0
  17. package/dist/cli/argParsing.d.ts.map +1 -1
  18. package/dist/cli/argParsing.js +6 -0
  19. package/dist/cli/argParsing.js.map +1 -1
  20. package/dist/cli/commands/benchmark.d.ts.map +1 -1
  21. package/dist/cli/commands/benchmark.js +3 -2
  22. package/dist/cli/commands/benchmark.js.map +1 -1
  23. package/dist/cli/commands/index.d.ts +1 -0
  24. package/dist/cli/commands/index.d.ts.map +1 -1
  25. package/dist/cli/commands/index.js +13 -7
  26. package/dist/cli/commands/index.js.map +1 -1
  27. package/dist/cli/commands/init.d.ts +5 -1
  28. package/dist/cli/commands/init.d.ts.map +1 -1
  29. package/dist/cli/commands/init.js +73 -3
  30. package/dist/cli/commands/init.js.map +1 -1
  31. package/dist/cli/commands/serve.d.ts.map +1 -1
  32. package/dist/cli/commands/serve.js +2 -0
  33. package/dist/cli/commands/serve.js.map +1 -1
  34. package/dist/cli/index.js +2 -0
  35. package/dist/cli/index.js.map +1 -1
  36. package/dist/cli/transport/http.d.ts +1 -35
  37. package/dist/cli/transport/http.d.ts.map +1 -1
  38. package/dist/cli/transport/http.js +151 -175
  39. package/dist/cli/transport/http.js.map +1 -1
  40. package/dist/cli/types.d.ts +1 -0
  41. package/dist/cli/types.d.ts.map +1 -1
  42. package/dist/config/constants.d.ts +30 -0
  43. package/dist/config/constants.d.ts.map +1 -1
  44. package/dist/config/constants.js +30 -0
  45. package/dist/config/constants.js.map +1 -1
  46. package/dist/config/types.d.ts +53 -1
  47. package/dist/config/types.d.ts.map +1 -1
  48. package/dist/config/types.js +62 -14
  49. package/dist/config/types.js.map +1 -1
  50. package/dist/db/ladybug-batching.d.ts +1 -0
  51. package/dist/db/ladybug-batching.d.ts.map +1 -1
  52. package/dist/db/ladybug-batching.js +1 -0
  53. package/dist/db/ladybug-batching.js.map +1 -1
  54. package/dist/db/ladybug-core.d.ts +3 -0
  55. package/dist/db/ladybug-core.d.ts.map +1 -1
  56. package/dist/db/ladybug-core.js +72 -2
  57. package/dist/db/ladybug-core.js.map +1 -1
  58. package/dist/db/ladybug-embeddings.d.ts +6 -1
  59. package/dist/db/ladybug-embeddings.d.ts.map +1 -1
  60. package/dist/db/ladybug-embeddings.js +6 -1
  61. package/dist/db/ladybug-embeddings.js.map +1 -1
  62. package/dist/db/ladybug-file-summaries.d.ts.map +1 -1
  63. package/dist/db/ladybug-file-summaries.js +23 -0
  64. package/dist/db/ladybug-file-summaries.js.map +1 -1
  65. package/dist/db/ladybug-queries.js +1 -1
  66. package/dist/db/ladybug-queries.js.map +1 -1
  67. package/dist/db/migrations/index.d.ts.map +1 -1
  68. package/dist/db/migrations/index.js +2 -0
  69. package/dist/db/migrations/index.js.map +1 -1
  70. package/dist/db/migrations/m007-copy-embeddings-to-symbol.d.ts +5 -9
  71. package/dist/db/migrations/m007-copy-embeddings-to-symbol.d.ts.map +1 -1
  72. package/dist/db/migrations/m007-copy-embeddings-to-symbol.js +24 -126
  73. package/dist/db/migrations/m007-copy-embeddings-to-symbol.js.map +1 -1
  74. package/dist/db/migrations/m021-remediate-symbol-embeddings.d.ts +5 -0
  75. package/dist/db/migrations/m021-remediate-symbol-embeddings.d.ts.map +1 -0
  76. package/dist/db/migrations/m021-remediate-symbol-embeddings.js +7 -0
  77. package/dist/db/migrations/m021-remediate-symbol-embeddings.js.map +1 -0
  78. package/dist/db/migrations/symbol-embedding-remediation.d.ts +57 -0
  79. package/dist/db/migrations/symbol-embedding-remediation.d.ts.map +1 -0
  80. package/dist/db/migrations/symbol-embedding-remediation.js +335 -0
  81. package/dist/db/migrations/symbol-embedding-remediation.js.map +1 -0
  82. package/dist/graph/layout/force-layout.d.ts +4 -0
  83. package/dist/graph/layout/force-layout.d.ts.map +1 -0
  84. package/dist/graph/layout/force-layout.js +127 -0
  85. package/dist/graph/layout/force-layout.js.map +1 -0
  86. package/dist/graph/layout/layout-service.d.ts +37 -0
  87. package/dist/graph/layout/layout-service.d.ts.map +1 -0
  88. package/dist/graph/layout/layout-service.js +172 -0
  89. package/dist/graph/layout/layout-service.js.map +1 -0
  90. package/dist/graph/layout/native-engine.d.ts +9 -0
  91. package/dist/graph/layout/native-engine.d.ts.map +1 -0
  92. package/dist/graph/layout/native-engine.js +59 -0
  93. package/dist/graph/layout/native-engine.js.map +1 -0
  94. package/dist/graph/layout/prng.d.ts +3 -0
  95. package/dist/graph/layout/prng.d.ts.map +1 -0
  96. package/dist/graph/layout/prng.js +19 -0
  97. package/dist/graph/layout/prng.js.map +1 -0
  98. package/dist/graph/layout/serializer.d.ts +3 -0
  99. package/dist/graph/layout/serializer.d.ts.map +1 -0
  100. package/dist/graph/layout/serializer.js +20 -0
  101. package/dist/graph/layout/serializer.js.map +1 -0
  102. package/dist/graph/layout/types.d.ts +30 -0
  103. package/dist/graph/layout/types.d.ts.map +1 -0
  104. package/dist/graph/layout/types.js +2 -0
  105. package/dist/graph/layout/types.js.map +1 -0
  106. package/dist/indexer/embeddings.d.ts +7 -0
  107. package/dist/indexer/embeddings.d.ts.map +1 -1
  108. package/dist/indexer/embeddings.js +44 -4
  109. package/dist/indexer/embeddings.js.map +1 -1
  110. package/dist/indexer/file-summary-embeddings.d.ts +12 -0
  111. package/dist/indexer/file-summary-embeddings.d.ts.map +1 -1
  112. package/dist/indexer/file-summary-embeddings.js +83 -21
  113. package/dist/indexer/file-summary-embeddings.js.map +1 -1
  114. package/dist/indexer/fileWalker.d.ts.map +1 -1
  115. package/dist/indexer/fileWalker.js +2 -1
  116. package/dist/indexer/fileWalker.js.map +1 -1
  117. package/dist/indexer/metrics-updater.d.ts.map +1 -1
  118. package/dist/indexer/metrics-updater.js +27 -4
  119. package/dist/indexer/metrics-updater.js.map +1 -1
  120. package/dist/indexer/watcher.d.ts.map +1 -1
  121. package/dist/indexer/watcher.js +2 -1
  122. package/dist/indexer/watcher.js.map +1 -1
  123. package/dist/mcp/context-response-projection.d.ts.map +1 -1
  124. package/dist/mcp/context-response-projection.js +49 -13
  125. package/dist/mcp/context-response-projection.js.map +1 -1
  126. package/dist/mcp/tools/search-edit/planner.d.ts.map +1 -1
  127. package/dist/mcp/tools/search-edit/planner.js +10 -3
  128. package/dist/mcp/tools/search-edit/planner.js.map +1 -1
  129. package/dist/observability/event-tap.d.ts +2 -1
  130. package/dist/observability/event-tap.d.ts.map +1 -1
  131. package/dist/observability/event-tap.js.map +1 -1
  132. package/dist/observability/service.d.ts +11 -4
  133. package/dist/observability/service.d.ts.map +1 -1
  134. package/dist/observability/service.js +83 -13
  135. package/dist/observability/service.js.map +1 -1
  136. package/dist/observability/types.d.ts +48 -2
  137. package/dist/observability/types.d.ts.map +1 -1
  138. package/dist/ui/.tsbuildinfo +1 -0
  139. package/dist/ui/vendor/fflate.js +2692 -0
  140. package/dist/ui/vendor/jsm/controls/ArcballControls.js +3543 -0
  141. package/dist/ui/vendor/jsm/controls/DragControls.js +452 -0
  142. package/dist/ui/vendor/jsm/controls/FirstPersonControls.js +488 -0
  143. package/dist/ui/vendor/jsm/controls/FlyControls.js +384 -0
  144. package/dist/ui/vendor/jsm/controls/MapControls.js +116 -0
  145. package/dist/ui/vendor/jsm/controls/OrbitControls.js +1963 -0
  146. package/dist/ui/vendor/jsm/controls/PointerLockControls.js +264 -0
  147. package/dist/ui/vendor/jsm/controls/TrackballControls.js +1001 -0
  148. package/dist/ui/vendor/jsm/controls/TransformControls.js +2003 -0
  149. package/dist/ui/vendor/jsm/loaders/3DMLoader.js +1836 -0
  150. package/dist/ui/vendor/jsm/loaders/3MFLoader.js +1621 -0
  151. package/dist/ui/vendor/jsm/loaders/AMFLoader.js +541 -0
  152. package/dist/ui/vendor/jsm/loaders/BVHLoader.js +484 -0
  153. package/dist/ui/vendor/jsm/loaders/ColladaLoader.js +153 -0
  154. package/dist/ui/vendor/jsm/loaders/DDSLoader.js +385 -0
  155. package/dist/ui/vendor/jsm/loaders/DRACOLoader.js +772 -0
  156. package/dist/ui/vendor/jsm/loaders/EXRLoader.js +3395 -0
  157. package/dist/ui/vendor/jsm/loaders/FBXLoader.js +4580 -0
  158. package/dist/ui/vendor/jsm/loaders/FontLoader.js +260 -0
  159. package/dist/ui/vendor/jsm/loaders/GCodeLoader.js +318 -0
  160. package/dist/ui/vendor/jsm/loaders/GLTFLoader.js +4860 -0
  161. package/dist/ui/vendor/jsm/loaders/HDRCubeTextureLoader.js +164 -0
  162. package/dist/ui/vendor/jsm/loaders/HDRLoader.js +463 -0
  163. package/dist/ui/vendor/jsm/loaders/IESLoader.js +379 -0
  164. package/dist/ui/vendor/jsm/loaders/KMZLoader.js +163 -0
  165. package/dist/ui/vendor/jsm/loaders/KTX2Loader.js +1276 -0
  166. package/dist/ui/vendor/jsm/loaders/KTXLoader.js +197 -0
  167. package/dist/ui/vendor/jsm/loaders/LDrawLoader.js +2510 -0
  168. package/dist/ui/vendor/jsm/loaders/LUT3dlLoader.js +205 -0
  169. package/dist/ui/vendor/jsm/loaders/LUTCubeLoader.js +190 -0
  170. package/dist/ui/vendor/jsm/loaders/LUTImageLoader.js +190 -0
  171. package/dist/ui/vendor/jsm/loaders/LWOLoader.js +1051 -0
  172. package/dist/ui/vendor/jsm/loaders/LottieLoader.js +130 -0
  173. package/dist/ui/vendor/jsm/loaders/MD2Loader.js +435 -0
  174. package/dist/ui/vendor/jsm/loaders/MDDLoader.js +147 -0
  175. package/dist/ui/vendor/jsm/loaders/MTLLoader.js +593 -0
  176. package/dist/ui/vendor/jsm/loaders/MaterialXLoader.js +1126 -0
  177. package/dist/ui/vendor/jsm/loaders/NRRDLoader.js +718 -0
  178. package/dist/ui/vendor/jsm/loaders/OBJLoader.js +955 -0
  179. package/dist/ui/vendor/jsm/loaders/PCDLoader.js +620 -0
  180. package/dist/ui/vendor/jsm/loaders/PDBLoader.js +272 -0
  181. package/dist/ui/vendor/jsm/loaders/PLYLoader.js +968 -0
  182. package/dist/ui/vendor/jsm/loaders/PVRLoader.js +270 -0
  183. package/dist/ui/vendor/jsm/loaders/RGBELoader.js +18 -0
  184. package/dist/ui/vendor/jsm/loaders/STLLoader.js +421 -0
  185. package/dist/ui/vendor/jsm/loaders/SVGLoader.js +3319 -0
  186. package/dist/ui/vendor/jsm/loaders/TDSLoader.js +1142 -0
  187. package/dist/ui/vendor/jsm/loaders/TGALoader.js +538 -0
  188. package/dist/ui/vendor/jsm/loaders/TIFFLoader.js +59 -0
  189. package/dist/ui/vendor/jsm/loaders/TTFLoader.js +261 -0
  190. package/dist/ui/vendor/jsm/loaders/USDLoader.js +303 -0
  191. package/dist/ui/vendor/jsm/loaders/USDZLoader.js +16 -0
  192. package/dist/ui/vendor/jsm/loaders/UltraHDRLoader.js +755 -0
  193. package/dist/ui/vendor/jsm/loaders/VOXLoader.js +919 -0
  194. package/dist/ui/vendor/jsm/loaders/VRMLLoader.js +3646 -0
  195. package/dist/ui/vendor/jsm/loaders/VTKLoader.js +1293 -0
  196. package/dist/ui/vendor/jsm/loaders/XYZLoader.js +143 -0
  197. package/dist/ui/vendor/jsm/loaders/collada/ColladaComposer.js +3044 -0
  198. package/dist/ui/vendor/jsm/loaders/collada/ColladaParser.js +1977 -0
  199. package/dist/ui/vendor/jsm/loaders/lwo/IFFParser.js +1217 -0
  200. package/dist/ui/vendor/jsm/loaders/lwo/LWO2Parser.js +414 -0
  201. package/dist/ui/vendor/jsm/loaders/lwo/LWO3Parser.js +373 -0
  202. package/dist/ui/vendor/jsm/loaders/usd/USDAParser.js +901 -0
  203. package/dist/ui/vendor/jsm/loaders/usd/USDCParser.js +1878 -0
  204. package/dist/ui/vendor/jsm/loaders/usd/USDComposer.js +4627 -0
  205. package/dist/ui/vendor/jsm/utils/BufferGeometryUtils.js +1501 -0
  206. package/dist/ui/vendor/jsm/utils/CameraUtils.js +82 -0
  207. package/dist/ui/vendor/jsm/utils/ColorUtils.js +76 -0
  208. package/dist/ui/vendor/jsm/utils/GeometryCompressionUtils.js +547 -0
  209. package/dist/ui/vendor/jsm/utils/GeometryUtils.js +226 -0
  210. package/dist/ui/vendor/jsm/utils/LDrawUtils.js +211 -0
  211. package/dist/ui/vendor/jsm/utils/SceneOptimizer.js +458 -0
  212. package/dist/ui/vendor/jsm/utils/SceneUtils.js +363 -0
  213. package/dist/ui/vendor/jsm/utils/ShadowMapViewer.js +244 -0
  214. package/dist/ui/vendor/jsm/utils/ShadowMapViewerGPU.js +233 -0
  215. package/dist/ui/vendor/jsm/utils/SkeletonUtils.js +496 -0
  216. package/dist/ui/vendor/jsm/utils/SortUtils.js +175 -0
  217. package/dist/ui/vendor/jsm/utils/UVsDebug.js +173 -0
  218. package/dist/ui/vendor/jsm/utils/WebGLTextureUtils.js +115 -0
  219. package/dist/ui/vendor/jsm/utils/WebGPUTextureUtils.js +81 -0
  220. package/dist/ui/vendor/jsm/utils/WorkerPool.js +167 -0
  221. package/dist/ui/vendor/three.core.min.js +6 -0
  222. package/dist/ui/vendor/three.module.min.js +6 -0
  223. package/dist/ui/viewer/ambient.js +39 -0
  224. package/dist/ui/viewer/api.js +93 -0
  225. package/dist/ui/viewer/chrome.js +36 -0
  226. package/dist/ui/viewer/edges.js +33 -0
  227. package/dist/ui/viewer/index.html +32 -0
  228. package/dist/ui/viewer/inspector.js +23 -0
  229. package/dist/ui/viewer/lenses/activity.js +24 -0
  230. package/dist/ui/viewer/lenses/community.js +5 -0
  231. package/dist/ui/viewer/lenses/edges.js +4 -0
  232. package/dist/ui/viewer/lenses/impact.js +6 -0
  233. package/dist/ui/viewer/lenses/search.js +69 -0
  234. package/dist/ui/viewer/lod.js +100 -0
  235. package/dist/ui/viewer/main.js +92 -0
  236. package/dist/ui/viewer/picking.js +45 -0
  237. package/dist/ui/viewer/scene.js +85 -0
  238. package/dist/ui/viewer/skins/default-skin.js +15 -0
  239. package/dist/ui/viewer/skins/loader.js +44 -0
  240. package/dist/ui/viewer/skins/manifest-schema.js +30 -0
  241. package/dist/ui/viewer/state.js +44 -0
  242. package/dist/ui/viewer/theme.js +23 -0
  243. package/dist/ui/viewer/universe.js +151 -0
  244. package/dist/ui/viewer/viewer.css +85 -0
  245. package/dist/util/safeRegex.d.ts.map +1 -1
  246. package/dist/util/safeRegex.js +221 -68
  247. package/dist/util/safeRegex.js.map +1 -1
  248. package/dist/viewer/legacy-graph.d.ts +40 -0
  249. package/dist/viewer/legacy-graph.d.ts.map +1 -0
  250. package/dist/viewer/legacy-graph.js +152 -0
  251. package/dist/viewer/legacy-graph.js.map +1 -0
  252. package/dist/viewer/routes.d.ts +10 -0
  253. package/dist/viewer/routes.d.ts.map +1 -0
  254. package/dist/viewer/routes.js +221 -0
  255. package/dist/viewer/routes.js.map +1 -0
  256. package/dist/viewer/service.d.ts +44 -0
  257. package/dist/viewer/service.d.ts.map +1 -0
  258. package/dist/viewer/service.js +160 -0
  259. package/dist/viewer/service.js.map +1 -0
  260. package/dist/viewer/types.d.ts +63 -0
  261. package/dist/viewer/types.d.ts.map +1 -0
  262. package/dist/viewer/types.js +2 -0
  263. package/dist/viewer/types.js.map +1 -0
  264. package/dist/viewer/viewer-config.d.ts +12 -0
  265. package/dist/viewer/viewer-config.d.ts.map +1 -0
  266. package/dist/viewer/viewer-config.js +36 -0
  267. package/dist/viewer/viewer-config.js.map +1 -0
  268. package/package.json +18 -9
  269. package/templates/SDL.md +19 -0
  270. package/templates/claude-code.json +8 -43
  271. package/dist/ui/graph.css +0 -108
  272. package/dist/ui/graph.d.ts +0 -2
  273. package/dist/ui/graph.d.ts.map +0 -1
  274. package/dist/ui/graph.html +0 -52
  275. package/dist/ui/graph.js +0 -259
  276. package/dist/ui/graph.js.map +0 -1
@@ -0,0 +1,1836 @@
1
+ import {
2
+ BufferGeometryLoader,
3
+ CanvasTexture,
4
+ ClampToEdgeWrapping,
5
+ Color,
6
+ DirectionalLight,
7
+ DoubleSide,
8
+ FileLoader,
9
+ LinearFilter,
10
+ Line,
11
+ LineBasicMaterial,
12
+ Loader,
13
+ Matrix4,
14
+ Mesh,
15
+ MeshPhysicalMaterial,
16
+ MeshStandardMaterial,
17
+ Object3D,
18
+ PointLight,
19
+ Points,
20
+ PointsMaterial,
21
+ RectAreaLight,
22
+ RepeatWrapping,
23
+ SpotLight,
24
+ Sprite,
25
+ SpriteMaterial,
26
+ TextureLoader,
27
+ EquirectangularReflectionMapping
28
+ } from 'three';
29
+
30
+ import { EXRLoader } from '../loaders/EXRLoader.js';
31
+
32
+ const _taskCache = new WeakMap();
33
+
34
+ /**
35
+ * A loader for Rhinoceros 3D files and objects.
36
+ *
37
+ * Rhinoceros is a 3D modeler used to create, edit, analyze, document, render,
38
+ * animate, and translate NURBS curves, surfaces, breps, extrusions, point clouds,
39
+ * as well as polygon meshes and SubD objects. `rhino3dm.js` is compiled to WebAssembly
40
+ * from the open source geometry library `openNURBS`. The loader currently uses
41
+ * `rhino3dm.js 8.4.0`.
42
+ *
43
+ * ```js
44
+ * const loader = new Rhino3dmLoader();
45
+ * loader.setLibraryPath( 'https://cdn.jsdelivr.net/npm/rhino3dm@8.17.0/' );
46
+ *
47
+ * const object = await loader.loadAsync( 'models/3dm/Rhino_Logo.3dm' );
48
+ * scene.add( object );
49
+ * ```
50
+ *
51
+ * @augments Loader
52
+ * @three_import import { Rhino3dmLoader } from 'three/addons/loaders/3DMLoader.js';
53
+ */
54
+ class Rhino3dmLoader extends Loader {
55
+
56
+ /**
57
+ * Constructs a new Rhino 3DM loader.
58
+ *
59
+ * @param {LoadingManager} [manager] - The loading manager.
60
+ */
61
+ constructor( manager ) {
62
+
63
+ super( manager );
64
+
65
+ // internals
66
+
67
+ this.libraryPath = '';
68
+ this.libraryPending = null;
69
+ this.libraryBinary = null;
70
+ this.libraryConfig = {};
71
+
72
+ this.url = '';
73
+
74
+ this.workerLimit = 4;
75
+ this.workerPool = [];
76
+ this.workerNextTaskID = 1;
77
+ this.workerSourceURL = '';
78
+ this.workerConfig = {};
79
+
80
+ this.materials = [];
81
+ this.warnings = [];
82
+
83
+ }
84
+
85
+ /**
86
+ * Path to a folder containing the JS and WASM libraries.
87
+ *
88
+ * @param {string} path - The library path to set.
89
+ * @return {Rhino3dmLoader} A reference to this loader.
90
+ */
91
+ setLibraryPath( path ) {
92
+
93
+ this.libraryPath = path;
94
+
95
+ return this;
96
+
97
+ }
98
+
99
+ /**
100
+ * Sets the maximum number of Web Workers to be used during decoding.
101
+ * A lower limit may be preferable if workers are also for other
102
+ * tasks in the application.
103
+ *
104
+ * @param {number} workerLimit - The worker limit.
105
+ * @return {Rhino3dmLoader} A reference to this loader.
106
+ */
107
+ setWorkerLimit( workerLimit ) {
108
+
109
+ this.workerLimit = workerLimit;
110
+
111
+ return this;
112
+
113
+ }
114
+
115
+ /**
116
+ * Starts loading from the given URL and passes the loaded 3DM asset
117
+ * to the `onLoad()` callback.
118
+ *
119
+ * @param {string} url - The path/URL of the file to be loaded. This can also be a data URI.
120
+ * @param {function(Object3D)} onLoad - Executed when the loading process has been finished.
121
+ * @param {onProgressCallback} onProgress - Executed while the loading is in progress.
122
+ * @param {onErrorCallback} onError - Executed when errors occur.
123
+ */
124
+ load( url, onLoad, onProgress, onError ) {
125
+
126
+ const loader = new FileLoader( this.manager );
127
+
128
+ loader.setPath( this.path );
129
+ loader.setResponseType( 'arraybuffer' );
130
+ loader.setRequestHeader( this.requestHeader );
131
+
132
+ this.url = url;
133
+
134
+ loader.load( url, ( buffer ) => {
135
+
136
+ // Check for an existing task using this buffer. A transferred buffer cannot be transferred
137
+ // again from this thread.
138
+ if ( _taskCache.has( buffer ) ) {
139
+
140
+ const cachedTask = _taskCache.get( buffer );
141
+
142
+ return cachedTask.promise.then( onLoad ).catch( onError );
143
+
144
+ }
145
+
146
+ this.decodeObjects( buffer, url )
147
+ .then( result => {
148
+
149
+ result.userData.warnings = this.warnings;
150
+ onLoad( result );
151
+
152
+ } )
153
+ .catch( e => onError( e ) );
154
+
155
+ }, onProgress, onError );
156
+
157
+ }
158
+
159
+ /**
160
+ * Prints debug messages to the browser console.
161
+ */
162
+ debug() {
163
+
164
+ console.log( 'Task load: ', this.workerPool.map( ( worker ) => worker._taskLoad ) );
165
+
166
+ }
167
+
168
+ /**
169
+ * Decodes the 3DM asset data with a Web Worker.
170
+ *
171
+ * @param {ArrayBuffer} buffer - The raw 3DM asset data as an array buffer.
172
+ * @param {string} url - The asset URL.
173
+ * @return {Promise<Object3D>} A Promise that resolved with the decoded 3D object.
174
+ */
175
+ decodeObjects( buffer, url ) {
176
+
177
+ let worker;
178
+ let taskID;
179
+
180
+ const taskCost = buffer.byteLength;
181
+
182
+ const objectPending = this._getWorker( taskCost )
183
+ .then( ( _worker ) => {
184
+
185
+ worker = _worker;
186
+ taskID = this.workerNextTaskID ++;
187
+
188
+ return new Promise( ( resolve, reject ) => {
189
+
190
+ worker._callbacks[ taskID ] = { resolve, reject };
191
+
192
+ worker.postMessage( { type: 'decode', id: taskID, buffer }, [ buffer ] );
193
+
194
+ // this.debug();
195
+
196
+ } );
197
+
198
+ } )
199
+ .then( ( message ) => this._createGeometry( message.data ) )
200
+ .catch( e => {
201
+
202
+ throw e;
203
+
204
+ } );
205
+
206
+ // Remove task from the task list.
207
+ // Note: replaced '.finally()' with '.catch().then()' block - iOS 11 support (#19416)
208
+ objectPending
209
+ .catch( () => true )
210
+ .then( () => {
211
+
212
+ if ( worker && taskID ) {
213
+
214
+ this._releaseTask( worker, taskID );
215
+
216
+ //this.debug();
217
+
218
+ }
219
+
220
+ } );
221
+
222
+ // Cache the task result.
223
+ _taskCache.set( buffer, {
224
+
225
+ url: url,
226
+ promise: objectPending
227
+
228
+ } );
229
+
230
+ return objectPending;
231
+
232
+ }
233
+
234
+ /**
235
+ * Parses the given 3DM data and passes the loaded 3DM asset
236
+ * to the `onLoad()` callback.
237
+ *
238
+ * @param {ArrayBuffer} data - The raw 3DM asset data as an array buffer.
239
+ * @param {function(Object3D)} onLoad - Executed when the loading process has been finished.
240
+ * @param {onErrorCallback} onError - Executed when errors occur.
241
+ */
242
+ parse( data, onLoad, onError ) {
243
+
244
+ this.decodeObjects( data, '' )
245
+ .then( result => {
246
+
247
+ result.userData.warnings = this.warnings;
248
+ onLoad( result );
249
+
250
+ } )
251
+ .catch( e => onError( e ) );
252
+
253
+ }
254
+
255
+ _compareMaterials( material ) {
256
+
257
+ const mat = {};
258
+ mat.name = material.name;
259
+ mat.color = {};
260
+ mat.color.r = material.color.r;
261
+ mat.color.g = material.color.g;
262
+ mat.color.b = material.color.b;
263
+ mat.type = material.type;
264
+ mat.vertexColors = material.vertexColors;
265
+
266
+ const json = JSON.stringify( mat );
267
+
268
+ for ( let i = 0; i < this.materials.length; i ++ ) {
269
+
270
+ const m = this.materials[ i ];
271
+ const _mat = {};
272
+ _mat.name = m.name;
273
+ _mat.color = {};
274
+ _mat.color.r = m.color.r;
275
+ _mat.color.g = m.color.g;
276
+ _mat.color.b = m.color.b;
277
+ _mat.type = m.type;
278
+ _mat.vertexColors = m.vertexColors;
279
+
280
+ if ( JSON.stringify( _mat ) === json ) {
281
+
282
+ return m;
283
+
284
+ }
285
+
286
+ }
287
+
288
+ this.materials.push( material );
289
+
290
+ return material;
291
+
292
+ }
293
+
294
+ _createMaterial( material, renderEnvironment ) {
295
+
296
+ if ( material === undefined ) {
297
+
298
+ return new MeshStandardMaterial( {
299
+ color: new Color( 1, 1, 1 ),
300
+ metalness: 0.8,
301
+ name: Loader.DEFAULT_MATERIAL_NAME,
302
+ side: DoubleSide
303
+ } );
304
+
305
+ }
306
+
307
+ //console.log(material)
308
+
309
+ const mat = new MeshPhysicalMaterial( {
310
+
311
+ color: new Color( material.diffuseColor.r / 255.0, material.diffuseColor.g / 255.0, material.diffuseColor.b / 255.0 ),
312
+ emissive: new Color( material.emissionColor.r, material.emissionColor.g, material.emissionColor.b ),
313
+ flatShading: material.disableLighting,
314
+ ior: material.indexOfRefraction,
315
+ name: material.name,
316
+ reflectivity: material.reflectivity,
317
+ opacity: 1.0 - material.transparency,
318
+ side: DoubleSide,
319
+ specularColor: material.specularColor,
320
+ transparent: material.transparency > 0 ? true : false
321
+
322
+ } );
323
+
324
+ mat.userData.id = material.id;
325
+
326
+ if ( material.pbrSupported ) {
327
+
328
+ const pbr = material.pbr;
329
+
330
+ mat.anisotropy = pbr.anisotropic;
331
+ mat.anisotropyRotation = pbr.anisotropicRotation;
332
+ mat.color = new Color( pbr.baseColor.r, pbr.baseColor.g, pbr.baseColor.b );
333
+ mat.clearcoat = pbr.clearcoat;
334
+ mat.clearcoatRoughness = pbr.clearcoatRoughness;
335
+ mat.metalness = pbr.metallic;
336
+ mat.transmission = 1 - pbr.opacity;
337
+ mat.roughness = pbr.roughness;
338
+ mat.sheen = pbr.sheen;
339
+ mat.specularIntensity = pbr.specular;
340
+ mat.thickness = pbr.subsurface;
341
+
342
+ }
343
+
344
+ if ( material.pbrSupported && material.pbr.opacity === 0 && material.transparency === 1 ) {
345
+
346
+ //some compromises
347
+
348
+ mat.opacity = 0.2;
349
+ mat.transmission = 1.00;
350
+
351
+ }
352
+
353
+ const textureLoader = new TextureLoader();
354
+
355
+ for ( let i = 0; i < material.textures.length; i ++ ) {
356
+
357
+ const texture = material.textures[ i ];
358
+
359
+ if ( texture.image !== null ) {
360
+
361
+ const map = textureLoader.load( texture.image );
362
+
363
+ //console.log(texture.type )
364
+
365
+ switch ( texture.type ) {
366
+
367
+ case 'Bump':
368
+
369
+ mat.bumpMap = map;
370
+
371
+ break;
372
+
373
+ case 'Diffuse':
374
+
375
+ mat.map = map;
376
+
377
+ break;
378
+
379
+ case 'Emap':
380
+
381
+ mat.envMap = map;
382
+
383
+ break;
384
+
385
+ case 'Opacity':
386
+
387
+ mat.transmissionMap = map;
388
+
389
+ break;
390
+
391
+ case 'Transparency':
392
+
393
+ mat.alphaMap = map;
394
+ mat.transparent = true;
395
+
396
+ break;
397
+
398
+ case 'PBR_Alpha':
399
+
400
+ mat.alphaMap = map;
401
+ mat.transparent = true;
402
+
403
+ break;
404
+
405
+ case 'PBR_AmbientOcclusion':
406
+
407
+ mat.aoMap = map;
408
+
409
+ break;
410
+
411
+ case 'PBR_Anisotropic':
412
+
413
+ mat.anisotropyMap = map;
414
+
415
+ break;
416
+
417
+ case 'PBR_BaseColor':
418
+
419
+ mat.map = map;
420
+
421
+ break;
422
+
423
+ case 'PBR_Clearcoat':
424
+
425
+ mat.clearcoatMap = map;
426
+
427
+ break;
428
+
429
+ case 'PBR_ClearcoatBump':
430
+
431
+ mat.clearcoatNormalMap = map;
432
+
433
+ break;
434
+
435
+ case 'PBR_ClearcoatRoughness':
436
+
437
+ mat.clearcoatRoughnessMap = map;
438
+
439
+ break;
440
+
441
+ case 'PBR_Displacement':
442
+
443
+ mat.displacementMap = map;
444
+
445
+ break;
446
+
447
+ case 'PBR_Emission':
448
+
449
+ mat.emissiveMap = map;
450
+
451
+ break;
452
+
453
+ case 'PBR_Metallic':
454
+
455
+ mat.metalnessMap = map;
456
+
457
+ break;
458
+
459
+ case 'PBR_Roughness':
460
+
461
+ mat.roughnessMap = map;
462
+
463
+ break;
464
+
465
+ case 'PBR_Sheen':
466
+
467
+ mat.sheenColorMap = map;
468
+
469
+ break;
470
+
471
+ case 'PBR_Specular':
472
+
473
+ mat.specularColorMap = map;
474
+
475
+ break;
476
+
477
+ case 'PBR_Subsurface':
478
+
479
+ mat.thicknessMap = map;
480
+
481
+ break;
482
+
483
+ default:
484
+
485
+ this.warnings.push( {
486
+ message: `THREE.3DMLoader: No conversion exists for 3dm ${texture.type}.`,
487
+ type: 'no conversion'
488
+ } );
489
+
490
+ break;
491
+
492
+ }
493
+
494
+ map.wrapS = texture.wrapU === 0 ? RepeatWrapping : ClampToEdgeWrapping;
495
+ map.wrapT = texture.wrapV === 0 ? RepeatWrapping : ClampToEdgeWrapping;
496
+
497
+ if ( texture.repeat ) {
498
+
499
+ map.repeat.set( texture.repeat[ 0 ], texture.repeat[ 1 ] );
500
+
501
+ }
502
+
503
+ }
504
+
505
+ }
506
+
507
+ if ( renderEnvironment ) {
508
+
509
+ new EXRLoader().load( renderEnvironment.image, function ( texture ) {
510
+
511
+ texture.mapping = EquirectangularReflectionMapping;
512
+ mat.envMap = texture;
513
+
514
+ } );
515
+
516
+ }
517
+
518
+ return mat;
519
+
520
+ }
521
+
522
+ _createGeometry( data ) {
523
+
524
+ const object = new Object3D();
525
+ const instanceDefinitionObjects = [];
526
+ const instanceDefinitions = [];
527
+ const instanceReferences = [];
528
+
529
+ object.userData[ 'layers' ] = data.layers;
530
+ object.userData[ 'groups' ] = data.groups;
531
+ object.userData[ 'settings' ] = data.settings;
532
+ object.userData.settings[ 'renderSettings' ] = data.renderSettings;
533
+ object.userData[ 'objectType' ] = 'File3dm';
534
+ object.userData[ 'materials' ] = null;
535
+
536
+ object.name = this.url;
537
+
538
+ let objects = data.objects;
539
+ const materials = data.materials;
540
+
541
+ for ( let i = 0; i < objects.length; i ++ ) {
542
+
543
+ const obj = objects[ i ];
544
+ const attributes = obj.attributes;
545
+
546
+ switch ( obj.objectType ) {
547
+
548
+ case 'InstanceDefinition':
549
+
550
+ instanceDefinitions.push( obj );
551
+
552
+ break;
553
+
554
+ case 'InstanceReference':
555
+
556
+ instanceReferences.push( obj );
557
+
558
+ break;
559
+
560
+ default:
561
+
562
+ let matId = null;
563
+
564
+ switch ( attributes.materialSource.name ) {
565
+
566
+ case 'ObjectMaterialSource_MaterialFromLayer':
567
+ //check layer index
568
+ if ( attributes.layerIndex >= 0 ) {
569
+
570
+ matId = data.layers[ attributes.layerIndex ].renderMaterialIndex;
571
+
572
+ }
573
+
574
+ break;
575
+
576
+ case 'ObjectMaterialSource_MaterialFromObject':
577
+
578
+ if ( attributes.materialIndex >= 0 ) {
579
+
580
+ matId = attributes.materialIndex;
581
+
582
+ }
583
+
584
+ break;
585
+
586
+ }
587
+
588
+ let material = null;
589
+
590
+ if ( matId >= 0 ) {
591
+
592
+ const rMaterial = materials[ matId ];
593
+ material = this._createMaterial( rMaterial, data.renderEnvironment );
594
+
595
+
596
+ }
597
+
598
+ const _object = this._createObject( obj, material );
599
+
600
+ if ( _object === undefined ) {
601
+
602
+ continue;
603
+
604
+ }
605
+
606
+ const layer = data.layers[ attributes.layerIndex ];
607
+
608
+ _object.visible = layer ? data.layers[ attributes.layerIndex ].visible : true;
609
+
610
+ if ( attributes.isInstanceDefinitionObject ) {
611
+
612
+ instanceDefinitionObjects.push( _object );
613
+
614
+ } else {
615
+
616
+ object.add( _object );
617
+
618
+ }
619
+
620
+ break;
621
+
622
+ }
623
+
624
+ }
625
+
626
+ for ( let i = 0; i < instanceDefinitions.length; i ++ ) {
627
+
628
+ const iDef = instanceDefinitions[ i ];
629
+
630
+ objects = [];
631
+
632
+ for ( let j = 0; j < iDef.attributes.objectIds.length; j ++ ) {
633
+
634
+ const objId = iDef.attributes.objectIds[ j ];
635
+
636
+ for ( let p = 0; p < instanceDefinitionObjects.length; p ++ ) {
637
+
638
+ const idoId = instanceDefinitionObjects[ p ].userData.attributes.id;
639
+
640
+ if ( objId === idoId ) {
641
+
642
+ objects.push( instanceDefinitionObjects[ p ] );
643
+
644
+ }
645
+
646
+ }
647
+
648
+ }
649
+
650
+ // Currently clones geometry and does not take advantage of instancing
651
+
652
+ for ( let j = 0; j < instanceReferences.length; j ++ ) {
653
+
654
+ const iRef = instanceReferences[ j ];
655
+
656
+ if ( iRef.geometry.parentIdefId === iDef.attributes.id ) {
657
+
658
+ const iRefObject = new Object3D();
659
+ const xf = iRef.geometry.xform.array;
660
+
661
+ const matrix = new Matrix4();
662
+ matrix.set( ...xf );
663
+
664
+ iRefObject.applyMatrix4( matrix );
665
+
666
+ for ( let p = 0; p < objects.length; p ++ ) {
667
+
668
+ iRefObject.add( objects[ p ].clone( true ) );
669
+
670
+ }
671
+
672
+ object.add( iRefObject );
673
+
674
+ }
675
+
676
+ }
677
+
678
+ }
679
+
680
+ object.userData[ 'materials' ] = this.materials;
681
+ object.name = '';
682
+ return object;
683
+
684
+ }
685
+
686
+ _createObject( obj, mat ) {
687
+
688
+ const loader = new BufferGeometryLoader();
689
+
690
+ const attributes = obj.attributes;
691
+
692
+ let geometry, material, _color, color;
693
+
694
+ switch ( obj.objectType ) {
695
+
696
+ case 'Point':
697
+ case 'PointSet':
698
+
699
+ geometry = loader.parse( obj.geometry );
700
+
701
+ if ( geometry.hasAttribute( 'color' ) ) {
702
+
703
+ material = new PointsMaterial( { vertexColors: true, sizeAttenuation: false, size: 2 } );
704
+
705
+ } else {
706
+
707
+ _color = attributes.drawColor;
708
+ color = new Color( _color.r / 255.0, _color.g / 255.0, _color.b / 255.0 );
709
+ material = new PointsMaterial( { color: color, sizeAttenuation: false, size: 2 } );
710
+
711
+ }
712
+
713
+ material = this._compareMaterials( material );
714
+
715
+ const points = new Points( geometry, material );
716
+ points.userData[ 'attributes' ] = attributes;
717
+ points.userData[ 'objectType' ] = obj.objectType;
718
+
719
+ if ( attributes.name ) {
720
+
721
+ points.name = attributes.name;
722
+
723
+ }
724
+
725
+ return points;
726
+
727
+ case 'Mesh':
728
+ case 'Extrusion':
729
+ case 'SubD':
730
+ case 'Brep':
731
+
732
+ if ( obj.geometry === null ) return;
733
+
734
+ geometry = loader.parse( obj.geometry );
735
+
736
+
737
+ if ( mat === null ) {
738
+
739
+ mat = this._createMaterial();
740
+
741
+ }
742
+
743
+
744
+ if ( geometry.hasAttribute( 'color' ) ) {
745
+
746
+ mat.vertexColors = true;
747
+
748
+ }
749
+
750
+ mat = this._compareMaterials( mat );
751
+
752
+ const mesh = new Mesh( geometry, mat );
753
+ mesh.castShadow = attributes.castsShadows;
754
+ mesh.receiveShadow = attributes.receivesShadows;
755
+ mesh.userData[ 'attributes' ] = attributes;
756
+ mesh.userData[ 'objectType' ] = obj.objectType;
757
+
758
+ if ( attributes.name ) {
759
+
760
+ mesh.name = attributes.name;
761
+
762
+ }
763
+
764
+ return mesh;
765
+
766
+ case 'Curve':
767
+
768
+ geometry = loader.parse( obj.geometry );
769
+
770
+ _color = attributes.drawColor;
771
+ color = new Color( _color.r / 255.0, _color.g / 255.0, _color.b / 255.0 );
772
+
773
+ material = new LineBasicMaterial( { color: color } );
774
+ material = this._compareMaterials( material );
775
+
776
+ const lines = new Line( geometry, material );
777
+ lines.userData[ 'attributes' ] = attributes;
778
+ lines.userData[ 'objectType' ] = obj.objectType;
779
+
780
+ if ( attributes.name ) {
781
+
782
+ lines.name = attributes.name;
783
+
784
+ }
785
+
786
+ return lines;
787
+
788
+ case 'TextDot':
789
+
790
+ geometry = obj.geometry;
791
+
792
+ const ctx = document.createElement( 'canvas' ).getContext( '2d' );
793
+ const font = `${geometry.fontHeight}px ${geometry.fontFace}`;
794
+ ctx.font = font;
795
+ const width = ctx.measureText( geometry.text ).width + 10;
796
+ const height = geometry.fontHeight + 10;
797
+
798
+ const r = window.devicePixelRatio;
799
+
800
+ ctx.canvas.width = width * r;
801
+ ctx.canvas.height = height * r;
802
+ ctx.canvas.style.width = width + 'px';
803
+ ctx.canvas.style.height = height + 'px';
804
+ ctx.setTransform( r, 0, 0, r, 0, 0 );
805
+
806
+ ctx.font = font;
807
+ ctx.textBaseline = 'middle';
808
+ ctx.textAlign = 'center';
809
+ color = attributes.drawColor;
810
+ ctx.fillStyle = `rgba(${color.r},${color.g},${color.b},${color.a})`;
811
+ ctx.fillRect( 0, 0, width, height );
812
+ ctx.fillStyle = 'white';
813
+ ctx.fillText( geometry.text, width / 2, height / 2 );
814
+
815
+ const texture = new CanvasTexture( ctx.canvas );
816
+ texture.minFilter = LinearFilter;
817
+ texture.generateMipmaps = false;
818
+ texture.wrapS = ClampToEdgeWrapping;
819
+ texture.wrapT = ClampToEdgeWrapping;
820
+
821
+ material = new SpriteMaterial( { map: texture, depthTest: false } );
822
+ const sprite = new Sprite( material );
823
+ sprite.position.set( geometry.point[ 0 ], geometry.point[ 1 ], geometry.point[ 2 ] );
824
+ sprite.scale.set( width / 10, height / 10, 1.0 );
825
+
826
+ sprite.userData[ 'attributes' ] = attributes;
827
+ sprite.userData[ 'objectType' ] = obj.objectType;
828
+
829
+ if ( attributes.name ) {
830
+
831
+ sprite.name = attributes.name;
832
+
833
+ }
834
+
835
+ return sprite;
836
+
837
+ case 'Light':
838
+
839
+ geometry = obj.geometry;
840
+
841
+ let light;
842
+
843
+ switch ( geometry.lightStyle.name ) {
844
+
845
+ case 'LightStyle_WorldPoint':
846
+
847
+ light = new PointLight();
848
+ light.castShadow = attributes.castsShadows;
849
+ light.position.set( geometry.location[ 0 ], geometry.location[ 1 ], geometry.location[ 2 ] );
850
+ light.shadow.normalBias = 0.1;
851
+
852
+ break;
853
+
854
+ case 'LightStyle_WorldSpot':
855
+
856
+ light = new SpotLight();
857
+ light.castShadow = attributes.castsShadows;
858
+ light.position.set( geometry.location[ 0 ], geometry.location[ 1 ], geometry.location[ 2 ] );
859
+ light.target.position.set( geometry.direction[ 0 ], geometry.direction[ 1 ], geometry.direction[ 2 ] );
860
+ light.angle = geometry.spotAngleRadians;
861
+ light.shadow.normalBias = 0.1;
862
+
863
+ break;
864
+
865
+ case 'LightStyle_WorldRectangular':
866
+
867
+ light = new RectAreaLight();
868
+ const width = Math.abs( geometry.width[ 2 ] );
869
+ const height = Math.abs( geometry.length[ 0 ] );
870
+ light.position.set( geometry.location[ 0 ] - ( height / 2 ), geometry.location[ 1 ], geometry.location[ 2 ] - ( width / 2 ) );
871
+ light.height = height;
872
+ light.width = width;
873
+ light.lookAt( geometry.direction[ 0 ], geometry.direction[ 1 ], geometry.direction[ 2 ] );
874
+
875
+ break;
876
+
877
+ case 'LightStyle_WorldDirectional':
878
+
879
+ light = new DirectionalLight();
880
+ light.castShadow = attributes.castsShadows;
881
+ light.position.set( geometry.location[ 0 ], geometry.location[ 1 ], geometry.location[ 2 ] );
882
+ light.target.position.set( geometry.direction[ 0 ], geometry.direction[ 1 ], geometry.direction[ 2 ] );
883
+ light.shadow.normalBias = 0.1;
884
+
885
+ break;
886
+
887
+ case 'LightStyle_WorldLinear':
888
+ // no conversion exists, warning has already been printed to the console
889
+ break;
890
+
891
+ default:
892
+ break;
893
+
894
+ }
895
+
896
+ if ( light ) {
897
+
898
+ light.intensity = geometry.intensity;
899
+ _color = geometry.diffuse;
900
+ color = new Color( _color.r / 255.0, _color.g / 255.0, _color.b / 255.0 );
901
+ light.color = color;
902
+ light.userData[ 'attributes' ] = attributes;
903
+ light.userData[ 'objectType' ] = obj.objectType;
904
+
905
+ }
906
+
907
+ return light;
908
+
909
+ }
910
+
911
+ }
912
+
913
+ _initLibrary() {
914
+
915
+ if ( ! this.libraryPending ) {
916
+
917
+ // Load rhino3dm wrapper.
918
+ const jsLoader = new FileLoader( this.manager );
919
+ jsLoader.setPath( this.libraryPath );
920
+ const jsContent = new Promise( ( resolve, reject ) => {
921
+
922
+ jsLoader.load( 'rhino3dm.js', resolve, undefined, reject );
923
+
924
+ } );
925
+
926
+ // Load rhino3dm WASM binary.
927
+ const binaryLoader = new FileLoader( this.manager );
928
+ binaryLoader.setPath( this.libraryPath );
929
+ binaryLoader.setResponseType( 'arraybuffer' );
930
+ const binaryContent = new Promise( ( resolve, reject ) => {
931
+
932
+ binaryLoader.load( 'rhino3dm.wasm', resolve, undefined, reject );
933
+
934
+ } );
935
+
936
+ this.libraryPending = Promise.all( [ jsContent, binaryContent ] )
937
+ .then( ( [ jsContent, binaryContent ] ) => {
938
+
939
+ //this.libraryBinary = binaryContent;
940
+ this.libraryConfig.wasmBinary = binaryContent;
941
+
942
+ const fn = Rhino3dmWorker.toString();
943
+
944
+ const body = [
945
+ '/* rhino3dm.js */',
946
+ jsContent,
947
+ '/* worker */',
948
+ fn.substring( fn.indexOf( '{' ) + 1, fn.lastIndexOf( '}' ) )
949
+ ].join( '\n' );
950
+
951
+ this.workerSourceURL = URL.createObjectURL( new Blob( [ body ] ) );
952
+
953
+ } );
954
+
955
+ }
956
+
957
+ return this.libraryPending;
958
+
959
+ }
960
+
961
+ _getWorker( taskCost ) {
962
+
963
+ return this._initLibrary().then( () => {
964
+
965
+ if ( this.workerPool.length < this.workerLimit ) {
966
+
967
+ const worker = new Worker( this.workerSourceURL );
968
+
969
+ worker._callbacks = {};
970
+ worker._taskCosts = {};
971
+ worker._taskLoad = 0;
972
+
973
+ worker.postMessage( {
974
+ type: 'init',
975
+ libraryConfig: this.libraryConfig
976
+ } );
977
+
978
+ worker.onmessage = e => {
979
+
980
+ const message = e.data;
981
+
982
+ switch ( message.type ) {
983
+
984
+ case 'warning':
985
+ this.warnings.push( message.data );
986
+ console.warn( message.data );
987
+ break;
988
+
989
+ case 'decode':
990
+ worker._callbacks[ message.id ].resolve( message );
991
+ break;
992
+
993
+ case 'error':
994
+ worker._callbacks[ message.id ].reject( message );
995
+ break;
996
+
997
+ default:
998
+ console.error( 'THREE.Rhino3dmLoader: Unexpected message, "' + message.type + '"' );
999
+
1000
+ }
1001
+
1002
+ };
1003
+
1004
+ this.workerPool.push( worker );
1005
+
1006
+ } else {
1007
+
1008
+ this.workerPool.sort( function ( a, b ) {
1009
+
1010
+ return a._taskLoad > b._taskLoad ? - 1 : 1;
1011
+
1012
+ } );
1013
+
1014
+ }
1015
+
1016
+ const worker = this.workerPool[ this.workerPool.length - 1 ];
1017
+
1018
+ worker._taskLoad += taskCost;
1019
+
1020
+ return worker;
1021
+
1022
+ } );
1023
+
1024
+ }
1025
+
1026
+ _releaseTask( worker, taskID ) {
1027
+
1028
+ worker._taskLoad -= worker._taskCosts[ taskID ];
1029
+ delete worker._callbacks[ taskID ];
1030
+ delete worker._taskCosts[ taskID ];
1031
+
1032
+ }
1033
+
1034
+ /**
1035
+ * Frees internal resources. This method should be called
1036
+ * when the loader is no longer required.
1037
+ */
1038
+ dispose() {
1039
+
1040
+ for ( let i = 0; i < this.workerPool.length; ++ i ) {
1041
+
1042
+ this.workerPool[ i ].terminate();
1043
+
1044
+ }
1045
+
1046
+ this.workerPool.length = 0;
1047
+
1048
+ }
1049
+
1050
+ }
1051
+
1052
+ /* WEB WORKER */
1053
+
1054
+ function Rhino3dmWorker() {
1055
+
1056
+ let libraryPending;
1057
+ let libraryConfig;
1058
+ let rhino;
1059
+ let taskID;
1060
+
1061
+ onmessage = function ( e ) {
1062
+
1063
+ const message = e.data;
1064
+
1065
+ switch ( message.type ) {
1066
+
1067
+ case 'init':
1068
+
1069
+ libraryConfig = message.libraryConfig;
1070
+ const wasmBinary = libraryConfig.wasmBinary;
1071
+ let RhinoModule;
1072
+ libraryPending = new Promise( function ( resolve ) {
1073
+
1074
+ /* Like Basis Loader */
1075
+ RhinoModule = { wasmBinary, onRuntimeInitialized: resolve };
1076
+
1077
+ rhino3dm( RhinoModule ); // eslint-disable-line no-undef
1078
+
1079
+ } ).then( () => {
1080
+
1081
+ rhino = RhinoModule;
1082
+
1083
+ } );
1084
+
1085
+ break;
1086
+
1087
+ case 'decode':
1088
+
1089
+ taskID = message.id;
1090
+ const buffer = message.buffer;
1091
+ libraryPending.then( () => {
1092
+
1093
+ try {
1094
+
1095
+ const data = decodeObjects( rhino, buffer );
1096
+ self.postMessage( { type: 'decode', id: message.id, data } );
1097
+
1098
+ } catch ( error ) {
1099
+
1100
+ self.postMessage( { type: 'error', id: message.id, error } );
1101
+
1102
+ }
1103
+
1104
+ } );
1105
+
1106
+ break;
1107
+
1108
+ }
1109
+
1110
+ };
1111
+
1112
+ function decodeObjects( rhino, buffer ) {
1113
+
1114
+ const arr = new Uint8Array( buffer );
1115
+ const doc = rhino.File3dm.fromByteArray( arr );
1116
+
1117
+ const objects = [];
1118
+ const materials = [];
1119
+ const layers = [];
1120
+ const views = [];
1121
+ const namedViews = [];
1122
+ const groups = [];
1123
+ const strings = [];
1124
+
1125
+ //Handle objects
1126
+
1127
+ const objs = doc.objects();
1128
+ const cnt = objs.count;
1129
+
1130
+ for ( let i = 0; i < cnt; i ++ ) {
1131
+
1132
+ const _object = objs.get( i );
1133
+
1134
+ const object = extractObjectData( _object, doc );
1135
+
1136
+ _object.delete();
1137
+
1138
+ if ( object ) {
1139
+
1140
+ objects.push( object );
1141
+
1142
+ }
1143
+
1144
+ }
1145
+
1146
+ // Handle instance definitions
1147
+ // console.log( `Instance Definitions Count: ${doc.instanceDefinitions().count()}` );
1148
+
1149
+ for ( let i = 0; i < doc.instanceDefinitions().count; i ++ ) {
1150
+
1151
+ const idef = doc.instanceDefinitions().get( i );
1152
+ const idefAttributes = extractProperties( idef );
1153
+ idefAttributes.objectIds = idef.getObjectIds();
1154
+
1155
+ objects.push( { geometry: null, attributes: idefAttributes, objectType: 'InstanceDefinition' } );
1156
+
1157
+ }
1158
+
1159
+ // Handle materials
1160
+
1161
+ const textureTypes = [
1162
+ // rhino.TextureType.Bitmap,
1163
+ rhino.TextureType.Diffuse,
1164
+ rhino.TextureType.Bump,
1165
+ rhino.TextureType.Transparency,
1166
+ rhino.TextureType.Opacity,
1167
+ rhino.TextureType.Emap
1168
+ ];
1169
+
1170
+ const pbrTextureTypes = [
1171
+ rhino.TextureType.PBR_BaseColor,
1172
+ rhino.TextureType.PBR_Subsurface,
1173
+ rhino.TextureType.PBR_SubsurfaceScattering,
1174
+ rhino.TextureType.PBR_SubsurfaceScatteringRadius,
1175
+ rhino.TextureType.PBR_Metallic,
1176
+ rhino.TextureType.PBR_Specular,
1177
+ rhino.TextureType.PBR_SpecularTint,
1178
+ rhino.TextureType.PBR_Roughness,
1179
+ rhino.TextureType.PBR_Anisotropic,
1180
+ rhino.TextureType.PBR_Anisotropic_Rotation,
1181
+ rhino.TextureType.PBR_Sheen,
1182
+ rhino.TextureType.PBR_SheenTint,
1183
+ rhino.TextureType.PBR_Clearcoat,
1184
+ rhino.TextureType.PBR_ClearcoatBump,
1185
+ rhino.TextureType.PBR_ClearcoatRoughness,
1186
+ rhino.TextureType.PBR_OpacityIor,
1187
+ rhino.TextureType.PBR_OpacityRoughness,
1188
+ rhino.TextureType.PBR_Emission,
1189
+ rhino.TextureType.PBR_AmbientOcclusion,
1190
+ rhino.TextureType.PBR_Displacement
1191
+ ];
1192
+
1193
+ for ( let i = 0; i < doc.materials().count; i ++ ) {
1194
+
1195
+ const _material = doc.materials().get( i );
1196
+
1197
+ const material = extractProperties( _material );
1198
+
1199
+ const textures = [];
1200
+
1201
+ textures.push( ...extractTextures( _material, textureTypes, doc ) );
1202
+
1203
+ material.pbrSupported = _material.physicallyBased().supported;
1204
+
1205
+ if ( material.pbrSupported ) {
1206
+
1207
+ textures.push( ...extractTextures( _material, pbrTextureTypes, doc ) );
1208
+ material.pbr = extractProperties( _material.physicallyBased() );
1209
+
1210
+ }
1211
+
1212
+ material.textures = textures;
1213
+
1214
+ materials.push( material );
1215
+
1216
+ _material.delete();
1217
+
1218
+ }
1219
+
1220
+ // Handle layers
1221
+
1222
+ for ( let i = 0; i < doc.layers().count; i ++ ) {
1223
+
1224
+ const _layer = doc.layers().get( i );
1225
+ const layer = extractProperties( _layer );
1226
+
1227
+ layers.push( layer );
1228
+
1229
+ _layer.delete();
1230
+
1231
+ }
1232
+
1233
+ // Handle views
1234
+
1235
+ for ( let i = 0; i < doc.views().count; i ++ ) {
1236
+
1237
+ const _view = doc.views().get( i );
1238
+ const view = extractProperties( _view );
1239
+
1240
+ views.push( view );
1241
+
1242
+ _view.delete();
1243
+
1244
+ }
1245
+
1246
+ // Handle named views
1247
+
1248
+ for ( let i = 0; i < doc.namedViews().count; i ++ ) {
1249
+
1250
+ const _namedView = doc.namedViews().get( i );
1251
+ const namedView = extractProperties( _namedView );
1252
+
1253
+ namedViews.push( namedView );
1254
+
1255
+ _namedView.delete();
1256
+
1257
+ }
1258
+
1259
+ // Handle groups
1260
+
1261
+ for ( let i = 0; i < doc.groups().count; i ++ ) {
1262
+
1263
+ const _group = doc.groups().get( i );
1264
+ const group = extractProperties( _group );
1265
+
1266
+ groups.push( group );
1267
+
1268
+ _group.delete();
1269
+
1270
+ }
1271
+
1272
+ // Handle settings
1273
+
1274
+ const settings = extractProperties( doc.settings() );
1275
+
1276
+ //TODO: Handle other document stuff like dimstyles, instance definitions, bitmaps etc.
1277
+
1278
+ // Handle dimstyles
1279
+ // console.log( `Dimstyle Count: ${doc.dimstyles().count()}` );
1280
+
1281
+ // Handle bitmaps
1282
+ // console.log( `Bitmap Count: ${doc.bitmaps().count()}` );
1283
+
1284
+ // Handle strings
1285
+ // console.log( `Document Strings Count: ${doc.strings().count()}` );
1286
+ // Note: doc.strings().documentUserTextCount() counts any doc.strings defined in a section
1287
+ // console.log( `Document User Text Count: ${doc.strings().documentUserTextCount()}` );
1288
+
1289
+ const strings_count = doc.strings().count;
1290
+
1291
+ for ( let i = 0; i < strings_count; i ++ ) {
1292
+
1293
+ strings.push( doc.strings().get( i ) );
1294
+
1295
+ }
1296
+
1297
+ // Handle Render Environments for Material Environment
1298
+
1299
+ // get the id of the active render environment skylight, which we'll use for environment texture
1300
+ const reflectionId = doc.settings().renderSettings().renderEnvironments.reflectionId;
1301
+
1302
+ const rc = doc.renderContent();
1303
+
1304
+ let renderEnvironment = null;
1305
+
1306
+ for ( let i = 0; i < rc.count; i ++ ) {
1307
+
1308
+ const content = rc.get( i );
1309
+
1310
+ switch ( content.kind ) {
1311
+
1312
+ case 'environment':
1313
+
1314
+ const id = content.id;
1315
+
1316
+ // there could be multiple render environments in a 3dm file
1317
+ if ( id !== reflectionId ) break;
1318
+
1319
+ const renderTexture = content.findChild( 'texture' );
1320
+ const fileName = renderTexture.fileName;
1321
+
1322
+ for ( let j = 0; j < doc.embeddedFiles().count; j ++ ) {
1323
+
1324
+ const _fileName = doc.embeddedFiles().get( j ).fileName;
1325
+
1326
+ if ( fileName === _fileName ) {
1327
+
1328
+ const background = doc.getEmbeddedFileAsBase64( fileName );
1329
+ const backgroundImage = 'data:image/png;base64,' + background;
1330
+ renderEnvironment = { type: 'renderEnvironment', image: backgroundImage, name: fileName };
1331
+
1332
+ }
1333
+
1334
+ }
1335
+
1336
+ break;
1337
+
1338
+ }
1339
+
1340
+ }
1341
+
1342
+ // Handle Render Settings
1343
+
1344
+ const renderSettings = {
1345
+ ambientLight: doc.settings().renderSettings().ambientLight,
1346
+ backgroundColorTop: doc.settings().renderSettings().backgroundColorTop,
1347
+ backgroundColorBottom: doc.settings().renderSettings().backgroundColorBottom,
1348
+ useHiddenLights: doc.settings().renderSettings().useHiddenLights,
1349
+ depthCue: doc.settings().renderSettings().depthCue,
1350
+ flatShade: doc.settings().renderSettings().flatShade,
1351
+ renderBackFaces: doc.settings().renderSettings().renderBackFaces,
1352
+ renderPoints: doc.settings().renderSettings().renderPoints,
1353
+ renderCurves: doc.settings().renderSettings().renderCurves,
1354
+ renderIsoParams: doc.settings().renderSettings().renderIsoParams,
1355
+ renderMeshEdges: doc.settings().renderSettings().renderMeshEdges,
1356
+ renderAnnotations: doc.settings().renderSettings().renderAnnotations,
1357
+ useViewportSize: doc.settings().renderSettings().useViewportSize,
1358
+ scaleBackgroundToFit: doc.settings().renderSettings().scaleBackgroundToFit,
1359
+ transparentBackground: doc.settings().renderSettings().transparentBackground,
1360
+ imageDpi: doc.settings().renderSettings().imageDpi,
1361
+ shadowMapLevel: doc.settings().renderSettings().shadowMapLevel,
1362
+ namedView: doc.settings().renderSettings().namedView,
1363
+ snapShot: doc.settings().renderSettings().snapShot,
1364
+ specificViewport: doc.settings().renderSettings().specificViewport,
1365
+ groundPlane: extractProperties( doc.settings().renderSettings().groundPlane ),
1366
+ safeFrame: extractProperties( doc.settings().renderSettings().safeFrame ),
1367
+ dithering: extractProperties( doc.settings().renderSettings().dithering ),
1368
+ skylight: extractProperties( doc.settings().renderSettings().skylight ),
1369
+ linearWorkflow: extractProperties( doc.settings().renderSettings().linearWorkflow ),
1370
+ renderChannels: extractProperties( doc.settings().renderSettings().renderChannels ),
1371
+ sun: extractProperties( doc.settings().renderSettings().sun ),
1372
+ renderEnvironments: extractProperties( doc.settings().renderSettings().renderEnvironments ),
1373
+ postEffects: extractProperties( doc.settings().renderSettings().postEffects ),
1374
+
1375
+ };
1376
+
1377
+ doc.delete();
1378
+
1379
+ return { objects, materials, layers, views, namedViews, groups, strings, settings, renderSettings, renderEnvironment };
1380
+
1381
+ }
1382
+
1383
+ function extractTextures( m, tTypes, d ) {
1384
+
1385
+ const textures = [];
1386
+
1387
+ for ( let i = 0; i < tTypes.length; i ++ ) {
1388
+
1389
+ const _texture = m.getTexture( tTypes[ i ] );
1390
+ if ( _texture ) {
1391
+
1392
+ let textureType = tTypes[ i ].constructor.name;
1393
+ textureType = textureType.substring( 12, textureType.length );
1394
+ const texture = extractTextureData( _texture, textureType, d );
1395
+ textures.push( texture );
1396
+ _texture.delete();
1397
+
1398
+ }
1399
+
1400
+ }
1401
+
1402
+ return textures;
1403
+
1404
+ }
1405
+
1406
+ function extractTextureData( t, tType, d ) {
1407
+
1408
+ const texture = { type: tType };
1409
+
1410
+ const image = d.getEmbeddedFileAsBase64( t.fileName );
1411
+
1412
+ texture.wrapU = t.wrapU;
1413
+ texture.wrapV = t.wrapV;
1414
+ texture.wrapW = t.wrapW;
1415
+ const uvw = t.uvwTransform.toFloatArray( true );
1416
+
1417
+ texture.repeat = [ uvw[ 0 ], uvw[ 5 ] ];
1418
+
1419
+ if ( image ) {
1420
+
1421
+ texture.image = 'data:image/png;base64,' + image;
1422
+
1423
+ } else {
1424
+
1425
+ self.postMessage( { type: 'warning', id: taskID, data: {
1426
+ message: `THREE.3DMLoader: Image for ${tType} texture not embedded in file.`,
1427
+ type: 'missing resource'
1428
+ }
1429
+
1430
+ } );
1431
+
1432
+ texture.image = null;
1433
+
1434
+ }
1435
+
1436
+ return texture;
1437
+
1438
+ }
1439
+
1440
+ function extractObjectData( object, doc ) {
1441
+
1442
+ const _geometry = object.geometry();
1443
+ const _attributes = object.attributes();
1444
+ let objectType = _geometry.objectType;
1445
+ let geometry, attributes, position, data, mesh;
1446
+
1447
+ // skip instance definition objects
1448
+ //if( _attributes.isInstanceDefinitionObject ) { continue; }
1449
+
1450
+ // TODO: handle other geometry types
1451
+ switch ( objectType ) {
1452
+
1453
+ case rhino.ObjectType.Curve:
1454
+
1455
+ const pts = curveToPoints( _geometry, 100 );
1456
+
1457
+ position = {};
1458
+ attributes = {};
1459
+ data = {};
1460
+
1461
+ position.itemSize = 3;
1462
+ position.type = 'Float32Array';
1463
+ position.array = [];
1464
+
1465
+ for ( let j = 0; j < pts.length; j ++ ) {
1466
+
1467
+ position.array.push( pts[ j ][ 0 ] );
1468
+ position.array.push( pts[ j ][ 1 ] );
1469
+ position.array.push( pts[ j ][ 2 ] );
1470
+
1471
+ }
1472
+
1473
+ attributes.position = position;
1474
+ data.attributes = attributes;
1475
+
1476
+ geometry = { data };
1477
+
1478
+ break;
1479
+
1480
+ case rhino.ObjectType.Point:
1481
+
1482
+ const pt = _geometry.location;
1483
+
1484
+ position = {};
1485
+ const color = {};
1486
+ attributes = {};
1487
+ data = {};
1488
+
1489
+ position.itemSize = 3;
1490
+ position.type = 'Float32Array';
1491
+ position.array = [ pt[ 0 ], pt[ 1 ], pt[ 2 ] ];
1492
+
1493
+ const _color = _attributes.drawColor( doc );
1494
+
1495
+ color.itemSize = 3;
1496
+ color.type = 'Float32Array';
1497
+ color.array = [ _color.r / 255.0, _color.g / 255.0, _color.b / 255.0 ];
1498
+
1499
+ attributes.position = position;
1500
+ attributes.color = color;
1501
+ data.attributes = attributes;
1502
+
1503
+ geometry = { data };
1504
+
1505
+ break;
1506
+
1507
+ case rhino.ObjectType.PointSet:
1508
+ case rhino.ObjectType.Mesh:
1509
+
1510
+ geometry = _geometry.toThreejsJSON();
1511
+
1512
+ break;
1513
+
1514
+ case rhino.ObjectType.Brep:
1515
+
1516
+ const faces = _geometry.faces();
1517
+ mesh = new rhino.Mesh();
1518
+
1519
+ for ( let faceIndex = 0; faceIndex < faces.count; faceIndex ++ ) {
1520
+
1521
+ const face = faces.get( faceIndex );
1522
+ const _mesh = face.getMesh( rhino.MeshType.Any );
1523
+
1524
+ if ( _mesh ) {
1525
+
1526
+ mesh.append( _mesh );
1527
+ _mesh.delete();
1528
+
1529
+ }
1530
+
1531
+ face.delete();
1532
+
1533
+ }
1534
+
1535
+ if ( mesh.faces().count > 0 ) {
1536
+
1537
+ mesh.compact();
1538
+ geometry = mesh.toThreejsJSON();
1539
+ faces.delete();
1540
+
1541
+ }
1542
+
1543
+ mesh.delete();
1544
+
1545
+ break;
1546
+
1547
+ case rhino.ObjectType.Extrusion:
1548
+
1549
+ mesh = _geometry.getMesh( rhino.MeshType.Any );
1550
+
1551
+ if ( mesh ) {
1552
+
1553
+ geometry = mesh.toThreejsJSON();
1554
+ mesh.delete();
1555
+
1556
+ }
1557
+
1558
+ break;
1559
+
1560
+ case rhino.ObjectType.TextDot:
1561
+
1562
+ geometry = extractProperties( _geometry );
1563
+
1564
+ break;
1565
+
1566
+ case rhino.ObjectType.Light:
1567
+
1568
+ geometry = extractProperties( _geometry );
1569
+
1570
+ if ( geometry.lightStyle.name === 'LightStyle_WorldLinear' ) {
1571
+
1572
+ self.postMessage( { type: 'warning', id: taskID, data: {
1573
+ message: `THREE.3DMLoader: No conversion exists for ${objectType.constructor.name} ${geometry.lightStyle.name}`,
1574
+ type: 'no conversion',
1575
+ guid: _attributes.id
1576
+ }
1577
+
1578
+ } );
1579
+
1580
+ }
1581
+
1582
+ break;
1583
+
1584
+ case rhino.ObjectType.InstanceReference:
1585
+
1586
+ geometry = extractProperties( _geometry );
1587
+ geometry.xform = extractProperties( _geometry.xform );
1588
+ geometry.xform.array = _geometry.xform.toFloatArray( true );
1589
+
1590
+ break;
1591
+
1592
+ case rhino.ObjectType.SubD:
1593
+
1594
+ // TODO: precalculate resulting vertices and faces and warn on excessive results
1595
+ _geometry.subdivide( 3 );
1596
+ mesh = rhino.Mesh.createFromSubDControlNet( _geometry, false );
1597
+ if ( mesh ) {
1598
+
1599
+ geometry = mesh.toThreejsJSON();
1600
+ mesh.delete();
1601
+
1602
+ }
1603
+
1604
+ break;
1605
+
1606
+ /*
1607
+ case rhino.ObjectType.Annotation:
1608
+ case rhino.ObjectType.Hatch:
1609
+ case rhino.ObjectType.ClipPlane:
1610
+ */
1611
+
1612
+ default:
1613
+
1614
+ self.postMessage( { type: 'warning', id: taskID, data: {
1615
+ message: `THREE.3DMLoader: Conversion not implemented for ${objectType.constructor.name}`,
1616
+ type: 'not implemented',
1617
+ guid: _attributes.id
1618
+ }
1619
+
1620
+ } );
1621
+
1622
+ break;
1623
+
1624
+ }
1625
+
1626
+ if ( geometry ) {
1627
+
1628
+ attributes = extractProperties( _attributes );
1629
+ attributes.geometry = extractProperties( _geometry );
1630
+
1631
+ if ( _attributes.groupCount > 0 ) {
1632
+
1633
+ attributes.groupIds = _attributes.getGroupList();
1634
+
1635
+ }
1636
+
1637
+ if ( _attributes.userStringCount > 0 ) {
1638
+
1639
+ attributes.userStrings = _attributes.getUserStrings();
1640
+
1641
+ }
1642
+
1643
+ if ( _geometry.userStringCount > 0 ) {
1644
+
1645
+ attributes.geometry.userStrings = _geometry.getUserStrings();
1646
+
1647
+ }
1648
+
1649
+ if ( _attributes.decals().count > 0 ) {
1650
+
1651
+ self.postMessage( { type: 'warning', id: taskID, data: {
1652
+ message: 'THREE.3DMLoader: No conversion exists for the decals associated with this object.',
1653
+ type: 'no conversion',
1654
+ guid: _attributes.id
1655
+ }
1656
+
1657
+ } );
1658
+
1659
+ }
1660
+
1661
+ attributes.drawColor = _attributes.drawColor( doc );
1662
+
1663
+ objectType = objectType.constructor.name;
1664
+ objectType = objectType.substring( 11, objectType.length );
1665
+
1666
+ return { geometry, attributes, objectType };
1667
+
1668
+ } else {
1669
+
1670
+ self.postMessage( { type: 'warning', id: taskID, data: {
1671
+ message: `THREE.3DMLoader: ${objectType.constructor.name} has no associated mesh geometry.`,
1672
+ type: 'missing mesh',
1673
+ guid: _attributes.id
1674
+ }
1675
+
1676
+ } );
1677
+
1678
+ }
1679
+
1680
+ }
1681
+
1682
+ function extractProperties( object ) {
1683
+
1684
+ const result = {};
1685
+
1686
+ for ( const property in object ) {
1687
+
1688
+ const value = object[ property ];
1689
+
1690
+ if ( typeof value !== 'function' ) {
1691
+
1692
+ if ( typeof value === 'object' && value !== null && value.hasOwnProperty( 'constructor' ) ) {
1693
+
1694
+ result[ property ] = { name: value.constructor.name, value: value.value };
1695
+
1696
+ } else if ( typeof value === 'object' && value !== null ) {
1697
+
1698
+ result[ property ] = extractProperties( value );
1699
+
1700
+ } else {
1701
+
1702
+ result[ property ] = value;
1703
+
1704
+ }
1705
+
1706
+ } else {
1707
+
1708
+ // these are functions that could be called to extract more data.
1709
+ //console.log( `${property}: ${object[ property ].constructor.name}` );
1710
+
1711
+ }
1712
+
1713
+ }
1714
+
1715
+ return result;
1716
+
1717
+ }
1718
+
1719
+ function curveToPoints( curve, pointLimit ) {
1720
+
1721
+ let pointCount = pointLimit;
1722
+ let rc = [];
1723
+ const ts = [];
1724
+
1725
+ if ( curve instanceof rhino.LineCurve ) {
1726
+
1727
+ return [ curve.pointAtStart, curve.pointAtEnd ];
1728
+
1729
+ }
1730
+
1731
+ if ( curve instanceof rhino.PolylineCurve ) {
1732
+
1733
+ pointCount = curve.pointCount;
1734
+ for ( let i = 0; i < pointCount; i ++ ) {
1735
+
1736
+ rc.push( curve.point( i ) );
1737
+
1738
+ }
1739
+
1740
+ return rc;
1741
+
1742
+ }
1743
+
1744
+ if ( curve instanceof rhino.PolyCurve ) {
1745
+
1746
+ const segmentCount = curve.segmentCount;
1747
+
1748
+ for ( let i = 0; i < segmentCount; i ++ ) {
1749
+
1750
+ const segment = curve.segmentCurve( i );
1751
+ const segmentArray = curveToPoints( segment, pointCount );
1752
+ rc = rc.concat( segmentArray );
1753
+ segment.delete();
1754
+
1755
+ }
1756
+
1757
+ return rc;
1758
+
1759
+ }
1760
+
1761
+ if ( curve instanceof rhino.ArcCurve ) {
1762
+
1763
+ pointCount = Math.floor( curve.angleDegrees / 5 );
1764
+ pointCount = pointCount < 2 ? 2 : pointCount;
1765
+ // alternative to this hardcoded version: https://stackoverflow.com/a/18499923/2179399
1766
+
1767
+ }
1768
+
1769
+ if ( curve instanceof rhino.NurbsCurve && curve.degree === 1 ) {
1770
+
1771
+ const pLine = curve.tryGetPolyline();
1772
+
1773
+ for ( let i = 0; i < pLine.count; i ++ ) {
1774
+
1775
+ rc.push( pLine.get( i ) );
1776
+
1777
+ }
1778
+
1779
+ pLine.delete();
1780
+
1781
+ return rc;
1782
+
1783
+ }
1784
+
1785
+ const domain = curve.domain;
1786
+ const divisions = pointCount - 1.0;
1787
+
1788
+ for ( let j = 0; j < pointCount; j ++ ) {
1789
+
1790
+ const t = domain[ 0 ] + ( j / divisions ) * ( domain[ 1 ] - domain[ 0 ] );
1791
+
1792
+ if ( t === domain[ 0 ] || t === domain[ 1 ] ) {
1793
+
1794
+ ts.push( t );
1795
+ continue;
1796
+
1797
+ }
1798
+
1799
+ const tan = curve.tangentAt( t );
1800
+ const prevTan = curve.tangentAt( ts.slice( - 1 )[ 0 ] );
1801
+
1802
+ // Duplicated from THREE.Vector3
1803
+ // How to pass imports to worker?
1804
+
1805
+ const tS = tan[ 0 ] * tan[ 0 ] + tan[ 1 ] * tan[ 1 ] + tan[ 2 ] * tan[ 2 ];
1806
+ const ptS = prevTan[ 0 ] * prevTan[ 0 ] + prevTan[ 1 ] * prevTan[ 1 ] + prevTan[ 2 ] * prevTan[ 2 ];
1807
+
1808
+ const denominator = Math.sqrt( tS * ptS );
1809
+
1810
+ let angle;
1811
+
1812
+ if ( denominator === 0 ) {
1813
+
1814
+ angle = Math.PI / 2;
1815
+
1816
+ } else {
1817
+
1818
+ const theta = ( tan.x * prevTan.x + tan.y * prevTan.y + tan.z * prevTan.z ) / denominator;
1819
+ angle = Math.acos( Math.max( - 1, Math.min( 1, theta ) ) );
1820
+
1821
+ }
1822
+
1823
+ if ( angle < 0.1 ) continue;
1824
+
1825
+ ts.push( t );
1826
+
1827
+ }
1828
+
1829
+ rc = ts.map( t => curve.pointAt( t ) );
1830
+ return rc;
1831
+
1832
+ }
1833
+
1834
+ }
1835
+
1836
+ export { Rhino3dmLoader };