@thatopen/components 2.2.3 → 2.2.4

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.
@@ -6,7 +6,7 @@ export declare class Components implements Disposable {
6
6
  /**
7
7
  * The version of the @thatopen/components library.
8
8
  */
9
- static readonly release = "2.2.3";
9
+ static readonly release = "2.2.4";
10
10
  /** {@link Disposable.onDisposed} */
11
11
  readonly onDisposed: Event<void>;
12
12
  /**
@@ -29,6 +29,7 @@ export declare class MeshCullerRenderer extends CullerRenderer implements Dispos
29
29
  * Used to prevent concurrent processing.
30
30
  */
31
31
  isProcessing: boolean;
32
+ private _interval;
32
33
  private _colorCodeMeshMap;
33
34
  private _meshIDColorCodeMap;
34
35
  private _currentVisibleMeshes;
@@ -33,22 +33,6 @@ export type InverseAttributes = [
33
33
  "Nests"
34
34
  ];
35
35
  export type InverseAttribute = InverseAttributes[number];
36
- export type IfcRelationNames = [
37
- "IfcRelAssignsToActor",
38
- "IfcRelAssignsToControl",
39
- "IfcRelAssignsToGroup",
40
- "IfcRelAssignsToProcess",
41
- "IfcRelAssignsToProduct",
42
- "IfcRelAssignsToResource",
43
- "IfcRelAssociatesApproval",
44
- "IfcRelAssociatesClassification",
45
- "IfcRelAssociatesConstraint",
46
- "IfcRelAssociatesDocument",
47
- "IfcRelAssociatesLibrary",
48
- "IfcRelAssociatesMaterial",
49
- "IfcRelAssociatesProfileDef"
50
- ];
51
- export type IfcRelName = IfcRelationNames[number];
52
36
  /**
53
37
  * Type alias for an array of IfcRelation types from WebIfc.
54
38
  */
package/dist/index.cjs CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  - If you're the tool creator, you can take one from https://www.uuidgenerator.net/.
4
4
 
5
- - If you're using a platform tool, verify the uuid isn't misspelled or contact the tool creator.`)}};T(St,"_pattern",/^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$/),T(St,"_lut",["00","01","02","03","04","05","06","07","08","09","0a","0b","0c","0d","0e","0f","10","11","12","13","14","15","16","17","18","19","1a","1b","1c","1d","1e","1f","20","21","22","23","24","25","26","27","28","29","2a","2b","2c","2d","2e","2f","30","31","32","33","34","35","36","37","38","39","3a","3b","3c","3d","3e","3f","40","41","42","43","44","45","46","47","48","49","4a","4b","4c","4d","4e","4f","50","51","52","53","54","55","56","57","58","59","5a","5b","5c","5d","5e","5f","60","61","62","63","64","65","66","67","68","69","6a","6b","6c","6d","6e","6f","70","71","72","73","74","75","76","77","78","79","7a","7b","7c","7d","7e","7f","80","81","82","83","84","85","86","87","88","89","8a","8b","8c","8d","8e","8f","90","91","92","93","94","95","96","97","98","99","9a","9b","9c","9d","9e","9f","a0","a1","a2","a3","a4","a5","a6","a7","a8","a9","aa","ab","ac","ad","ae","af","b0","b1","b2","b3","b4","b5","b6","b7","b8","b9","ba","bb","bc","bd","be","bf","c0","c1","c2","c3","c4","c5","c6","c7","c8","c9","ca","cb","cc","cd","ce","cf","d0","d1","d2","d3","d4","d5","d6","d7","d8","d9","da","db","dc","dd","de","df","e0","e1","e2","e3","e4","e5","e6","e7","e8","e9","ea","eb","ec","ed","ee","ef","f0","f1","f2","f3","f4","f5","f6","f7","f8","f9","fa","fb","fc","fd","fe","ff"]);let le=St;class Ra extends wt{constructor(t,e){super(t);T(this,"onDisposed",new j);T(this,"onVertexFound",new j);T(this,"onVertexLost",new j);T(this,"onEnabled",new j);T(this,"components");T(this,"workingPlane",null);T(this,"_pickedPoint",null);T(this,"_config");T(this,"_enabled",!1);this.components=t,this.config={snapDistance:.25,showOnlyVertex:!1,...e},this.enabled=!1}set enabled(t){this._enabled=t,t||(this._pickedPoint=null),this.onEnabled.trigger(t)}get enabled(){return this._enabled}set config(t){this._config={...this._config,...t}}get config(){return this._config}dispose(){this.onVertexFound.reset(),this.onVertexLost.reset(),this.components=null,this.onDisposed.trigger(),this.onDisposed.reset()}get(t){if(!this.enabled)return this._pickedPoint;const n=this.components.get(Oe).get(t).castRay();if(!n)return this._pickedPoint!==null&&(this.onVertexLost.trigger(),this._pickedPoint=null),this._pickedPoint;const r=this.getClosestVertex(n);return r?(this.workingPlane?Math.abs(this.workingPlane.distanceToPoint(r))<.001:!0)?((this._pickedPoint===null||!this._pickedPoint.equals(r))&&(this._pickedPoint=r.clone(),this.onVertexFound.trigger(this._pickedPoint)),this._pickedPoint):(this._pickedPoint=null,this._pickedPoint):(this._pickedPoint!==null&&(this.onVertexLost.trigger(),this._pickedPoint=null),this._pickedPoint)}getClosestVertex(t){let e=new x.Vector3,i=!1,n=Number.MAX_SAFE_INTEGER;const r=this.getVertices(t);if(r===null)return null;for(const o of r){if(!o)continue;const a=t.point.distanceTo(o);a>n||a>this._config.snapDistance||(i=!0,e=o,n=t.point.distanceTo(o))}return i?e:this.config.showOnlyVertex?null:t.point}getVertices(t){const e=t.object;if(!t.face||!e)return null;const i=e.geometry,n=new x.Matrix4,{instanceId:r}=t,o=r!==void 0,a=e instanceof x.InstancedMesh;return a&&o&&e.getMatrixAt(r,n),[this.getVertex(t.face.a,i),this.getVertex(t.face.b,i),this.getVertex(t.face.c,i)].map(l=>(l&&(a&&o&&l.applyMatrix4(n),l.applyMatrix4(e.matrixWorld)),l))}getVertex(t,e){if(t===void 0)return null;const i=e.attributes.position;return new x.Vector3(i.getX(t),i.getY(t),i.getZ(t))}}const ci=class ci{constructor(){T(this,"onDisposed",new j);T(this,"list",new Map);T(this,"enabled",!1);T(this,"_clock");T(this,"update",()=>{if(!this.enabled)return;const s=this._clock.getDelta();for(const[t,e]of this.list)e.enabled&&e.isUpdateable()&&e.update(s);requestAnimationFrame(this.update)});this._clock=new x.Clock,ci.setupBVH()}add(s,t){if(this.list.has(s))throw new Error("You're trying to add a component that already exists in the components instance. Use Components.get() instead.");le.validate(s),this.list.set(s,t)}get(s){const t=s.uuid;if(!this.list.has(t)){const e=new s(this);return this.list.has(t)||this.add(t,e),e}return this.list.get(t)}init(){this.enabled=!0,this._clock.start(),this.update()}dispose(){this.enabled=!1;for(const[s,t]of this.list)t.enabled=!1,t.isDisposeable()&&t.dispose();this._clock.stop(),this.onDisposed.trigger(),this.onDisposed.reset()}static setupBVH(){x.BufferGeometry.prototype.computeBoundsTree=fa,x.BufferGeometry.prototype.disposeBoundsTree=pa,x.Mesh.prototype.raycast=ua}};T(ci,"release","2.2.3");let Js=ci;class Fr extends Ri{constructor(){super(...arguments);T(this,"meshes",new Set);T(this,"onAfterUpdate",new j);T(this,"onBeforeUpdate",new j);T(this,"onDisposed",new j);T(this,"isDisposing",!1);T(this,"enabled",!0);T(this,"uuid",le.create());T(this,"name");T(this,"_scene");T(this,"_camera");T(this,"_renderer",null)}get scene(){if(!this._scene)throw new Error("No scene initialized!");return this._scene}set scene(t){this._scene=t,t.worlds.set(this.uuid,this),t.currentWorld=this,t.onWorldChanged.trigger({world:this,action:"added"})}get camera(){if(!this._camera)throw new Error("No camera initialized!");return this._camera}set camera(t){this._camera=t,t.worlds.set(this.uuid,this),t.currentWorld=this,t.onWorldChanged.trigger({world:this,action:"added"})}get renderer(){return this._renderer}set renderer(t){this._renderer=t,t&&(t.worlds.set(this.uuid,this),t.currentWorld=this,t.onWorldChanged.trigger({world:this,action:"added"}))}update(t){this.enabled&&(!this._scene||!this._camera||(this.scene.currentWorld=this,this.camera.currentWorld=this,this.renderer&&(this.renderer.currentWorld=this),this.onBeforeUpdate.trigger(),this.scene.isUpdateable()&&this.scene.update(t),this.camera.isUpdateable()&&this.camera.update(t),this.renderer&&this.renderer.update(t),this.onAfterUpdate.trigger()))}dispose(t=!0){if(this.enabled=!1,this.isDisposing=!0,this.scene.onWorldChanged.trigger({world:this,action:"removed"}),this.camera.onWorldChanged.trigger({world:this,action:"removed"}),this.renderer&&this.renderer.onWorldChanged.trigger({world:this,action:"removed"}),t){const e=this.components.get(ce);this.scene.dispose(),this.camera.isDisposeable()&&this.camera.dispose(),this.renderer&&this.renderer.dispose();for(const i of this.meshes)e.destroy(i);this.meshes.clear()}this._scene=null,this._camera=null,this._renderer=null,this.onDisposed.trigger()}}class Or extends Rr{constructor(t){super(t);T(this,"isSetup",!1);T(this,"three");T(this,"onSetup",new j);T(this,"config",{directionalLight:{color:new x.Color("white"),intensity:1.5,position:new x.Vector3(5,10,3)},ambientLight:{color:new x.Color("white"),intensity:1}});this.three=new x.Scene,this.three.background=new x.Color(2107698)}setup(t){this.config={...this.config,...t};const e=new x.DirectionalLight(this.config.directionalLight.color,this.config.directionalLight.intensity);e.position.copy(this.config.directionalLight.position);const i=new x.AmbientLight(this.config.ambientLight.color,this.config.ambientLight.intensity);this.three.add(e,i),this.directionalLights.set(e.uuid,e),this.ambientLights.set(i.uuid,i),this.isSetup=!0,this.onSetup.trigger(this)}}class ya extends Ar{constructor(t,e,i){super(t);T(this,"enabled",!0);T(this,"container");T(this,"three");T(this,"_canvas");T(this,"_parameters");T(this,"_resizeObserver",null);T(this,"onContainerUpdated",new j);T(this,"_resizing",!1);T(this,"resize",t=>{if(this._resizing)return;this._resizing=!0,this.onContainerUpdated.trigger();const e=t?t.x:this.container.clientWidth,i=t?t.y:this.container.clientHeight;this.three.setSize(e,i),this.onResize.trigger(new x.Vector2(e,i)),this._resizing=!1});T(this,"resizeEvent",()=>{this.resize()});T(this,"onContextLost",t=>{t.preventDefault(),this.enabled=!1});T(this,"onContextBack",()=>{this.three.setRenderTarget(null),this.three.dispose(),this.three=new x.WebGLRenderer({canvas:this._canvas,antialias:!0,alpha:!0,...this._parameters}),this.enabled=!0});this.container=e,this._parameters=i,this.three=new x.WebGLRenderer({antialias:!0,alpha:!0,...i}),this.three.setPixelRatio(Math.min(window.devicePixelRatio,2)),this.setupRenderer(),this.setupEvents(!0),this.resize(),this._canvas=this.three.domElement;const n=this.three.getContext(),{canvas:r}=n;r.addEventListener("webglcontextlost",this.onContextLost,!1),r.addEventListener("webglcontextrestored",this.onContextBack,!1)}update(){if(!this.enabled||!this.currentWorld)return;this.onBeforeUpdate.trigger(this);const t=this.currentWorld.scene.three,e=this.currentWorld.camera.three;this.three.render(t,e),this.onAfterUpdate.trigger(this)}dispose(){this.enabled=!1,this.setupEvents(!1),this.three.domElement.remove(),this.three.forceContextLoss(),this.three.dispose(),this.onResize.reset(),this.onAfterUpdate.reset(),this.onBeforeUpdate.reset(),this.onDisposed.trigger(),this.onDisposed.reset()}getSize(){return new x.Vector2(this.three.domElement.clientWidth,this.three.domElement.clientHeight)}setupEvents(t){const e=this.three.domElement.parentElement;if(!e)throw new Error("This renderer needs to have an HTML container!");this._resizeObserver&&(this._resizeObserver.disconnect(),this._resizeObserver=null),window.removeEventListener("resize",this.resizeEvent),t&&(this._resizeObserver=new ResizeObserver(this.resizeEvent),this._resizeObserver.observe(e),window.addEventListener("resize",this.resizeEvent))}setupRenderer(){this.three.localClippingEnabled=!0,this.container&&this.container.appendChild(this.three.domElement),this.onContainerUpdated.trigger()}}/*!
5
+ - If you're using a platform tool, verify the uuid isn't misspelled or contact the tool creator.`)}};T(St,"_pattern",/^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$/),T(St,"_lut",["00","01","02","03","04","05","06","07","08","09","0a","0b","0c","0d","0e","0f","10","11","12","13","14","15","16","17","18","19","1a","1b","1c","1d","1e","1f","20","21","22","23","24","25","26","27","28","29","2a","2b","2c","2d","2e","2f","30","31","32","33","34","35","36","37","38","39","3a","3b","3c","3d","3e","3f","40","41","42","43","44","45","46","47","48","49","4a","4b","4c","4d","4e","4f","50","51","52","53","54","55","56","57","58","59","5a","5b","5c","5d","5e","5f","60","61","62","63","64","65","66","67","68","69","6a","6b","6c","6d","6e","6f","70","71","72","73","74","75","76","77","78","79","7a","7b","7c","7d","7e","7f","80","81","82","83","84","85","86","87","88","89","8a","8b","8c","8d","8e","8f","90","91","92","93","94","95","96","97","98","99","9a","9b","9c","9d","9e","9f","a0","a1","a2","a3","a4","a5","a6","a7","a8","a9","aa","ab","ac","ad","ae","af","b0","b1","b2","b3","b4","b5","b6","b7","b8","b9","ba","bb","bc","bd","be","bf","c0","c1","c2","c3","c4","c5","c6","c7","c8","c9","ca","cb","cc","cd","ce","cf","d0","d1","d2","d3","d4","d5","d6","d7","d8","d9","da","db","dc","dd","de","df","e0","e1","e2","e3","e4","e5","e6","e7","e8","e9","ea","eb","ec","ed","ee","ef","f0","f1","f2","f3","f4","f5","f6","f7","f8","f9","fa","fb","fc","fd","fe","ff"]);let le=St;class Ra extends wt{constructor(t,e){super(t);T(this,"onDisposed",new j);T(this,"onVertexFound",new j);T(this,"onVertexLost",new j);T(this,"onEnabled",new j);T(this,"components");T(this,"workingPlane",null);T(this,"_pickedPoint",null);T(this,"_config");T(this,"_enabled",!1);this.components=t,this.config={snapDistance:.25,showOnlyVertex:!1,...e},this.enabled=!1}set enabled(t){this._enabled=t,t||(this._pickedPoint=null),this.onEnabled.trigger(t)}get enabled(){return this._enabled}set config(t){this._config={...this._config,...t}}get config(){return this._config}dispose(){this.onVertexFound.reset(),this.onVertexLost.reset(),this.components=null,this.onDisposed.trigger(),this.onDisposed.reset()}get(t){if(!this.enabled)return this._pickedPoint;const n=this.components.get(Oe).get(t).castRay();if(!n)return this._pickedPoint!==null&&(this.onVertexLost.trigger(),this._pickedPoint=null),this._pickedPoint;const r=this.getClosestVertex(n);return r?(this.workingPlane?Math.abs(this.workingPlane.distanceToPoint(r))<.001:!0)?((this._pickedPoint===null||!this._pickedPoint.equals(r))&&(this._pickedPoint=r.clone(),this.onVertexFound.trigger(this._pickedPoint)),this._pickedPoint):(this._pickedPoint=null,this._pickedPoint):(this._pickedPoint!==null&&(this.onVertexLost.trigger(),this._pickedPoint=null),this._pickedPoint)}getClosestVertex(t){let e=new x.Vector3,i=!1,n=Number.MAX_SAFE_INTEGER;const r=this.getVertices(t);if(r===null)return null;for(const o of r){if(!o)continue;const a=t.point.distanceTo(o);a>n||a>this._config.snapDistance||(i=!0,e=o,n=t.point.distanceTo(o))}return i?e:this.config.showOnlyVertex?null:t.point}getVertices(t){const e=t.object;if(!t.face||!e)return null;const i=e.geometry,n=new x.Matrix4,{instanceId:r}=t,o=r!==void 0,a=e instanceof x.InstancedMesh;return a&&o&&e.getMatrixAt(r,n),[this.getVertex(t.face.a,i),this.getVertex(t.face.b,i),this.getVertex(t.face.c,i)].map(l=>(l&&(a&&o&&l.applyMatrix4(n),l.applyMatrix4(e.matrixWorld)),l))}getVertex(t,e){if(t===void 0)return null;const i=e.attributes.position;return new x.Vector3(i.getX(t),i.getY(t),i.getZ(t))}}const ci=class ci{constructor(){T(this,"onDisposed",new j);T(this,"list",new Map);T(this,"enabled",!1);T(this,"_clock");T(this,"update",()=>{if(!this.enabled)return;const s=this._clock.getDelta();for(const[t,e]of this.list)e.enabled&&e.isUpdateable()&&e.update(s);requestAnimationFrame(this.update)});this._clock=new x.Clock,ci.setupBVH()}add(s,t){if(this.list.has(s))throw new Error("You're trying to add a component that already exists in the components instance. Use Components.get() instead.");le.validate(s),this.list.set(s,t)}get(s){const t=s.uuid;if(!this.list.has(t)){const e=new s(this);return this.list.has(t)||this.add(t,e),e}return this.list.get(t)}init(){this.enabled=!0,this._clock.start(),this.update()}dispose(){this.enabled=!1;for(const[s,t]of this.list)t.enabled=!1,t.isDisposeable()&&t.dispose();this._clock.stop(),this.onDisposed.trigger(),this.onDisposed.reset()}static setupBVH(){x.BufferGeometry.prototype.computeBoundsTree=fa,x.BufferGeometry.prototype.disposeBoundsTree=pa,x.Mesh.prototype.raycast=ua}};T(ci,"release","2.2.4");let Js=ci;class Fr extends Ri{constructor(){super(...arguments);T(this,"meshes",new Set);T(this,"onAfterUpdate",new j);T(this,"onBeforeUpdate",new j);T(this,"onDisposed",new j);T(this,"isDisposing",!1);T(this,"enabled",!0);T(this,"uuid",le.create());T(this,"name");T(this,"_scene");T(this,"_camera");T(this,"_renderer",null)}get scene(){if(!this._scene)throw new Error("No scene initialized!");return this._scene}set scene(t){this._scene=t,t.worlds.set(this.uuid,this),t.currentWorld=this,t.onWorldChanged.trigger({world:this,action:"added"})}get camera(){if(!this._camera)throw new Error("No camera initialized!");return this._camera}set camera(t){this._camera=t,t.worlds.set(this.uuid,this),t.currentWorld=this,t.onWorldChanged.trigger({world:this,action:"added"})}get renderer(){return this._renderer}set renderer(t){this._renderer=t,t&&(t.worlds.set(this.uuid,this),t.currentWorld=this,t.onWorldChanged.trigger({world:this,action:"added"}))}update(t){this.enabled&&(!this._scene||!this._camera||(this.scene.currentWorld=this,this.camera.currentWorld=this,this.renderer&&(this.renderer.currentWorld=this),this.onBeforeUpdate.trigger(),this.scene.isUpdateable()&&this.scene.update(t),this.camera.isUpdateable()&&this.camera.update(t),this.renderer&&this.renderer.update(t),this.onAfterUpdate.trigger()))}dispose(t=!0){if(this.enabled=!1,this.isDisposing=!0,this.scene.onWorldChanged.trigger({world:this,action:"removed"}),this.camera.onWorldChanged.trigger({world:this,action:"removed"}),this.renderer&&this.renderer.onWorldChanged.trigger({world:this,action:"removed"}),t){const e=this.components.get(ce);this.scene.dispose(),this.camera.isDisposeable()&&this.camera.dispose(),this.renderer&&this.renderer.dispose();for(const i of this.meshes)e.destroy(i);this.meshes.clear()}this._scene=null,this._camera=null,this._renderer=null,this.onDisposed.trigger()}}class Or extends Rr{constructor(t){super(t);T(this,"isSetup",!1);T(this,"three");T(this,"onSetup",new j);T(this,"config",{directionalLight:{color:new x.Color("white"),intensity:1.5,position:new x.Vector3(5,10,3)},ambientLight:{color:new x.Color("white"),intensity:1}});this.three=new x.Scene,this.three.background=new x.Color(2107698)}setup(t){this.config={...this.config,...t};const e=new x.DirectionalLight(this.config.directionalLight.color,this.config.directionalLight.intensity);e.position.copy(this.config.directionalLight.position);const i=new x.AmbientLight(this.config.ambientLight.color,this.config.ambientLight.intensity);this.three.add(e,i),this.directionalLights.set(e.uuid,e),this.ambientLights.set(i.uuid,i),this.isSetup=!0,this.onSetup.trigger(this)}}class ya extends Ar{constructor(t,e,i){super(t);T(this,"enabled",!0);T(this,"container");T(this,"three");T(this,"_canvas");T(this,"_parameters");T(this,"_resizeObserver",null);T(this,"onContainerUpdated",new j);T(this,"_resizing",!1);T(this,"resize",t=>{if(this._resizing)return;this._resizing=!0,this.onContainerUpdated.trigger();const e=t?t.x:this.container.clientWidth,i=t?t.y:this.container.clientHeight;this.three.setSize(e,i),this.onResize.trigger(new x.Vector2(e,i)),this._resizing=!1});T(this,"resizeEvent",()=>{this.resize()});T(this,"onContextLost",t=>{t.preventDefault(),this.enabled=!1});T(this,"onContextBack",()=>{this.three.setRenderTarget(null),this.three.dispose(),this.three=new x.WebGLRenderer({canvas:this._canvas,antialias:!0,alpha:!0,...this._parameters}),this.enabled=!0});this.container=e,this._parameters=i,this.three=new x.WebGLRenderer({antialias:!0,alpha:!0,...i}),this.three.setPixelRatio(Math.min(window.devicePixelRatio,2)),this.setupRenderer(),this.setupEvents(!0),this.resize(),this._canvas=this.three.domElement;const n=this.three.getContext(),{canvas:r}=n;r.addEventListener("webglcontextlost",this.onContextLost,!1),r.addEventListener("webglcontextrestored",this.onContextBack,!1)}update(){if(!this.enabled||!this.currentWorld)return;this.onBeforeUpdate.trigger(this);const t=this.currentWorld.scene.three,e=this.currentWorld.camera.three;this.three.render(t,e),this.onAfterUpdate.trigger(this)}dispose(){this.enabled=!1,this.setupEvents(!1),this.three.domElement.remove(),this.three.forceContextLoss(),this.three.dispose(),this.onResize.reset(),this.onAfterUpdate.reset(),this.onBeforeUpdate.reset(),this.onDisposed.trigger(),this.onDisposed.reset()}getSize(){return new x.Vector2(this.three.domElement.clientWidth,this.three.domElement.clientHeight)}setupEvents(t){const e=this.three.domElement.parentElement;if(!e)throw new Error("This renderer needs to have an HTML container!");this._resizeObserver&&(this._resizeObserver.disconnect(),this._resizeObserver=null),window.removeEventListener("resize",this.resizeEvent),t&&(this._resizeObserver=new ResizeObserver(this.resizeEvent),this._resizeObserver.observe(e),window.addEventListener("resize",this.resizeEvent))}setupRenderer(){this.three.localClippingEnabled=!0,this.container&&this.container.appendChild(this.three.domElement),this.onContainerUpdated.trigger()}}/*!
6
6
  * camera-controls
7
7
  * https://github.com/yomotsu/camera-controls
8
8
  * (c) 2017 @yomotsu
@@ -24,7 +24,7 @@
24
24
  }
25
25
  postMessage({ colors });
26
26
  });
27
- `,n=new Blob([i],{type:"application/javascript"});this.worker=new Worker(URL.createObjectURL(n))}dispose(){this.enabled=!1;for(const s of this.scene.children)s.removeFromParent();this.onViewUpdated.reset(),this.worker.terminate(),this.renderer.forceContextLoss(),this.renderer.dispose(),this.renderTarget.dispose(),this._buffer=null,this.onDisposed.reset()}getAvailableColor(){let s=BigInt(this._availableColor.toString());const t=[];do t.unshift(Number(s%256n)),s/=256n;while(s);for(;t.length!==3;)t.unshift(0);const[e,i,n]=t,r=`${e}-${i}-${n}`;return{r:e,g:i,b:n,code:r}}increaseColor(){if(this._availableColor===256*256*256){console.warn("Color can't be increased over 256 x 256 x 256!");return}this._availableColor++}decreaseColor(){if(this._availableColor===1){console.warn("Color can't be decreased under 0!");return}this._availableColor--}applySettings(s){s&&(s.updateInterval!==void 0&&(this.updateInterval=s.updateInterval),s.height!==void 0&&(this._height=s.height),s.width!==void 0&&(this._width=s.width),s.autoUpdate!==void 0&&(this.autoUpdate=s.autoUpdate))}}class Pr extends br{constructor(t,e,i){super(t,e,i);T(this,"onViewUpdated",new j);T(this,"threshold",100);T(this,"colorMeshes",new Map);T(this,"isProcessing",!1);T(this,"_colorCodeMeshMap",new Map);T(this,"_meshIDColorCodeMap",new Map);T(this,"_currentVisibleMeshes",new Set);T(this,"_recentlyHiddenMeshes",new Set);T(this,"_intervalID",null);T(this,"_transparentMat",new x.MeshBasicMaterial({transparent:!0,opacity:0}));T(this,"handleWorkerMessage",async t=>{if(this.isProcessing)return;const e=t.data.colors;this._recentlyHiddenMeshes=new Set(this._currentVisibleMeshes),this._currentVisibleMeshes.clear();for(const[i,n]of e){if(n<this.threshold)continue;const r=this._colorCodeMeshMap.get(i);r&&(this._currentVisibleMeshes.add(r),this._recentlyHiddenMeshes.delete(r))}this.onViewUpdated.trigger({seen:this._currentVisibleMeshes,unseen:this._recentlyHiddenMeshes}),this._isWorkerBusy=!1});this.worker.addEventListener("message",this.handleWorkerMessage),this.autoUpdate&&window.setInterval(async()=>{this.isProcessing||await this.updateVisibility()},this.updateInterval),this.onViewUpdated.add(({seen:n,unseen:r})=>{for(const o of n)o.visible=!0;for(const o of r)o.visible=!1})}dispose(){super.dispose(),this._intervalID!==null&&(window.clearInterval(this._intervalID),this._intervalID=null),this._currentVisibleMeshes.clear(),this._recentlyHiddenMeshes.clear(),this._meshIDColorCodeMap.clear(),this._transparentMat.dispose(),this._colorCodeMeshMap.clear();const t=this.components.get(ce);for(const e in this.colorMeshes){const i=this.colorMeshes.get(e);i&&t.destroy(i,!0)}this.colorMeshes.clear()}add(t){if(!this.enabled)return;if(this.isProcessing){console.log("Culler processing not finished yet.");return}this.isProcessing=!0;const e=t instanceof x.InstancedMesh,{geometry:i,material:n}=t,{colorMaterial:r,code:o}=this.getAvailableMaterial();let a;if(Array.isArray(n)){let u=!0;const d=[];for(const f of n)on.isTransparent(f)?d.push(this._transparentMat):(u=!1,d.push(r));if(u){r.dispose(),this.isProcessing=!1;return}a=d}else if(on.isTransparent(n)){r.dispose(),this.isProcessing=!1;return}else a=r;this._colorCodeMeshMap.set(o,t),this._meshIDColorCodeMap.set(t.uuid,o);const l=e?t.count:1,h=new x.InstancedMesh(i,a,l);e?h.instanceMatrix=t.instanceMatrix:h.setMatrixAt(0,new x.Matrix4),t.visible=!1,t.updateWorldMatrix(!0,!1),h.applyMatrix4(t.matrixWorld),h.updateMatrix(),this.scene.add(h),this.colorMeshes.set(t.uuid,h),this.increaseColor(),this.isProcessing=!1}remove(t){if(this.isProcessing){console.log("Culler processing not finished yet.");return}this.isProcessing=!0;const e=this.components.get(ce);this._currentVisibleMeshes.delete(t),this._recentlyHiddenMeshes.delete(t);const i=this.colorMeshes.get(t.uuid),n=this._meshIDColorCodeMap.get(t.uuid);if(!i||!n){this.isProcessing=!1;return}this._colorCodeMeshMap.delete(n),this._meshIDColorCodeMap.delete(t.uuid),this.colorMeshes.delete(t.uuid),i.geometry=void 0,i.material=[],e.destroy(i,!0),this._recentlyHiddenMeshes.delete(t),this._currentVisibleMeshes.delete(t),this.isProcessing=!1}updateInstanced(t){for(const e of t){const i=this.colorMeshes.get(e.uuid);i&&(i.count=e.count)}}getAvailableMaterial(){const{r:t,g:e,b:i,code:n}=this.getAvailableColor(),r=x.ColorManagement.enabled;x.ColorManagement.enabled=!1;const o=new x.Color(`rgb(${t}, ${e}, ${i})`);if(!this.world.renderer)throw new Error("Renderer not found in the world!");const a=this.world.renderer.clippingPlanes,l=new x.MeshBasicMaterial({color:o,clippingPlanes:a,side:x.DoubleSide});return x.ColorManagement.enabled=r,{colorMaterial:l,code:n}}}const Is=class Is extends wt{constructor(t){super(t);T(this,"onDisposed",new j);T(this,"_enabled",!0);T(this,"list",new Map);t.add(Is.uuid,this)}get enabled(){return this._enabled}set enabled(t){this._enabled=t;for(const[e,i]of this.list)i.enabled=t}create(t,e){if(this.list.has(t.uuid))return this.list.get(t.uuid);const i=new Pr(this.components,t,e);return this.list.set(t.uuid,i),i}delete(t){const e=this.list.get(t.uuid);e&&e.dispose(),this.list.delete(t.uuid)}dispose(){this.enabled=!1,this.onDisposed.trigger(Is.uuid),this.onDisposed.reset();for(const[t,e]of this.list)e.dispose();this.list.clear()}updateInstanced(t){for(const[,e]of this.list)e.updateInstanced(t)}};T(Is,"uuid","69f2a50d-c266-44fc-b1bd-fa4d34be89e6");let ei=Is;class Pa{constructor(s,t){T(this,"onDisposed",new j);T(this,"onDistanceComputed",new j);T(this,"excludedObjects",new Set);T(this,"enabled",!0);T(this,"renderDebugFrame",!1);T(this,"components");T(this,"scene",new x.Scene);T(this,"camera",new x.OrthographicCamera(-1,1,1,-1,0,1));T(this,"depthMaterial");T(this,"world");T(this,"renderer");T(this,"worker");T(this,"_width",512);T(this,"_height",512);T(this,"_postQuad");T(this,"tempRT");T(this,"resultRT");T(this,"bufferSize");T(this,"_buffer");T(this,"_isWorkerBusy",!1);T(this,"compute",async()=>{if(!this.enabled||this.world.isDisposing||this._isWorkerBusy)return;this._isWorkerBusy=!0,this.world.camera.three.updateMatrix(),this.renderer.setSize(this._width,this._height),this.renderer.setRenderTarget(this.tempRT);const s="visibilityBeforeDistanceCheck";for(const e of this.excludedObjects)e.userData[s]=e.visible,e.visible=!1;this.renderer.render(this.world.scene.three,this.world.camera.three);for(const e of this.excludedObjects)e.userData[s]!==void 0&&(e.visible=e.userData[s]);this.depthMaterial.uniforms.tDiffuse.value=this.tempRT.texture,this.depthMaterial.uniforms.tDepth.value=this.tempRT.depthTexture,this.renderer.setRenderTarget(this.resultRT),this.renderer.render(this.scene,this.camera);const t=this.renderer.getContext();await Cn(t,0,0,this._width,this._height,t.RGBA,t.UNSIGNED_BYTE,this._buffer),this.renderer.setRenderTarget(null),this.renderDebugFrame&&this.renderer.render(this.scene,this.camera),this.worker.postMessage({buffer:this._buffer})});T(this,"handleWorkerMessage",s=>{if(!this.enabled||this.world.isDisposing)return;const t=s.data.colors;let e=Number.MAX_VALUE;for(const a of t)a!==0&&a<e&&(e=a);const i=this.world.camera.three||x.OrthographicCamera,r=(e/255-1)*-1*(i.far-i.near),o=Math.min(r,i.far);this.onDistanceComputed.trigger(o),this._isWorkerBusy=!1});if(!t.renderer)throw new Error("The given world must have a renderer!");this.components=s,this.world=t;const e=t.camera.three;this.renderer=new x.WebGLRenderer,this.tempRT=new x.WebGLRenderTarget(this._width,this._height),this.bufferSize=this._width*this._height*4,this._buffer=new Uint8Array(this.bufferSize),this.tempRT.texture.minFilter=x.NearestFilter,this.tempRT.texture.magFilter=x.NearestFilter,this.tempRT.stencilBuffer=!1,this.tempRT.samples=0,this.tempRT.depthTexture=new x.DepthTexture(this._width,this._height),this.tempRT.depthTexture.format=x.DepthFormat,this.tempRT.depthTexture.type=x.UnsignedShortType,this.resultRT=new x.WebGLRenderTarget(this._width,this._height),this.depthMaterial=new x.ShaderMaterial({vertexShader:`
27
+ `,n=new Blob([i],{type:"application/javascript"});this.worker=new Worker(URL.createObjectURL(n))}dispose(){this.enabled=!1;for(const s of this.scene.children)s.removeFromParent();this.onViewUpdated.reset(),this.worker.terminate(),this.renderer.forceContextLoss(),this.renderer.dispose(),this.renderTarget.dispose(),this._buffer=null,this.onDisposed.reset()}getAvailableColor(){let s=BigInt(this._availableColor.toString());const t=[];do t.unshift(Number(s%256n)),s/=256n;while(s);for(;t.length!==3;)t.unshift(0);const[e,i,n]=t,r=`${e}-${i}-${n}`;return{r:e,g:i,b:n,code:r}}increaseColor(){if(this._availableColor===256*256*256){console.warn("Color can't be increased over 256 x 256 x 256!");return}this._availableColor++}decreaseColor(){if(this._availableColor===1){console.warn("Color can't be decreased under 0!");return}this._availableColor--}applySettings(s){s&&(s.updateInterval!==void 0&&(this.updateInterval=s.updateInterval),s.height!==void 0&&(this._height=s.height),s.width!==void 0&&(this._width=s.width),s.autoUpdate!==void 0&&(this.autoUpdate=s.autoUpdate))}}class Pr extends br{constructor(t,e,i){super(t,e,i);T(this,"onViewUpdated",new j);T(this,"threshold",100);T(this,"colorMeshes",new Map);T(this,"isProcessing",!1);T(this,"_interval",null);T(this,"_colorCodeMeshMap",new Map);T(this,"_meshIDColorCodeMap",new Map);T(this,"_currentVisibleMeshes",new Set);T(this,"_recentlyHiddenMeshes",new Set);T(this,"_intervalID",null);T(this,"_transparentMat",new x.MeshBasicMaterial({transparent:!0,opacity:0}));T(this,"handleWorkerMessage",async t=>{if(this.isProcessing)return;const e=t.data.colors;this._recentlyHiddenMeshes=new Set(this._currentVisibleMeshes),this._currentVisibleMeshes.clear();for(const[i,n]of e){if(n<this.threshold)continue;const r=this._colorCodeMeshMap.get(i);r&&(this._currentVisibleMeshes.add(r),this._recentlyHiddenMeshes.delete(r))}this.onViewUpdated.trigger({seen:this._currentVisibleMeshes,unseen:this._recentlyHiddenMeshes}),this._isWorkerBusy=!1});this.worker.addEventListener("message",this.handleWorkerMessage),this.autoUpdate&&(this._interval=window.setInterval(async()=>{this.isProcessing||await this.updateVisibility()},this.updateInterval)),this.onViewUpdated.add(({seen:n,unseen:r})=>{for(const o of n)o.visible=!0;for(const o of r)o.visible=!1})}dispose(){super.dispose(),this._intervalID!==null&&(window.clearInterval(this._intervalID),this._intervalID=null),this._interval!==null&&(window.clearInterval(this._interval),this._intervalID=null),this._currentVisibleMeshes.clear(),this._recentlyHiddenMeshes.clear(),this._meshIDColorCodeMap.clear(),this._transparentMat.dispose(),this._colorCodeMeshMap.clear();const t=this.components.get(ce);for(const e in this.colorMeshes){const i=this.colorMeshes.get(e);i&&t.destroy(i,!0)}this.colorMeshes.clear()}add(t){if(!this.enabled)return;if(this.isProcessing){console.log("Culler processing not finished yet.");return}this.isProcessing=!0;const e=t instanceof x.InstancedMesh,{geometry:i,material:n}=t,{colorMaterial:r,code:o}=this.getAvailableMaterial();let a;if(Array.isArray(n)){let u=!0;const d=[];for(const f of n)on.isTransparent(f)?d.push(this._transparentMat):(u=!1,d.push(r));if(u){r.dispose(),this.isProcessing=!1;return}a=d}else if(on.isTransparent(n)){r.dispose(),this.isProcessing=!1;return}else a=r;this._colorCodeMeshMap.set(o,t),this._meshIDColorCodeMap.set(t.uuid,o);const l=e?t.count:1,h=new x.InstancedMesh(i,a,l);e?h.instanceMatrix=t.instanceMatrix:h.setMatrixAt(0,new x.Matrix4),t.visible=!1,t.updateWorldMatrix(!0,!1),h.applyMatrix4(t.matrixWorld),h.updateMatrix(),this.scene.add(h),this.colorMeshes.set(t.uuid,h),this.increaseColor(),this.isProcessing=!1}remove(t){if(this.isProcessing){console.log("Culler processing not finished yet.");return}this.isProcessing=!0;const e=this.components.get(ce);this._currentVisibleMeshes.delete(t),this._recentlyHiddenMeshes.delete(t);const i=this.colorMeshes.get(t.uuid),n=this._meshIDColorCodeMap.get(t.uuid);if(!i||!n){this.isProcessing=!1;return}this._colorCodeMeshMap.delete(n),this._meshIDColorCodeMap.delete(t.uuid),this.colorMeshes.delete(t.uuid),i.geometry=void 0,i.material=[],e.destroy(i,!0),this._recentlyHiddenMeshes.delete(t),this._currentVisibleMeshes.delete(t),this.isProcessing=!1}updateInstanced(t){for(const e of t){const i=this.colorMeshes.get(e.uuid);i&&(i.count=e.count)}}getAvailableMaterial(){const{r:t,g:e,b:i,code:n}=this.getAvailableColor(),r=x.ColorManagement.enabled;x.ColorManagement.enabled=!1;const o=new x.Color(`rgb(${t}, ${e}, ${i})`);if(!this.world.renderer)throw new Error("Renderer not found in the world!");const a=this.world.renderer.clippingPlanes,l=new x.MeshBasicMaterial({color:o,clippingPlanes:a,side:x.DoubleSide});return x.ColorManagement.enabled=r,{colorMaterial:l,code:n}}}const Is=class Is extends wt{constructor(t){super(t);T(this,"onDisposed",new j);T(this,"_enabled",!0);T(this,"list",new Map);t.add(Is.uuid,this)}get enabled(){return this._enabled}set enabled(t){this._enabled=t;for(const[e,i]of this.list)i.enabled=t}create(t,e){if(this.list.has(t.uuid))return this.list.get(t.uuid);const i=new Pr(this.components,t,e);return this.list.set(t.uuid,i),i}delete(t){const e=this.list.get(t.uuid);e&&e.dispose(),this.list.delete(t.uuid)}dispose(){this.enabled=!1,this.onDisposed.trigger(Is.uuid),this.onDisposed.reset();for(const[t,e]of this.list)e.dispose();this.list.clear()}updateInstanced(t){for(const[,e]of this.list)e.updateInstanced(t)}};T(Is,"uuid","69f2a50d-c266-44fc-b1bd-fa4d34be89e6");let ei=Is;class Pa{constructor(s,t){T(this,"onDisposed",new j);T(this,"onDistanceComputed",new j);T(this,"excludedObjects",new Set);T(this,"enabled",!0);T(this,"renderDebugFrame",!1);T(this,"components");T(this,"scene",new x.Scene);T(this,"camera",new x.OrthographicCamera(-1,1,1,-1,0,1));T(this,"depthMaterial");T(this,"world");T(this,"renderer");T(this,"worker");T(this,"_width",512);T(this,"_height",512);T(this,"_postQuad");T(this,"tempRT");T(this,"resultRT");T(this,"bufferSize");T(this,"_buffer");T(this,"_isWorkerBusy",!1);T(this,"compute",async()=>{if(!this.enabled||this.world.isDisposing||this._isWorkerBusy)return;this._isWorkerBusy=!0,this.world.camera.three.updateMatrix(),this.renderer.setSize(this._width,this._height),this.renderer.setRenderTarget(this.tempRT);const s="visibilityBeforeDistanceCheck";for(const e of this.excludedObjects)e.userData[s]=e.visible,e.visible=!1;this.renderer.render(this.world.scene.three,this.world.camera.three);for(const e of this.excludedObjects)e.userData[s]!==void 0&&(e.visible=e.userData[s]);this.depthMaterial.uniforms.tDiffuse.value=this.tempRT.texture,this.depthMaterial.uniforms.tDepth.value=this.tempRT.depthTexture,this.renderer.setRenderTarget(this.resultRT),this.renderer.render(this.scene,this.camera);const t=this.renderer.getContext();await Cn(t,0,0,this._width,this._height,t.RGBA,t.UNSIGNED_BYTE,this._buffer),this.renderer.setRenderTarget(null),this.renderDebugFrame&&this.renderer.render(this.scene,this.camera),this.worker.postMessage({buffer:this._buffer})});T(this,"handleWorkerMessage",s=>{if(!this.enabled||this.world.isDisposing)return;const t=s.data.colors;let e=Number.MAX_VALUE;for(const a of t)a!==0&&a<e&&(e=a);const i=this.world.camera.three||x.OrthographicCamera,r=(e/255-1)*-1*(i.far-i.near),o=Math.min(r,i.far);this.onDistanceComputed.trigger(o),this._isWorkerBusy=!1});if(!t.renderer)throw new Error("The given world must have a renderer!");this.components=s,this.world=t;const e=t.camera.three;this.renderer=new x.WebGLRenderer,this.tempRT=new x.WebGLRenderTarget(this._width,this._height),this.bufferSize=this._width*this._height*4,this._buffer=new Uint8Array(this.bufferSize),this.tempRT.texture.minFilter=x.NearestFilter,this.tempRT.texture.magFilter=x.NearestFilter,this.tempRT.stencilBuffer=!1,this.tempRT.samples=0,this.tempRT.depthTexture=new x.DepthTexture(this._width,this._height),this.tempRT.depthTexture.format=x.DepthFormat,this.tempRT.depthTexture.type=x.UnsignedShortType,this.resultRT=new x.WebGLRenderTarget(this._width,this._height),this.depthMaterial=new x.ShaderMaterial({vertexShader:`
28
28
  varying vec2 vUv;
29
29
 
30
30
  void main() {
package/dist/index.mjs CHANGED
@@ -3114,7 +3114,7 @@ const di = class di {
3114
3114
  /**
3115
3115
  * The version of the @thatopen/components library.
3116
3116
  */
