@treasuryspatial/rhino-bridge 0.1.6 → 0.1.7

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.
package/dist/index.d.ts CHANGED
@@ -13,14 +13,7 @@ export type GeometryBridgeOptions = {
13
13
  layerKey?: string;
14
14
  materialKey?: string;
15
15
  curveMode?: "auto" | "always" | "never";
16
- zFightMitigation?: boolean | ZFightMitigationOptions;
17
- };
18
- export type ZFightMitigationOptions = {
19
- enabled?: boolean;
20
- dedupe?: boolean;
21
- polygonOffset?: boolean;
22
- polygonOffsetFactor?: number;
23
- polygonOffsetUnits?: number;
16
+ zFightMitigation?: boolean;
24
17
  };
25
18
  export type LayeredGeometryOptions = {
26
19
  mapLayerToId?: (layerName: string, attributes: any) => string | null;
@@ -32,10 +25,6 @@ export type LayeredGeometryOptions = {
32
25
  layerKey?: string;
33
26
  materialKey?: string;
34
27
  };
35
- export declare const sanitizeObject3d: (root?: THREE.Object3D | null) => void;
36
- export declare const dedupeMeshesInGroup: (group?: THREE.Group | null) => void;
37
- export declare const applyPolygonOffsetToGroup: (group?: THREE.Group | null, factor?: number, units?: number) => void;
38
- export declare const applyZFightMitigation: (group?: THREE.Group | null, options?: boolean | ZFightMitigationOptions) => void;
39
28
  export declare function threeGroupFrom3dm(base64: string, options?: GeometryBridgeOptions): Promise<THREE.Group>;
40
29
  export type Geometry3dmInspection = {
41
30
  ok: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -18,26 +18,6 @@ const resolveBrowserWasmUrl = (path, override) => {
18
18
  return DEFAULT_BROWSER_WASM_PATH;
19
19
  };
20
20
  let geometryModulePromise = null;
21
- const DEFAULT_Z_FIGHT_OPTIONS = {
22
- enabled: true,
23
- dedupe: true,
24
- polygonOffset: true,
25
- polygonOffsetFactor: 0.5,
26
- polygonOffsetUnits: 0.5,
27
- };
28
- const resolveZFightOptions = (input) => {
29
- if (input === false || input === undefined || input === null)
30
- return null;
31
- if (input === true)
32
- return { ...DEFAULT_Z_FIGHT_OPTIONS };
33
- if (input.enabled === false)
34
- return null;
35
- return {
36
- ...DEFAULT_Z_FIGHT_OPTIONS,
37
- ...input,
38
- enabled: input.enabled ?? true,
39
- };
40
- };
41
21
  async function getGeometryModule(options) {
42
22
  if (!geometryModulePromise) {
43
23
  if (typeof window === "undefined") {
@@ -128,7 +108,76 @@ const resolveUserString = (attributes, keys) => {
128
108
  }
129
109
  return null;
130
110
  };
131
- export const sanitizeObject3d = (root) => {
111
+ export async function threeGroupFrom3dm(base64, options) {
112
+ const rhino = await getGeometryModule(options);
113
+ const bytes = base64ToUint8Array(base64);
114
+ const doc = rhino.File3dm.fromByteArray(bytes);
115
+ const group = new THREE.Group();
116
+ if (!doc) {
117
+ console.error("[geometry] Failed to parse 3DM file from bytes");
118
+ return group;
119
+ }
120
+ const rotation = options?.rotateToYUp === false ? null : new THREE.Matrix4().makeRotationX(-Math.PI / 2);
121
+ const roleKeys = options?.roleKeys ?? [];
122
+ const roleKey = options?.roleKey ?? DEFAULT_ROLE_KEY;
123
+ const roleKeyList = roleKeys.length > 0 ? [roleKey, ...roleKeys] : [roleKey];
124
+ const excludeRoles = options?.excludeRoles ?? [];
125
+ const packetKey = options?.packetKey ?? DEFAULT_ID_KEY;
126
+ const layerKey = options?.layerKey ?? "b2:layer";
127
+ const materialKey = options?.materialKey ?? "b2:material";
128
+ const objects = doc.objects();
129
+ const objectCount = objects.count ?? 0;
130
+ const curveMode = options?.curveMode ?? "auto";
131
+ let allowCurves = curveMode === "always";
132
+ if (curveMode === "auto") {
133
+ allowCurves = true;
134
+ for (let i = 0; i < objectCount; i += 1) {
135
+ const obj = objects.get(i);
136
+ const geom = obj?.geometry?.();
137
+ const typeName = geom?.constructor?.name;
138
+ if (typeName === "Mesh") {
139
+ allowCurves = false;
140
+ break;
141
+ }
142
+ }
143
+ }
144
+ else if (curveMode === "never") {
145
+ allowCurves = false;
146
+ }
147
+ for (let i = 0; i < objectCount; i += 1) {
148
+ const obj = objects.get(i);
149
+ const attributes = typeof obj?.attributes === "function" ? obj.attributes() : null;
150
+ const role = attributes ? resolveUserString(attributes, roleKeyList) : null;
151
+ if (role && excludeRoles.includes(role)) {
152
+ continue;
153
+ }
154
+ const geom = obj?.geometry?.();
155
+ const threeObject = convertGeometryToThree(geom, { allowCurves });
156
+ if (threeObject) {
157
+ if (rotation) {
158
+ threeObject.applyMatrix4(rotation);
159
+ }
160
+ const packetId = attributes ? getUserString(attributes, packetKey) : null;
161
+ const layer = attributes ? getUserString(attributes, layerKey) : null;
162
+ const material = attributes ? getUserString(attributes, materialKey) : null;
163
+ threeObject.userData = {
164
+ role: role ?? undefined,
165
+ packet: packetId ?? undefined,
166
+ id: packetId ?? undefined,
167
+ layer: layer ?? undefined,
168
+ material: material ?? undefined,
169
+ };
170
+ options?.transform?.(threeObject);
171
+ group.add(threeObject);
172
+ }
173
+ }
174
+ if (options?.zFightMitigation) {
175
+ dedupeMeshesInGroup(group);
176
+ applyZFightMitigation(group);
177
+ }
178
+ return group;
179
+ }
180
+ const sanitizeObject3d = (root) => {
132
181
  if (!root || !Array.isArray(root.children))
133
182
  return;
134
183
  const children = root.children;
@@ -142,6 +191,8 @@ export const sanitizeObject3d = (root) => {
142
191
  }
143
192
  };
144
193
  const buildGeometrySignature = (geometry) => {
194
+ if (!geometry)
195
+ return null;
145
196
  const position = geometry.getAttribute("position");
146
197
  if (!position || position.count === 0)
147
198
  return null;
@@ -160,7 +211,7 @@ const buildGeometrySignature = (geometry) => {
160
211
  }
161
212
  return signature;
162
213
  };
163
- export const dedupeMeshesInGroup = (group) => {
214
+ const dedupeMeshesInGroup = (group) => {
164
215
  if (!group || typeof group.traverse !== "function")
165
216
  return;
166
217
  sanitizeObject3d(group);
@@ -189,7 +240,7 @@ export const dedupeMeshesInGroup = (group) => {
189
240
  });
190
241
  }
191
242
  };
192
- export const applyPolygonOffsetToGroup = (group, factor = DEFAULT_Z_FIGHT_OPTIONS.polygonOffsetFactor, units = DEFAULT_Z_FIGHT_OPTIONS.polygonOffsetUnits) => {
243
+ const applyZFightMitigation = (group) => {
193
244
  if (!group || typeof group.traverse !== "function")
194
245
  return;
195
246
  group.traverse((object) => {
@@ -200,91 +251,11 @@ export const applyPolygonOffsetToGroup = (group, factor = DEFAULT_Z_FIGHT_OPTION
200
251
  if (!material)
201
252
  return;
202
253
  material.polygonOffset = true;
203
- material.polygonOffsetFactor = factor;
204
- material.polygonOffsetUnits = units;
254
+ material.polygonOffsetFactor = 0.5;
255
+ material.polygonOffsetUnits = 0.5;
205
256
  });
206
257
  });
207
258
  };
208
- export const applyZFightMitigation = (group, options) => {
209
- const resolved = resolveZFightOptions(options);
210
- if (!resolved || !group)
211
- return;
212
- if (resolved.dedupe) {
213
- dedupeMeshesInGroup(group);
214
- }
215
- if (resolved.polygonOffset) {
216
- applyPolygonOffsetToGroup(group, resolved.polygonOffsetFactor, resolved.polygonOffsetUnits);
217
- }
218
- };
219
- export async function threeGroupFrom3dm(base64, options) {
220
- const rhino = await getGeometryModule(options);
221
- const bytes = base64ToUint8Array(base64);
222
- const doc = rhino.File3dm.fromByteArray(bytes);
223
- const group = new THREE.Group();
224
- if (!doc) {
225
- console.error("[geometry] Failed to parse 3DM file from bytes");
226
- return group;
227
- }
228
- const rotation = options?.rotateToYUp === false ? null : new THREE.Matrix4().makeRotationX(-Math.PI / 2);
229
- const roleKeys = options?.roleKeys ?? [];
230
- const roleKey = options?.roleKey ?? DEFAULT_ROLE_KEY;
231
- const roleKeyList = roleKeys.length > 0 ? [roleKey, ...roleKeys] : [roleKey];
232
- const excludeRoles = options?.excludeRoles ?? [];
233
- const packetKey = options?.packetKey ?? DEFAULT_ID_KEY;
234
- const layerKey = options?.layerKey ?? "b2:layer";
235
- const materialKey = options?.materialKey ?? "b2:material";
236
- const objects = doc.objects();
237
- const objectCount = objects.count ?? 0;
238
- const curveMode = options?.curveMode ?? "auto";
239
- let allowCurves = curveMode === "always";
240
- if (curveMode === "auto") {
241
- allowCurves = true;
242
- for (let i = 0; i < objectCount; i += 1) {
243
- const obj = objects.get(i);
244
- const geom = obj?.geometry?.();
245
- const typeName = geom?.constructor?.name;
246
- if (typeName === "Mesh") {
247
- allowCurves = false;
248
- break;
249
- }
250
- }
251
- }
252
- else if (curveMode === "never") {
253
- allowCurves = false;
254
- }
255
- for (let i = 0; i < objectCount; i += 1) {
256
- const obj = objects.get(i);
257
- const attributes = typeof obj?.attributes === "function" ? obj.attributes() : null;
258
- const role = attributes ? resolveUserString(attributes, roleKeyList) : null;
259
- if (role && excludeRoles.includes(role)) {
260
- continue;
261
- }
262
- const geom = obj?.geometry?.();
263
- const threeObject = convertGeometryToThree(geom, { allowCurves });
264
- if (threeObject) {
265
- if (rotation) {
266
- threeObject.applyMatrix4(rotation);
267
- }
268
- const packetId = attributes ? getUserString(attributes, packetKey) : null;
269
- const layer = attributes ? getUserString(attributes, layerKey) : null;
270
- const material = attributes ? getUserString(attributes, materialKey) : null;
271
- threeObject.userData = {
272
- role: role ?? undefined,
273
- packet: packetId ?? undefined,
274
- id: packetId ?? undefined,
275
- layer: layer ?? undefined,
276
- material: material ?? undefined,
277
- };
278
- options?.transform?.(threeObject);
279
- group.add(threeObject);
280
- }
281
- }
282
- sanitizeObject3d(group);
283
- if (options?.zFightMitigation) {
284
- applyZFightMitigation(group, options.zFightMitigation);
285
- }
286
- return group;
287
- }
288
259
  export async function grasshopperResultTo3dmBase64(result) {
289
260
  const rhino = await getGeometryModule();
290
261
  const stats = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@treasuryspatial/rhino-bridge",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
4
4
  "type": "module",
5
5
  "license": "UNLICENSED",
6
6
  "main": "./dist/index.js",