@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 +1 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +76 -105
- package/package.json +1 -1
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
|
|
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;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AA0B/B,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,QAAQ,KAAK,IAAI,CAAC;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;IACxC,gBAAgB,CAAC,EAAE,OAAO,
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
204
|
-
material.polygonOffsetUnits =
|
|
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 = {
|