3117
- T(di, "release", "2.2.3");
3117
+ T(di, "release", "2.2.4");
3118
3118
  let on = di;
3119
3119
  class Pa extends _n {
3120
3120
  constructor() {
@@ -5110,6 +5110,7 @@ class ka extends za {
5110
5110
  * Used to prevent concurrent processing.
5111
5111
  */
5112
5112
  T(this, "isProcessing", !1);
5113
+ T(this, "_interval", null);
5113
5114
  T(this, "_colorCodeMeshMap", /* @__PURE__ */ new Map());
5114
5115
  T(this, "_meshIDColorCodeMap", /* @__PURE__ */ new Map());
5115
5116
  T(this, "_currentVisibleMeshes", /* @__PURE__ */ new Set());
@@ -5135,9 +5136,9 @@ class ka extends za {
5135
5136
  unseen: this._recentlyHiddenMeshes
5136
5137
  }), this._isWorkerBusy = !1;
5137
5138
  });
5138
- this.worker.addEventListener("message", this.handleWorkerMessage), this.autoUpdate && window.setInterval(async () => {
5139
+ this.worker.addEventListener("message", this.handleWorkerMessage), this.autoUpdate && (this._interval = window.setInterval(async () => {
5139
5140
  this.isProcessing || await this.updateVisibility();
5140
- }, this.updateInterval), this.onViewUpdated.add(({ seen: n, unseen: r }) => {
5141
+ }, this.updateInterval)), this.onViewUpdated.add(({ seen: n, unseen: r }) => {
5141
5142
  for (const o of n)
5142
5143
  o.visible = !0;
5143
5144
  for (const o of r)
@@ -5146,7 +5147,7 @@ class ka extends za {
5146
5147
  }
5147
5148
  /** {@link Disposable.dispose} */
5148
5149
  dispose() {
5149
- super.dispose(), this._intervalID !== null && (window.clearInterval(this._intervalID), this._intervalID = null), this._currentVisibleMeshes.clear(), this._recentlyHiddenMeshes.clear(), this._meshIDColorCodeMap.clear(), this._transparentMat.dispose(), this._colorCodeMeshMap.clear();
5150
+ super.dispose(), this._intervalID !== null && (window.clearInterval(this._intervalID), this._intervalID = null), this._interval !== null && (window.clearInterval(this._interval), this._intervalID = null), this._currentVisibleMeshes.clear(), this._recentlyHiddenMeshes.clear(), this._meshIDColorCodeMap.clear(), this._transparentMat.dispose(), this._colorCodeMeshMap.clear();
5150
5151
  const t = this.components.get(ye);
5151
5152
  for (const e in this.colorMeshes) {
5152
5153
  const i = this.colorMeshes.get(e);
@@ -7515,19 +7516,6 @@ const nc = /* @__PURE__ */ new Map([
7515
7516
  }
7516
7517
  return r;
7517
7518
  }
7518
- // private readonly _changeMap: {
7519
- // [modelID: string]: {
7520
- // [attr: InverseAttribute]: {
7521
- // [expressID: number]: { added: number[]; removed: number[] };
7522
- // };
7523
- // };
7524
- // };
7525
- // removeEntitiesRelation(
7526
- // model: FragmentsGroup,
7527
- // expressID: number,
7528
- // relationName: InverseAttribute,
7529
- // ...relIDs: number[]
7530
- // ) {}
7531
7519
  /**
7532
7520
  * Adds relations between an entity and other entities in a BIM model.
7533
7521
  *
@@ -7556,33 +7544,6 @@ const nc = /* @__PURE__ */ new Map([
7556
7544
  a == null || a.set(o, n);
7557
7545
  }
7558
7546
  }
7559
- // private async addEntitiesRelation(
7560
- // model: FragmentsGroup,
7561
- // expressID: number,
7562
- // rel: { name: InverseAttribute; type: IfcRelName },
7563
- // ...relIDs: number[]
7564
- // ) {
7565
- // const { name, type } = rel;
7566
- // const ifcRel = createIfcRel(
7567
- // type,
7568
- // expressID,
7569
- // relIDs,
7570
- // model.ifcMetadata.schema,
7571
- // );
7572
- // if (!ifcRel) return;
7573
- // const propsManager = this.components.get(IfcPropertiesManager);
7574
- // await propsManager.setData(model, ifcRel);
7575
- // // ------
7576
- // const existingRelations = this.getEntityRelations(model, expressID, name);
7577
- // if (!existingRelations) {
7578
- // const attributeIndex = this.getAttributeIndex(name);
7579
- // if (!attributeIndex) return;
7580
- // const entityRelations = this.relationMaps[model.uuid].get(expressID);
7581
- // entityRelations?.set(attributeIndex, relIDs);
7582
- // } else {
7583
- // existingRelations.push(...relIDs);
7584
- // }
7585
- // }
7586
7547
  /**
7587
7548
  * Gets the children of the given element recursively. E.g. in a model with project - site - building - storeys - rooms, passing a storey will include all its children and the children of the rooms contained in it.
7588
7549
  *