@thatopen/components 3.4.5 → 3.4.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/README.md +1 -0
- package/dist/index.cjs +385 -97
- package/dist/index.d.ts +85 -2
- package/dist/index.min.cjs +2 -2
- package/dist/index.min.mjs +2 -2
- package/dist/index.mjs +387 -99
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -197,6 +197,15 @@ class BaseRenderer extends BaseWorldItem {
|
|
|
197
197
|
* The list of [clipping planes](https://threejs.org/docs/#api/en/renderers/WebGLRenderer.clippingPlanes) used by this instance of the renderer.
|
|
198
198
|
*/
|
|
199
199
|
__publicField(this, "clippingPlanes", []);
|
|
200
|
+
/**
|
|
201
|
+
* The default `isLocal` value used by {@link setPlane} when the caller
|
|
202
|
+
* doesn't pass one. When `true`, planes added without an explicit
|
|
203
|
+
* `isLocal` stay out of the global `three.clippingPlanes` list and are
|
|
204
|
+
* clipped per-material instead. The {@link Clipper} sets this to mirror
|
|
205
|
+
* its own `localClippingPlanes` flag, so consumers like `Views` that add
|
|
206
|
+
* their own planes automatically inherit the active clipping mode.
|
|
207
|
+
*/
|
|
208
|
+
__publicField(this, "localClippingPlanes", false);
|
|
200
209
|
}
|
|
201
210
|
/**
|
|
202
211
|
* Updates the clipping planes and triggers the `onClippingPlanesUpdated` event.
|
|
@@ -222,7 +231,7 @@ class BaseRenderer extends BaseWorldItem {
|
|
|
222
231
|
* The `three.clippingPlanes` property is then updated to reflect the current state of the `clippingPlanes` array,
|
|
223
232
|
* excluding any planes marked as local.
|
|
224
233
|
*/
|
|
225
|
-
setPlane(active, plane, isLocal) {
|
|
234
|
+
setPlane(active, plane, isLocal = this.localClippingPlanes) {
|
|
226
235
|
plane.isLocal = isLocal;
|
|
227
236
|
const index = this.clippingPlanes.indexOf(plane);
|
|
228
237
|
if (active && index === -1) {
|
|
@@ -233,6 +242,7 @@ class BaseRenderer extends BaseWorldItem {
|
|
|
233
242
|
this.three.clippingPlanes = this.clippingPlanes.filter(
|
|
234
243
|
(plane2) => !plane2.isLocal
|
|
235
244
|
);
|
|
245
|
+
this.updateClippingPlanes();
|
|
236
246
|
}
|
|
237
247
|
}
|
|
238
248
|
const _Disposer = class _Disposer extends Component {
|
|
@@ -9487,9 +9497,11 @@ class VisibilityCuller {
|
|
|
9487
9497
|
const tilesX = Math.ceil(pixelWidth / maxTextureSize);
|
|
9488
9498
|
const tilesY = Math.ceil(pixelHeight / maxTextureSize);
|
|
9489
9499
|
target.setSize(Math.ceil(pixelWidth / tilesX), Math.ceil(pixelHeight / tilesY));
|
|
9500
|
+
const yMargin = Math.max(size.y, 1) * 0.01;
|
|
9490
9501
|
camera.rotation.x = -Math.PI / 2;
|
|
9491
|
-
camera.
|
|
9492
|
-
camera.
|
|
9502
|
+
camera.near = 0;
|
|
9503
|
+
camera.far = size.y + 2 * yMargin;
|
|
9504
|
+
camera.position.y = box.max.y + yMargin;
|
|
9493
9505
|
const idScene = new THREE.Scene();
|
|
9494
9506
|
const originalMaterials = /* @__PURE__ */ new Map();
|
|
9495
9507
|
const originalParents = /* @__PURE__ */ new Map();
|
|
@@ -9523,7 +9535,7 @@ class VisibilityCuller {
|
|
|
9523
9535
|
const tileMaxZ = tileMinZ + stepZ;
|
|
9524
9536
|
const tileCenterX = (tileMinX + tileMaxX) / 2;
|
|
9525
9537
|
const tileCenterZ = (tileMinZ + tileMaxZ) / 2;
|
|
9526
|
-
camera.position.set(tileCenterX, box.max.y, tileCenterZ);
|
|
9538
|
+
camera.position.set(tileCenterX, box.max.y + yMargin, tileCenterZ);
|
|
9527
9539
|
const halfWidth = stepX / 2;
|
|
9528
9540
|
const halfHeight = stepZ / 2;
|
|
9529
9541
|
camera.left = -halfWidth;
|
|
@@ -9572,6 +9584,11 @@ class IDMaterial extends THREE.ShaderMaterial {
|
|
|
9572
9584
|
super({
|
|
9573
9585
|
glslVersion: THREE.GLSL3,
|
|
9574
9586
|
blending: THREE.NoBlending,
|
|
9587
|
+
// A flat item (a slab) seen straight down shows only one face; if its
|
|
9588
|
+
// winding puts the back face toward the camera it wouldn't rasterize and
|
|
9589
|
+
// the item would be culled. The pass only cares about coverage, so render
|
|
9590
|
+
// both sides.
|
|
9591
|
+
side: THREE.DoubleSide,
|
|
9575
9592
|
uniforms: {
|
|
9576
9593
|
objectId: { value: new THREE.Vector4() }
|
|
9577
9594
|
},
|
|
@@ -12562,6 +12579,19 @@ const _FastModelPicker = class _FastModelPicker {
|
|
|
12562
12579
|
* restored after.
|
|
12563
12580
|
*/
|
|
12564
12581
|
__publicField(this, "_hiddenLods", []);
|
|
12582
|
+
/**
|
|
12583
|
+
* The meshes each model owns, i.e. excluding those belonging to a
|
|
12584
|
+
* model nested inside it. A delta model's object is parented under
|
|
12585
|
+
* its parent model's object (see the fragments EditHelper), while
|
|
12586
|
+
* both are listed as separate models, so subtree membership alone
|
|
12587
|
+
* does not determine ownership.
|
|
12588
|
+
*
|
|
12589
|
+
* Populated in {@link applyIdMaterial}, consumed by
|
|
12590
|
+
* {@link renderPickPass} to isolate one model per render without
|
|
12591
|
+
* relying on root visibility. A nested model can't be isolated by
|
|
12592
|
+
* its root, since hiding the parent's root culls the child too.
|
|
12593
|
+
*/
|
|
12594
|
+
__publicField(this, "_ownMeshes", /* @__PURE__ */ new Map());
|
|
12565
12595
|
if (!world.renderer) {
|
|
12566
12596
|
throw new Error("A renderer is needed for the FastModelPicker to work!");
|
|
12567
12597
|
}
|
|
@@ -12802,14 +12832,14 @@ const _FastModelPicker = class _FastModelPicker {
|
|
|
12802
12832
|
applyIdMaterial() {
|
|
12803
12833
|
const fragments = this.components.get(FragmentsManager);
|
|
12804
12834
|
const byteToModel = /* @__PURE__ */ new Map();
|
|
12835
|
+
const modelRoots = this.getModelRoots();
|
|
12836
|
+
this._ownMeshes.clear();
|
|
12805
12837
|
let nextByte = 1;
|
|
12806
12838
|
for (const [modelId, model] of fragments.list) {
|
|
12807
12839
|
if (nextByte > _FastModelPicker.MAX_MODELS)
|
|
12808
12840
|
break;
|
|
12809
|
-
const
|
|
12810
|
-
|
|
12811
|
-
let any = false;
|
|
12812
|
-
model.object.traverse((child) => {
|
|
12841
|
+
const owned = [];
|
|
12842
|
+
this.traverseOwn(model.object, modelRoots, (child) => {
|
|
12813
12843
|
if (!(child instanceof THREE__namespace.Mesh))
|
|
12814
12844
|
return;
|
|
12815
12845
|
const geom = child.geometry;
|
|
@@ -12823,14 +12853,47 @@ const _FastModelPicker = class _FastModelPicker {
|
|
|
12823
12853
|
return;
|
|
12824
12854
|
}
|
|
12825
12855
|
this._originalMaterials.set(child, child.material);
|
|
12826
|
-
|
|
12827
|
-
|
|
12856
|
+
const original = child.material;
|
|
12857
|
+
const len = Array.isArray(original) ? original.length : 1;
|
|
12858
|
+
child.material = new Array(len).fill(this._idMaterial);
|
|
12859
|
+
owned.push(child);
|
|
12828
12860
|
});
|
|
12829
|
-
if (
|
|
12830
|
-
|
|
12861
|
+
if (!owned.length)
|
|
12862
|
+
continue;
|
|
12863
|
+
this._ownMeshes.set(modelId, owned);
|
|
12864
|
+
byteToModel.set(nextByte, modelId);
|
|
12865
|
+
nextByte += 1;
|
|
12831
12866
|
}
|
|
12832
12867
|
return byteToModel;
|
|
12833
12868
|
}
|
|
12869
|
+
/**
|
|
12870
|
+
* The object roots of every loaded model.
|
|
12871
|
+
*/
|
|
12872
|
+
getModelRoots() {
|
|
12873
|
+
const fragments = this.components.get(FragmentsManager);
|
|
12874
|
+
const roots = /* @__PURE__ */ new Set();
|
|
12875
|
+
for (const [, model] of fragments.list)
|
|
12876
|
+
roots.add(model.object);
|
|
12877
|
+
return roots;
|
|
12878
|
+
}
|
|
12879
|
+
/**
|
|
12880
|
+
* Like `Object3D.traverse`, but prunes the subtree of any nested model
|
|
12881
|
+
* root, so each mesh is visited exactly once, by the model that owns
|
|
12882
|
+
* it. A delta model's object hangs under its parent model's object
|
|
12883
|
+
* while being a model in its own right; a plain `traverse` from the
|
|
12884
|
+
* parent would walk into it.
|
|
12885
|
+
*/
|
|
12886
|
+
traverseOwn(root, modelRoots, callback) {
|
|
12887
|
+
const stack = [root];
|
|
12888
|
+
while (stack.length) {
|
|
12889
|
+
const node = stack.pop();
|
|
12890
|
+
if (node !== root && modelRoots.has(node))
|
|
12891
|
+
continue;
|
|
12892
|
+
callback(node);
|
|
12893
|
+
for (const child of node.children)
|
|
12894
|
+
stack.push(child);
|
|
12895
|
+
}
|
|
12896
|
+
}
|
|
12834
12897
|
/**
|
|
12835
12898
|
* Renders the world scene to the id target one model at a time,
|
|
12836
12899
|
* flipping the `modelByte` uniform between renders. The depth buffer
|
|
@@ -12921,21 +12984,47 @@ const _FastModelPicker = class _FastModelPicker {
|
|
|
12921
12984
|
nonBimVisibility.set(child, child.visible);
|
|
12922
12985
|
child.visible = false;
|
|
12923
12986
|
});
|
|
12924
|
-
const
|
|
12987
|
+
const wasOnScreen = /* @__PURE__ */ new Map();
|
|
12988
|
+
for (const [modelId, obj] of objectsByModel) {
|
|
12989
|
+
let visible = true;
|
|
12990
|
+
let node = obj;
|
|
12991
|
+
while (node) {
|
|
12992
|
+
if (!node.visible) {
|
|
12993
|
+
visible = false;
|
|
12994
|
+
break;
|
|
12995
|
+
}
|
|
12996
|
+
node = node.parent;
|
|
12997
|
+
}
|
|
12998
|
+
wasOnScreen.set(modelId, visible);
|
|
12999
|
+
}
|
|
13000
|
+
const rootVisibilityBefore = /* @__PURE__ */ new Map();
|
|
12925
13001
|
for (const obj of objectsByModel.values()) {
|
|
12926
|
-
|
|
12927
|
-
obj.visible =
|
|
13002
|
+
rootVisibilityBefore.set(obj, obj.visible);
|
|
13003
|
+
obj.visible = true;
|
|
13004
|
+
}
|
|
13005
|
+
const meshVisibilityBefore = /* @__PURE__ */ new Map();
|
|
13006
|
+
for (const meshes of this._ownMeshes.values()) {
|
|
13007
|
+
for (const mesh of meshes) {
|
|
13008
|
+
meshVisibilityBefore.set(mesh, mesh.visible);
|
|
13009
|
+
mesh.visible = false;
|
|
13010
|
+
}
|
|
12928
13011
|
}
|
|
12929
13012
|
for (const [byte, modelId] of byteToModel) {
|
|
12930
|
-
|
|
12931
|
-
if (!obj)
|
|
13013
|
+
if (!wasOnScreen.get(modelId))
|
|
12932
13014
|
continue;
|
|
12933
|
-
|
|
13015
|
+
const meshes = this._ownMeshes.get(modelId);
|
|
13016
|
+
if (!meshes)
|
|
13017
|
+
continue;
|
|
13018
|
+
for (const mesh of meshes)
|
|
13019
|
+
mesh.visible = meshVisibilityBefore.get(mesh);
|
|
12934
13020
|
material.uniforms.modelByte.value = byte;
|
|
12935
13021
|
renderer.render(scene, camera);
|
|
12936
|
-
|
|
13022
|
+
for (const mesh of meshes)
|
|
13023
|
+
mesh.visible = false;
|
|
12937
13024
|
}
|
|
12938
|
-
for (const [
|
|
13025
|
+
for (const [mesh, was] of meshVisibilityBefore)
|
|
13026
|
+
mesh.visible = was;
|
|
13027
|
+
for (const [obj, was] of rootVisibilityBefore)
|
|
12939
13028
|
obj.visible = was;
|
|
12940
13029
|
for (const [obj, was] of nonBimVisibility)
|
|
12941
13030
|
obj.visible = was;
|
|
@@ -12976,8 +13065,9 @@ const _FastModelPicker = class _FastModelPicker {
|
|
|
12976
13065
|
const prevClearAlpha = renderer.getClearAlpha();
|
|
12977
13066
|
const matSwap = /* @__PURE__ */ new Map();
|
|
12978
13067
|
const hiddenLines = [];
|
|
13068
|
+
const modelRoots = this.getModelRoots();
|
|
12979
13069
|
for (const [, model] of fragments.list) {
|
|
12980
|
-
model.object
|
|
13070
|
+
this.traverseOwn(model.object, modelRoots, (child) => {
|
|
12981
13071
|
if (!(child instanceof THREE__namespace.Mesh))
|
|
12982
13072
|
return;
|
|
12983
13073
|
const geom = child.geometry;
|
|
@@ -12993,7 +13083,9 @@ const _FastModelPicker = class _FastModelPicker {
|
|
|
12993
13083
|
if (!child.visible)
|
|
12994
13084
|
return;
|
|
12995
13085
|
matSwap.set(child, child.material);
|
|
12996
|
-
|
|
13086
|
+
const original = child.material;
|
|
13087
|
+
const len = Array.isArray(original) ? original.length : 1;
|
|
13088
|
+
child.material = new Array(len).fill(material);
|
|
12997
13089
|
});
|
|
12998
13090
|
}
|
|
12999
13091
|
const bimRoots = /* @__PURE__ */ new Set();
|
|
@@ -13045,6 +13137,7 @@ const _FastModelPicker = class _FastModelPicker {
|
|
|
13045
13137
|
mesh.material = mat;
|
|
13046
13138
|
}
|
|
13047
13139
|
this._originalMaterials.clear();
|
|
13140
|
+
this._ownMeshes.clear();
|
|
13048
13141
|
for (const obj of this._hiddenLods)
|
|
13049
13142
|
obj.visible = true;
|
|
13050
13143
|
this._hiddenLods.length = 0;
|
|
@@ -13421,12 +13514,32 @@ class SnapResolver {
|
|
|
13421
13514
|
*/
|
|
13422
13515
|
__publicField(this, "maxCacheSize", 1e3);
|
|
13423
13516
|
__publicField(this, "components");
|
|
13517
|
+
__publicField(this, "_precision", "half");
|
|
13424
13518
|
// Map insertion order is recency order (LRU). On every read we
|
|
13425
13519
|
// delete + re-set the entry to bump it to most-recent; on every
|
|
13426
13520
|
// write we drop oldest entries until size <= maxCacheSize.
|
|
13427
13521
|
__publicField(this, "cache", /* @__PURE__ */ new Map());
|
|
13428
13522
|
this.components = components;
|
|
13429
13523
|
}
|
|
13524
|
+
/**
|
|
13525
|
+
* Numeric precision for cached face/edge/vertex buffers.
|
|
13526
|
+
*
|
|
13527
|
+
* `"half"` uses Float32Array for lower memory footprint.
|
|
13528
|
+
* `"full"` uses Float64Array for higher numeric precision.
|
|
13529
|
+
* Use `"full"` for workflows that require higher geometric fidelity.
|
|
13530
|
+
*
|
|
13531
|
+
* Changing this value clears the snap cache so subsequent requests
|
|
13532
|
+
* are rebuilt with the new precision.
|
|
13533
|
+
*/
|
|
13534
|
+
get precision() {
|
|
13535
|
+
return this._precision;
|
|
13536
|
+
}
|
|
13537
|
+
set precision(value) {
|
|
13538
|
+
if (value === this._precision)
|
|
13539
|
+
return;
|
|
13540
|
+
this._precision = value;
|
|
13541
|
+
this.clear();
|
|
13542
|
+
}
|
|
13430
13543
|
/** {@link Disposable.dispose} */
|
|
13431
13544
|
dispose() {
|
|
13432
13545
|
this.cache.clear();
|
|
@@ -13566,8 +13679,8 @@ class SnapResolver {
|
|
|
13566
13679
|
}
|
|
13567
13680
|
if (polygons.length === 0)
|
|
13568
13681
|
return null;
|
|
13569
|
-
const edges = deriveUniqueEdges(polygons);
|
|
13570
|
-
const vertices = deriveUniqueVertices(polygons);
|
|
13682
|
+
const edges = deriveUniqueEdges(polygons, this._precision);
|
|
13683
|
+
const vertices = deriveUniqueVertices(polygons, this._precision);
|
|
13571
13684
|
return { faces: polygons, edges, vertices };
|
|
13572
13685
|
}
|
|
13573
13686
|
collectPolygonsFromShell(shell, worldMatrix, out) {
|
|
@@ -13578,7 +13691,8 @@ class SnapResolver {
|
|
|
13578
13691
|
const collect = (indices) => {
|
|
13579
13692
|
if (indices.length < 3)
|
|
13580
13693
|
return;
|
|
13581
|
-
const
|
|
13694
|
+
const Ctor = this._precision === "full" ? Float64Array : Float32Array;
|
|
13695
|
+
const flat = new Ctor(indices.length * 3);
|
|
13582
13696
|
for (let i = 0; i < indices.length; i++) {
|
|
13583
13697
|
const p = points[indices[i]];
|
|
13584
13698
|
tmp.set(p[0], p[1], p[2]).applyMatrix4(worldMatrix);
|
|
@@ -13687,19 +13801,33 @@ class SnapResolver {
|
|
|
13687
13801
|
return null;
|
|
13688
13802
|
let best = null;
|
|
13689
13803
|
let bestAbs = Infinity;
|
|
13804
|
+
let bestContains = false;
|
|
13690
13805
|
for (const f of faces) {
|
|
13691
|
-
const signed =
|
|
13806
|
+
const signed = this.signedDistance(f, point);
|
|
13692
13807
|
const abs = Math.abs(signed);
|
|
13693
|
-
if (abs
|
|
13808
|
+
if (abs > this.maxDistance)
|
|
13809
|
+
continue;
|
|
13810
|
+
const contains = this.containsPoint(f, this.projectOntoPlane(point, f, signed));
|
|
13811
|
+
if (bestContains && !contains)
|
|
13812
|
+
continue;
|
|
13813
|
+
if (contains && !bestContains) {
|
|
13814
|
+
bestContains = true;
|
|
13815
|
+
bestAbs = abs;
|
|
13816
|
+
best = f;
|
|
13817
|
+
continue;
|
|
13818
|
+
}
|
|
13819
|
+
if (abs < bestAbs) {
|
|
13694
13820
|
bestAbs = abs;
|
|
13695
13821
|
best = f;
|
|
13696
13822
|
}
|
|
13697
13823
|
}
|
|
13698
13824
|
if (!best)
|
|
13699
13825
|
return null;
|
|
13700
|
-
const projected =
|
|
13701
|
-
|
|
13702
|
-
|
|
13826
|
+
const projected = this.projectOntoPlane(
|
|
13827
|
+
point,
|
|
13828
|
+
best,
|
|
13829
|
+
this.signedDistance(best, point)
|
|
13830
|
+
);
|
|
13703
13831
|
return {
|
|
13704
13832
|
result: {
|
|
13705
13833
|
point: projected,
|
|
@@ -13710,6 +13838,50 @@ class SnapResolver {
|
|
|
13710
13838
|
}
|
|
13711
13839
|
};
|
|
13712
13840
|
}
|
|
13841
|
+
signedDistance(face, point) {
|
|
13842
|
+
return face.normal.x * point.x + face.normal.y * point.y + face.normal.z * point.z - face.d;
|
|
13843
|
+
}
|
|
13844
|
+
projectOntoPlane(point, face, signed) {
|
|
13845
|
+
return point.clone().sub(face.normal.clone().multiplyScalar(signed));
|
|
13846
|
+
}
|
|
13847
|
+
/**
|
|
13848
|
+
* Even-odd point-in-polygon test, run on the polygon projected onto its
|
|
13849
|
+
* dominant plane. `point` is assumed to already lie on the face's plane.
|
|
13850
|
+
*/
|
|
13851
|
+
containsPoint(face, point) {
|
|
13852
|
+
const { points, normal } = face;
|
|
13853
|
+
const count = points.length / 3;
|
|
13854
|
+
if (count < 3)
|
|
13855
|
+
return false;
|
|
13856
|
+
const ax = Math.abs(normal.x);
|
|
13857
|
+
const ay = Math.abs(normal.y);
|
|
13858
|
+
const az = Math.abs(normal.z);
|
|
13859
|
+
let a = 0;
|
|
13860
|
+
let b = 1;
|
|
13861
|
+
if (ax >= ay && ax >= az) {
|
|
13862
|
+
a = 1;
|
|
13863
|
+
b = 2;
|
|
13864
|
+
} else if (ay >= az) {
|
|
13865
|
+
a = 0;
|
|
13866
|
+
b = 2;
|
|
13867
|
+
}
|
|
13868
|
+
const px = point.getComponent(a);
|
|
13869
|
+
const py = point.getComponent(b);
|
|
13870
|
+
let inside = false;
|
|
13871
|
+
for (let i = 0, j = count - 1; i < count; j = i, i += 1) {
|
|
13872
|
+
const xi = points[i * 3 + a];
|
|
13873
|
+
const yi = points[i * 3 + b];
|
|
13874
|
+
const xj = points[j * 3 + a];
|
|
13875
|
+
const yj = points[j * 3 + b];
|
|
13876
|
+
const straddles = yi > py !== yj > py;
|
|
13877
|
+
if (!straddles)
|
|
13878
|
+
continue;
|
|
13879
|
+
const x = (xj - xi) * (py - yi) / (yj - yi) + xi;
|
|
13880
|
+
if (px < x)
|
|
13881
|
+
inside = !inside;
|
|
13882
|
+
}
|
|
13883
|
+
return inside;
|
|
13884
|
+
}
|
|
13713
13885
|
}
|
|
13714
13886
|
const _tmpMatrix = new THREE__namespace.Matrix4();
|
|
13715
13887
|
const _tmpX = new THREE__namespace.Vector3();
|
|
@@ -13777,7 +13949,7 @@ function fanTriangulation(vertexCount) {
|
|
|
13777
13949
|
}
|
|
13778
13950
|
return out;
|
|
13779
13951
|
}
|
|
13780
|
-
function deriveUniqueEdges(faces) {
|
|
13952
|
+
function deriveUniqueEdges(faces, precision) {
|
|
13781
13953
|
const seen = /* @__PURE__ */ new Set();
|
|
13782
13954
|
const collected = [];
|
|
13783
13955
|
for (const f of faces) {
|
|
@@ -13794,9 +13966,10 @@ function deriveUniqueEdges(faces) {
|
|
|
13794
13966
|
collected.push(ax, ay, az, bx, by, bz);
|
|
13795
13967
|
}
|
|
13796
13968
|
}
|
|
13797
|
-
|
|
13969
|
+
const Ctor = precision === "full" ? Float64Array : Float32Array;
|
|
13970
|
+
return new Ctor(collected);
|
|
13798
13971
|
}
|
|
13799
|
-
function deriveUniqueVertices(faces) {
|
|
13972
|
+
function deriveUniqueVertices(faces, precision) {
|
|
13800
13973
|
const seen = /* @__PURE__ */ new Set();
|
|
13801
13974
|
const collected = [];
|
|
13802
13975
|
for (const f of faces) {
|
|
@@ -13811,7 +13984,8 @@ function deriveUniqueVertices(faces) {
|
|
|
13811
13984
|
collected.push(x, y, z);
|
|
13812
13985
|
}
|
|
13813
13986
|
}
|
|
13814
|
-
|
|
13987
|
+
const Ctor = precision === "full" ? Float64Array : Float32Array;
|
|
13988
|
+
return new Ctor(collected);
|
|
13815
13989
|
}
|
|
13816
13990
|
function quantKey(x, y, z) {
|
|
13817
13991
|
return `${Math.round(x * VERTEX_QUANT)},${Math.round(y * VERTEX_QUANT)},${Math.round(z * VERTEX_QUANT)}`;
|
|
@@ -14107,6 +14281,9 @@ class SimpleWorld extends Base {
|
|
|
14107
14281
|
*/
|
|
14108
14282
|
__publicField(this, "enabled", true);
|
|
14109
14283
|
__publicField(this, "_dynamicAnchor", false);
|
|
14284
|
+
// Bumped on every anchor press so a slow geometry pick that resolves after a
|
|
14285
|
+
// newer press is ignored (see onPointerDown).
|
|
14286
|
+
__publicField(this, "_anchorRequestId", 0);
|
|
14110
14287
|
/**
|
|
14111
14288
|
* A unique identifier for the world. Is not meant to be changed at any moment.
|
|
14112
14289
|
*/
|
|
@@ -14118,21 +14295,36 @@ class SimpleWorld extends Base {
|
|
|
14118
14295
|
__publicField(this, "_scene");
|
|
14119
14296
|
__publicField(this, "_camera");
|
|
14120
14297
|
__publicField(this, "_renderer", null);
|
|
14121
|
-
__publicField(this, "onPointerDown",
|
|
14298
|
+
__publicField(this, "onPointerDown", (event) => {
|
|
14122
14299
|
if (!this.camera.hasCameraControls()) {
|
|
14123
14300
|
throw new Error(
|
|
14124
14301
|
"World: can't set dynamic anchor if the camera doesn't have controls."
|
|
14125
14302
|
);
|
|
14126
14303
|
}
|
|
14304
|
+
if (event.button !== 0)
|
|
14305
|
+
return;
|
|
14306
|
+
const position = this.getPointerPosition(event);
|
|
14307
|
+
if (!position)
|
|
14308
|
+
return;
|
|
14127
14309
|
const caster = this.components.get(Raycasters).get(this);
|
|
14128
|
-
const
|
|
14129
|
-
if (
|
|
14310
|
+
const planePoint = this.getPlaneAnchor(caster, position);
|
|
14311
|
+
if (planePoint) {
|
|
14130
14312
|
this.camera.controls.setOrbitPoint(
|
|
14131
|
-
|
|
14132
|
-
|
|
14133
|
-
|
|
14313
|
+
planePoint.x,
|
|
14314
|
+
planePoint.y,
|
|
14315
|
+
planePoint.z
|
|
14134
14316
|
);
|
|
14135
14317
|
}
|
|
14318
|
+
const requestId = ++this._anchorRequestId;
|
|
14319
|
+
caster.castRay({ position }).then((result) => {
|
|
14320
|
+
const isStale = requestId !== this._anchorRequestId;
|
|
14321
|
+
if (isStale || this.isDisposing || !this._dynamicAnchor)
|
|
14322
|
+
return;
|
|
14323
|
+
if (!(result == null ? void 0 : result.point) || !this.camera.hasCameraControls())
|
|
14324
|
+
return;
|
|
14325
|
+
const { x, y, z } = result.point;
|
|
14326
|
+
this.camera.controls.setOrbitPoint(x, y, z);
|
|
14327
|
+
});
|
|
14136
14328
|
});
|
|
14137
14329
|
__publicField(this, "_defaultCamera");
|
|
14138
14330
|
}
|
|
@@ -14151,10 +14343,46 @@ class SimpleWorld extends Base {
|
|
|
14151
14343
|
} else {
|
|
14152
14344
|
container.removeEventListener("pointerdown", this.onPointerDown);
|
|
14153
14345
|
}
|
|
14346
|
+
this._dynamicAnchor = value;
|
|
14154
14347
|
}
|
|
14155
14348
|
get dynamicAnchor() {
|
|
14156
14349
|
return this._dynamicAnchor;
|
|
14157
14350
|
}
|
|
14351
|
+
/**
|
|
14352
|
+
* The pointer position in normalized device coordinates, derived from the
|
|
14353
|
+
* event rather than the raycaster's mouse: that one only tracks pointermove
|
|
14354
|
+
* and touchstart, so on a bare pointerdown it would still report the center of
|
|
14355
|
+
* the viewport.
|
|
14356
|
+
*/
|
|
14357
|
+
getPointerPosition(event) {
|
|
14358
|
+
var _a;
|
|
14359
|
+
const dom = (_a = this.renderer) == null ? void 0 : _a.three.domElement;
|
|
14360
|
+
if (!dom)
|
|
14361
|
+
return null;
|
|
14362
|
+
const bounds = dom.getBoundingClientRect();
|
|
14363
|
+
return new THREE__namespace.Vector2(
|
|
14364
|
+
(event.clientX - bounds.left) / (bounds.right - bounds.left) * 2 - 1,
|
|
14365
|
+
-((event.clientY - bounds.top) / (bounds.bottom - bounds.top)) * 2 + 1
|
|
14366
|
+
);
|
|
14367
|
+
}
|
|
14368
|
+
/**
|
|
14369
|
+
* The point where the pointer ray crosses the plane that contains the current
|
|
14370
|
+
* orbit target and faces the camera. Used as the anchor when the pointer
|
|
14371
|
+
* doesn't land on any geometry.
|
|
14372
|
+
*/
|
|
14373
|
+
getPlaneAnchor(caster, position) {
|
|
14374
|
+
if (!this.camera.hasCameraControls())
|
|
14375
|
+
return null;
|
|
14376
|
+
const camera = this.camera.three;
|
|
14377
|
+
caster.three.setFromCamera(position, camera);
|
|
14378
|
+
const target = this.camera.controls.getTarget(new THREE__namespace.Vector3());
|
|
14379
|
+
const normal = camera.getWorldDirection(new THREE__namespace.Vector3());
|
|
14380
|
+
const plane = new THREE__namespace.Plane().setFromNormalAndCoplanarPoint(
|
|
14381
|
+
normal,
|
|
14382
|
+
target
|
|
14383
|
+
);
|
|
14384
|
+
return caster.three.ray.intersectPlane(plane, new THREE__namespace.Vector3());
|
|
14385
|
+
}
|
|
14158
14386
|
get defaultCamera() {
|
|
14159
14387
|
if (!this._defaultCamera) {
|
|
14160
14388
|
throw new Error("World: there is no default camera defined.");
|
|
@@ -14257,8 +14485,16 @@ class SimpleWorld extends Base {
|
|
|
14257
14485
|
}
|
|
14258
14486
|
/** {@link Disposable.dispose} */
|
|
14259
14487
|
dispose(disposeResources = true) {
|
|
14488
|
+
var _a;
|
|
14489
|
+
if (this.isDisposing)
|
|
14490
|
+
return;
|
|
14260
14491
|
this.enabled = false;
|
|
14261
14492
|
this.isDisposing = true;
|
|
14493
|
+
const container = (_a = this.renderer) == null ? void 0 : _a.three.domElement.parentElement;
|
|
14494
|
+
if (container) {
|
|
14495
|
+
container.removeEventListener("pointerdown", this.onPointerDown);
|
|
14496
|
+
}
|
|
14497
|
+
this._dynamicAnchor = false;
|
|
14262
14498
|
this.scene.onWorldChanged.trigger({ world: this, action: "removed" });
|
|
14263
14499
|
this.camera.onWorldChanged.trigger({ world: this, action: "removed" });
|
|
14264
14500
|
if (this.renderer) {
|
|
@@ -15505,16 +15741,23 @@ const _Components = class _Components {
|
|
|
15505
15741
|
dispose() {
|
|
15506
15742
|
this.enabled = false;
|
|
15507
15743
|
let fragments;
|
|
15744
|
+
let worlds;
|
|
15508
15745
|
for (const [_id, component] of this.list) {
|
|
15509
15746
|
component.enabled = false;
|
|
15510
15747
|
if (_id === FragmentsManager.uuid) {
|
|
15511
15748
|
fragments = component;
|
|
15512
15749
|
continue;
|
|
15513
15750
|
}
|
|
15751
|
+
if (_id === Worlds.uuid) {
|
|
15752
|
+
worlds = component;
|
|
15753
|
+
continue;
|
|
15754
|
+
}
|
|
15514
15755
|
if (component.isDisposeable()) {
|
|
15515
15756
|
component.dispose();
|
|
15516
15757
|
}
|
|
15517
15758
|
}
|
|
15759
|
+
if (worlds == null ? void 0 : worlds.isDisposeable())
|
|
15760
|
+
worlds.dispose();
|
|
15518
15761
|
fragments == null ? void 0 : fragments.dispose();
|
|
15519
15762
|
this._timer.dispose();
|
|
15520
15763
|
this.onDisposed.trigger();
|
|
@@ -15991,7 +16234,7 @@ Dual licenced under the MIT license or GPLv3. See https://raw.github.com/Stuk/js
|
|
|
15991
16234
|
JSZip uses the library pako released under the MIT license :
|
|
15992
16235
|
https://github.com/nodeca/pako/blob/main/LICENSE
|
|
15993
16236
|
*/
|
|
15994
|
-
(function(module2,
|
|
16237
|
+
(function(module2, exports$1) {
|
|
15995
16238
|
!function(e) {
|
|
15996
16239
|
module2.exports = e();
|
|
15997
16240
|
}(function() {
|
|
@@ -19049,33 +19292,31 @@ const _Topic = class _Topic {
|
|
|
19049
19292
|
serialize() {
|
|
19050
19293
|
var _a, _b;
|
|
19051
19294
|
const version = this._managerVersion;
|
|
19295
|
+
const isV3 = version === "3";
|
|
19052
19296
|
const topic = {
|
|
19053
19297
|
$Guid: this.guid,
|
|
19054
19298
|
$TopicType: this.type,
|
|
19055
19299
|
$TopicStatus: this.status,
|
|
19056
19300
|
$ServerAssignedId: this.serverAssignedId,
|
|
19057
19301
|
Title: this.title,
|
|
19058
|
-
CreationAuthor: this.creationAuthor,
|
|
19059
|
-
CreationDate: this.creationDate.toISOString(),
|
|
19060
19302
|
Priority: this.priority,
|
|
19061
19303
|
Index: version === "2.1" ? this.index : void 0,
|
|
19304
|
+
Labels: isV3 ? { Label: this.createLabelTags() } : this.createLabelTags(),
|
|
19305
|
+
CreationDate: this.creationDate.toISOString(),
|
|
19306
|
+
CreationAuthor: this.creationAuthor,
|
|
19062
19307
|
ModifiedDate: (_a = this.modifiedDate) == null ? void 0 : _a.toISOString(),
|
|
19063
19308
|
ModifiedAuthor: this.modifiedAuthor,
|
|
19064
19309
|
DueDate: (_b = this.dueDate) == null ? void 0 : _b.toISOString(),
|
|
19065
19310
|
AssignedTo: this.assignedTo,
|
|
19066
|
-
Description: this.description,
|
|
19067
19311
|
Stage: this.stage,
|
|
19068
|
-
|
|
19069
|
-
|
|
19070
|
-
|
|
19071
|
-
|
|
19072
|
-
|
|
19073
|
-
Comments:
|
|
19312
|
+
Description: this.description,
|
|
19313
|
+
DocumentReferences: isV3 ? { DocumentReference: this.createDocumentReferencesTag(version) } : void 0,
|
|
19314
|
+
DocumentReference: isV3 ? void 0 : this.createDocumentReferencesTag(version),
|
|
19315
|
+
RelatedTopics: isV3 ? { RelatedTopic: this.createRelatedTopicTags() } : void 0,
|
|
19316
|
+
RelatedTopic: isV3 ? void 0 : this.createRelatedTopicTags(),
|
|
19317
|
+
Comments: isV3 ? { Comment: this.createCommentTags() } : void 0,
|
|
19318
|
+
Viewpoints: isV3 ? { ViewPoint: this.createViewpointTags() } : void 0
|
|
19074
19319
|
};
|
|
19075
|
-
if (version === "2.1") {
|
|
19076
|
-
topic.Labels = this.createLabelTags();
|
|
19077
|
-
topic.DocumentReference = this.createDocumentReferencesTag(version);
|
|
19078
|
-
}
|
|
19079
19320
|
const markup = {
|
|
19080
19321
|
Markup: { Topic: topic }
|
|
19081
19322
|
};
|
|
@@ -19502,10 +19743,13 @@ const _BCFTopics = class _BCFTopics extends Component {
|
|
|
19502
19743
|
*/
|
|
19503
19744
|
async export(topics = this.list.values()) {
|
|
19504
19745
|
const zip = new JSZip();
|
|
19746
|
+
const isV3 = this.config.version === "3";
|
|
19747
|
+
const versionId = isV3 ? "3.0" : this.config.version;
|
|
19748
|
+
const schemaRelease = isV3 ? "release_3_0" : "release_2_1";
|
|
19505
19749
|
zip.file(
|
|
19506
19750
|
"bcf.version",
|
|
19507
19751
|
`<?xml version="1.0" encoding="UTF-8"?>
|
|
19508
|
-
<Version VersionId="${
|
|
19752
|
+
<Version VersionId="${versionId}" xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/buildingSMART/BCF-XML/${schemaRelease}/Schemas/version.xsd"
|
|
19509
19753
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
|
19510
19754
|
</Version>`
|
|
19511
19755
|
);
|
|
@@ -19540,7 +19784,7 @@ const _BCFTopics = class _BCFTopics extends Component {
|
|
|
19540
19784
|
);
|
|
19541
19785
|
}
|
|
19542
19786
|
}
|
|
19543
|
-
zip.file("
|
|
19787
|
+
zip.file("extensions.xml", this.serializeExtensions());
|
|
19544
19788
|
const viewpoints = this.components.get(Viewpoints);
|
|
19545
19789
|
for (const topic of topics) {
|
|
19546
19790
|
const topicFolder = zip.folder(topic.guid);
|
|
@@ -19612,7 +19856,7 @@ ${users}
|
|
|
19612
19856
|
Comment: CommentText,
|
|
19613
19857
|
Viewpoint: Viewpoint2
|
|
19614
19858
|
} = markupComment;
|
|
19615
|
-
if (!(Guid && CommentDate && Author && Comment))
|
|
19859
|
+
if (!(Guid && CommentDate && Author && (Comment || Viewpoint2)))
|
|
19616
19860
|
return null;
|
|
19617
19861
|
const comment = new Comment(this.components, CommentText ?? "");
|
|
19618
19862
|
comment.guid = Guid;
|
|
@@ -19709,14 +19953,16 @@ ${users}
|
|
|
19709
19953
|
const versionFile = files.find((file) => file.name.endsWith(".version"));
|
|
19710
19954
|
if (versionFile) {
|
|
19711
19955
|
const versionXML = await versionFile.async("string");
|
|
19712
|
-
const bcfVersion =
|
|
19713
|
-
|
|
19956
|
+
const bcfVersion = String(
|
|
19957
|
+
_BCFTopics.xmlParser.parse(versionXML).Version.VersionId
|
|
19958
|
+
);
|
|
19959
|
+
version = bcfVersion === "3.0" ? "3" : bcfVersion;
|
|
19714
19960
|
}
|
|
19715
19961
|
if (!(version && (version === "2.1" || version === "3"))) {
|
|
19716
19962
|
throw new Error(`BCFTopics: ${version} is not supported.`);
|
|
19717
19963
|
}
|
|
19718
19964
|
const extensionsFile = files.find(
|
|
19719
|
-
(file) => file.name.endsWith(".extensions")
|
|
19965
|
+
(file) => file.name.endsWith("extensions.xml") || file.name.endsWith(".extensions")
|
|
19720
19966
|
);
|
|
19721
19967
|
if (updateExtensionsOnImport && extensionsFile) {
|
|
19722
19968
|
const extensionsXML = await extensionsFile.async("string");
|
|
@@ -20259,7 +20505,7 @@ class SimplePlane {
|
|
|
20259
20505
|
dispose() {
|
|
20260
20506
|
var _a;
|
|
20261
20507
|
this._enabled = false;
|
|
20262
|
-
if ((_a = this.world.camera) == null ? void 0 : _a.controls) {
|
|
20508
|
+
if (!this.world.isDisposing && ((_a = this.world.camera) == null ? void 0 : _a.controls)) {
|
|
20263
20509
|
this.world.camera.controls.removeEventListener(
|
|
20264
20510
|
"update",
|
|
20265
20511
|
this.updateScale
|
|
@@ -20500,8 +20746,13 @@ const _Clipper = class _Clipper extends Component {
|
|
|
20500
20746
|
* Default `false` to preserve existing behavior. Set this once
|
|
20501
20747
|
* before creating planes; toggling at runtime won't reclassify
|
|
20502
20748
|
* planes already on the renderer.
|
|
20749
|
+
*
|
|
20750
|
+
* Setting this also mirrors the value onto every world's
|
|
20751
|
+
* `renderer.localClippingPlanes`, so planes added by other
|
|
20752
|
+
* components (e.g. the {@link Views} cut planes) default to the
|
|
20753
|
+
* same mode without each call site having to pass `isLocal`.
|
|
20503
20754
|
*/
|
|
20504
|
-
__publicField(this, "
|
|
20755
|
+
__publicField(this, "_localClippingPlanes", false);
|
|
20505
20756
|
/**
|
|
20506
20757
|
* The type of clipping plane to be created.
|
|
20507
20758
|
* Default is {@link SimplePlane}.
|
|
@@ -20537,6 +20788,17 @@ const _Clipper = class _Clipper extends Component {
|
|
|
20537
20788
|
this.components.add(_Clipper.uuid, this);
|
|
20538
20789
|
this.setEvents();
|
|
20539
20790
|
}
|
|
20791
|
+
get localClippingPlanes() {
|
|
20792
|
+
return this._localClippingPlanes;
|
|
20793
|
+
}
|
|
20794
|
+
set localClippingPlanes(value) {
|
|
20795
|
+
this._localClippingPlanes = value;
|
|
20796
|
+
const worlds = this.components.get(Worlds);
|
|
20797
|
+
for (const [, world] of worlds.list) {
|
|
20798
|
+
if (world.renderer)
|
|
20799
|
+
world.renderer.localClippingPlanes = value;
|
|
20800
|
+
}
|
|
20801
|
+
}
|
|
20540
20802
|
/** {@link Component.enabled} */
|
|
20541
20803
|
get enabled() {
|
|
20542
20804
|
return this._enabled;
|
|
@@ -23464,19 +23726,24 @@ class IDSProperty extends IDSFacet {
|
|
|
23464
23726
|
);
|
|
23465
23727
|
}
|
|
23466
23728
|
getTypePsets(item) {
|
|
23467
|
-
|
|
23468
|
-
|
|
23469
|
-
|
|
23470
|
-
|
|
23471
|
-
|
|
23729
|
+
const definitions = [
|
|
23730
|
+
...Array.isArray(item.IsTypedBy) ? item.IsTypedBy : [],
|
|
23731
|
+
...Array.isArray(item.IsDefinedBy) ? item.IsDefinedBy : []
|
|
23732
|
+
];
|
|
23733
|
+
const psets = [];
|
|
23734
|
+
for (const definition of definitions) {
|
|
23735
|
+
if (Array.isArray(definition == null ? void 0 : definition.HasPropertySets)) {
|
|
23736
|
+
psets.push(...definition.HasPropertySets);
|
|
23737
|
+
}
|
|
23472
23738
|
}
|
|
23473
|
-
return
|
|
23739
|
+
return psets;
|
|
23474
23740
|
}
|
|
23475
23741
|
async getPsets(item) {
|
|
23476
23742
|
const typeSets = this.getTypePsets(item);
|
|
23477
23743
|
if (!Array.isArray(item.IsDefinedBy))
|
|
23478
23744
|
return typeSets;
|
|
23479
23745
|
const sets = [];
|
|
23746
|
+
const mergedTypeSets = /* @__PURE__ */ new Set();
|
|
23480
23747
|
for (const definition of item.IsDefinedBy) {
|
|
23481
23748
|
if (!("value" in definition.Name))
|
|
23482
23749
|
continue;
|
|
@@ -23489,22 +23756,29 @@ class IDSProperty extends IDSFacet {
|
|
|
23489
23756
|
return false;
|
|
23490
23757
|
return set.Name.value === definitionName;
|
|
23491
23758
|
});
|
|
23492
|
-
if (typeSet
|
|
23493
|
-
|
|
23494
|
-
|
|
23495
|
-
|
|
23496
|
-
|
|
23497
|
-
|
|
23498
|
-
|
|
23499
|
-
|
|
23500
|
-
|
|
23501
|
-
|
|
23502
|
-
|
|
23503
|
-
|
|
23759
|
+
if (typeSet) {
|
|
23760
|
+
mergedTypeSets.add(typeSet);
|
|
23761
|
+
if (Array.isArray(typeSet.HasProperties) && Array.isArray(definition.HasProperties)) {
|
|
23762
|
+
for (const prop of typeSet.HasProperties) {
|
|
23763
|
+
if (!("value" in prop.Name))
|
|
23764
|
+
continue;
|
|
23765
|
+
const name = prop.Name.value;
|
|
23766
|
+
const existingProp = definition.HasProperties.find((p) => {
|
|
23767
|
+
if (!("value" in p.Name))
|
|
23768
|
+
return false;
|
|
23769
|
+
return p.Name.value === name;
|
|
23770
|
+
});
|
|
23771
|
+
if (!existingProp)
|
|
23772
|
+
definition.HasProperties.push(prop);
|
|
23773
|
+
}
|
|
23504
23774
|
}
|
|
23505
23775
|
}
|
|
23506
23776
|
sets.push(definition);
|
|
23507
23777
|
}
|
|
23778
|
+
for (const typeSet of typeSets) {
|
|
23779
|
+
if (!mergedTypeSets.has(typeSet))
|
|
23780
|
+
sets.push(typeSet);
|
|
23781
|
+
}
|
|
23508
23782
|
return sets;
|
|
23509
23783
|
}
|
|
23510
23784
|
// IFCPROPERTYBOUNDEDVALUE are not supported yet
|
|
@@ -23526,7 +23800,7 @@ class IDSProperty extends IDSFacet {
|
|
|
23526
23800
|
return false;
|
|
23527
23801
|
}
|
|
23528
23802
|
const facetValue = structuredClone(this.value);
|
|
23529
|
-
if (valueAttr.
|
|
23803
|
+
if (typeof valueAttr.value === "string" && facetValue.type === "simple") {
|
|
23530
23804
|
facetValue.parameter = String(facetValue.parameter);
|
|
23531
23805
|
}
|
|
23532
23806
|
const result = this.evalRequirement(
|
|
@@ -23582,12 +23856,38 @@ class IDSProperty extends IDSFacet {
|
|
|
23582
23856
|
class IDSMaterial extends IDSFacet {
|
|
23583
23857
|
constructor() {
|
|
23584
23858
|
super(...arguments);
|
|
23859
|
+
// Every type IfcRelAssociatesMaterial.RelatingMaterial (IfcMaterialSelect)
|
|
23860
|
+
// can point at. Missing any of them silently drops every element that
|
|
23861
|
+
// associates its material through it: an element can reference a layer set
|
|
23862
|
+
// directly instead of through a layer set usage, and both spellings are
|
|
23863
|
+
// valid IFC.
|
|
23585
23864
|
__publicField(this, "_ifcMaterialEntities", [
|
|
23586
23865
|
/^IFCMATERIALLAYERSETUSAGE$/,
|
|
23866
|
+
/^IFCMATERIALLAYERSET$/,
|
|
23867
|
+
/^IFCMATERIALPROFILESETUSAGE$/,
|
|
23868
|
+
/^IFCMATERIALPROFILESET$/,
|
|
23587
23869
|
/^IFCMATERIALCONSTITUENTSET$/,
|
|
23588
23870
|
/^IFCMATERIAL$/,
|
|
23589
23871
|
/^IFCMATERIALLIST$/
|
|
23590
23872
|
]);
|
|
23873
|
+
// Attributes that lead from a material set / usage down to its IfcMaterial.
|
|
23874
|
+
__publicField(this, "_materialParentAttributes", [
|
|
23875
|
+
"ForLayerSet",
|
|
23876
|
+
"MaterialLayers",
|
|
23877
|
+
"ForProfileSet",
|
|
23878
|
+
"MaterialProfiles",
|
|
23879
|
+
"Material",
|
|
23880
|
+
"MaterialConstituents",
|
|
23881
|
+
"Materials"
|
|
23882
|
+
]);
|
|
23883
|
+
__publicField(this, "_materialRelations", {
|
|
23884
|
+
MaterialConstituents: { attributes: true, relations: true },
|
|
23885
|
+
ForLayerSet: { attributes: true, relations: true },
|
|
23886
|
+
MaterialLayers: { attributes: true, relations: true },
|
|
23887
|
+
ForProfileSet: { attributes: true, relations: true },
|
|
23888
|
+
MaterialProfiles: { attributes: true, relations: true },
|
|
23889
|
+
Materials: { attributes: true, relations: false }
|
|
23890
|
+
});
|
|
23591
23891
|
__publicField(this, "facetType", "Material");
|
|
23592
23892
|
__publicField(this, "value");
|
|
23593
23893
|
__publicField(this, "uri");
|
|
@@ -23619,10 +23919,7 @@ class IDSMaterial extends IDSFacet {
|
|
|
23619
23919
|
const data = await model.getItemsData(localIds, {
|
|
23620
23920
|
relations: {
|
|
23621
23921
|
AssociatedTo: { attributes: true, relations: false },
|
|
23622
|
-
|
|
23623
|
-
ForLayerSet: { attributes: true, relations: true },
|
|
23624
|
-
MaterialLayers: { attributes: true, relations: true },
|
|
23625
|
-
Materials: { attributes: true, relations: false }
|
|
23922
|
+
...this._materialRelations
|
|
23626
23923
|
}
|
|
23627
23924
|
});
|
|
23628
23925
|
for (const item of data) {
|
|
@@ -23651,10 +23948,7 @@ class IDSMaterial extends IDSFacet {
|
|
|
23651
23948
|
relations: {
|
|
23652
23949
|
AssociatedTo: { attributes: false, relations: false },
|
|
23653
23950
|
HasAssociations: { attributes: true, relations: true },
|
|
23654
|
-
|
|
23655
|
-
ForLayerSet: { attributes: true, relations: true },
|
|
23656
|
-
MaterialLayers: { attributes: true, relations: true },
|
|
23657
|
-
Materials: { attributes: true, relations: false }
|
|
23951
|
+
...this._materialRelations
|
|
23658
23952
|
}
|
|
23659
23953
|
});
|
|
23660
23954
|
for (const item of data) {
|
|
@@ -23698,13 +23992,7 @@ class IDSMaterial extends IDSFacet {
|
|
|
23698
23992
|
isValid = true;
|
|
23699
23993
|
} else {
|
|
23700
23994
|
for (const [name, attribute] of Object.entries(item)) {
|
|
23701
|
-
if (!
|
|
23702
|
-
"ForLayerSet",
|
|
23703
|
-
"MaterialLayers",
|
|
23704
|
-
"Material",
|
|
23705
|
-
"MaterialConstituents",
|
|
23706
|
-
"Materials"
|
|
23707
|
-
].includes(name))
|
|
23995
|
+
if (!this._materialParentAttributes.includes(name))
|
|
23708
23996
|
continue;
|
|
23709
23997
|
if (!Array.isArray(attribute))
|
|
23710
23998
|
continue;
|
|
@@ -26711,7 +26999,7 @@ function buildPreviewPositions(kind, points, cursor, style) {
|
|
|
26711
26999
|
for (let i = 0; i < points.length - 1; i++) {
|
|
26712
27000
|
positions.push(
|
|
26713
27001
|
...buildDimensionPositions(
|
|
26714
|
-
{
|
|
27002
|
+
{ pointA: points[i], pointB: points[i + 1], offset },
|
|
26715
27003
|
style
|
|
26716
27004
|
)
|
|
26717
27005
|
);
|