diff --git a/examples/AngleMeasurement/index.html b/examples/AngleMeasurement/index.html
index 013df9e89..78df49410 100644
--- a/examples/AngleMeasurement/index.html
+++ b/examples/AngleMeasurement/index.html
@@ -60,6 +60,7 @@
+
diff --git a/examples/AreaMeasurement/index.html b/examples/AreaMeasurement/index.html
index b819e3164..35638d387 100644
--- a/examples/AreaMeasurement/index.html
+++ b/examples/AreaMeasurement/index.html
@@ -62,6 +62,7 @@
+
diff --git a/examples/EdgeMeasurement/index.html b/examples/EdgeMeasurement/index.html
index 0ca7ec1f7..6882455b3 100644
--- a/examples/EdgeMeasurement/index.html
+++ b/examples/EdgeMeasurement/index.html
@@ -62,6 +62,7 @@
+
diff --git a/examples/FaceMeasurement/index.html b/examples/FaceMeasurement/index.html
index 8c367d061..dcb86161a 100644
--- a/examples/FaceMeasurement/index.html
+++ b/examples/FaceMeasurement/index.html
@@ -62,6 +62,7 @@
+
diff --git a/examples/VolumeMeasurement/index.html b/examples/VolumeMeasurement/index.html
index 9f6e56ee1..f35ab7d6d 100644
--- a/examples/VolumeMeasurement/index.html
+++ b/examples/VolumeMeasurement/index.html
@@ -62,6 +62,7 @@
+
diff --git a/examples/assets/angleMeasurement.js b/examples/assets/angleMeasurement.js
index 7fcb89df7..ad3d26ac8 100644
--- a/examples/assets/angleMeasurement.js
+++ b/examples/assets/angleMeasurement.js
@@ -1 +1,23 @@
-import{B as d,M as c,a as l}from"./web-ifc-api-r1ed24cU.js";import{C as m,W as i,S as p,a as w,G as u}from"./index-4oEgnBmA.js";import{W as b,w as f}from"./index-CDKMALq_.js";import{S as g}from"./stats.min-GTpOrGrX.js";import"./_commonjsHelpers-Cpj98o6Y.js";const r=document.getElementById("container"),o=new m,y=o.get(i),e=y.create();e.scene=new p(o);e.renderer=new b(o,r);e.camera=new w(o);o.init();e.camera.controls.setLookAt(5,5,5,0,0,0);e.scene.setup();const S=o.get(u);S.create(e);e.scene.three.background=null;const h=new d(3,3,3),k=new c({color:"#6528D7"}),s=new l(h,k);s.position.set(0,1.5,0);e.scene.three.add(s);e.meshes.add(s);const t=o.get(f);t.world=e;t.enabled=!0;r.ondblclick=()=>t.create();window.onkeydown=a=>{(a.code==="Delete"||a.code==="Backspace")&&t.deleteAll()};const n=new g;n.showPanel(2);document.body.append(n.dom);n.dom.style.left="0px";n.dom.style.zIndex="unset";e.renderer.onBeforeUpdate.add(()=>n.begin());e.renderer.onAfterUpdate.add(()=>n.end());
+import{B as d,M as m,a as b}from"./web-ifc-api-r1ed24cU.js";import{C as p,W as u,S as w,a as g,G as h}from"./index-4oEgnBmA.js";import{T as k,L as c,m as i}from"./index-ByMLC5eT.js";import{W as f,w as y}from"./index-CDKMALq_.js";import{S}from"./stats.min-GTpOrGrX.js";import"./_commonjsHelpers-Cpj98o6Y.js";const r=document.getElementById("container"),n=new p,D=n.get(u),e=D.create();e.scene=new w(n);e.renderer=new f(n,r);e.camera=new g(n);n.init();e.camera.controls.setLookAt(5,5,5,0,0,0);e.scene.setup();const L=n.get(h);L.create(e);e.scene.three.background=null;const M=new d(3,3,3),v=new m({color:"#6528D7"}),l=new b(M,v);l.position.set(0,1.5,0);e.scene.three.add(l);e.meshes.add(l);const t=n.get(y);t.world=e;t.enabled=!0;r.ondblclick=()=>t.create();window.onkeydown=a=>{(a.code==="Delete"||a.code==="Backspace")&&t.deleteAll()};const o=new S;o.showPanel(2);document.body.append(o.dom);o.dom.style.left="0px";o.dom.style.zIndex="unset";e.renderer.onBeforeUpdate.add(()=>o.begin());e.renderer.onAfterUpdate.add(()=>o.end());k.init();const s=c.create(()=>i`
+
+
+ Create angle: Double click
+ Delete angle: Delete
+
+
+
+ {t.enabled=a.value}}">
+
+
+ {t.deleteAll()}}">
+
+
+
+
+ `);document.body.append(s);const x=c.create(()=>i`
+ {s.classList.contains("options-menu-visible")?s.classList.remove("options-menu-visible"):s.classList.add("options-menu-visible")}}">
+
+ `);document.body.append(x);
diff --git a/examples/assets/areaMeasurement.js b/examples/assets/areaMeasurement.js
index 38549028a..8bc3904a3 100644
--- a/examples/assets/areaMeasurement.js
+++ b/examples/assets/areaMeasurement.js
@@ -1 +1,27 @@
-import{B as d,M as c,a as m}from"./web-ifc-api-r1ed24cU.js";import{S as l}from"./stats.min-GTpOrGrX.js";import{C as i,W as p,S as w,a as u,G as b}from"./index-4oEgnBmA.js";import{W as f,v as g}from"./index-CDKMALq_.js";import"./_commonjsHelpers-Cpj98o6Y.js";const s=document.getElementById("container"),n=new i,y=n.get(p),e=y.create();e.scene=new w(n);e.renderer=new f(n,s);e.camera=new u(n);n.init();e.camera.controls.setLookAt(5,5,5,0,0,0);e.scene.setup();const S=n.get(b);S.create(e);e.scene.three.background=null;const h=new d(3,3,3),k=new c({color:"#6528D7"}),a=new m(h,k);a.position.set(0,1.5,0);e.scene.three.add(a);e.meshes.add(a);const t=n.get(g);t.world=e;t.enabled=!0;s.ondblclick=()=>t.create();s.oncontextmenu=()=>t.endCreation();window.onkeydown=r=>{(r.code==="Delete"||r.code==="Backspace")&&t.deleteAll()};const o=new l;o.showPanel(2);document.body.append(o.dom);o.dom.style.left="0px";o.dom.style.zIndex="unset";e.renderer.onBeforeUpdate.add(()=>o.begin());e.renderer.onAfterUpdate.add(()=>o.end());
+import{B as m,M as d,a as b}from"./web-ifc-api-r1ed24cU.js";import{S as p}from"./stats.min-GTpOrGrX.js";import{C as u,W as h,S as k,a as w,G as g}from"./index-4oEgnBmA.js";import{T as f,L as c,m as r}from"./index-ByMLC5eT.js";import{W as v,v as y}from"./index-CDKMALq_.js";import"./_commonjsHelpers-Cpj98o6Y.js";const l=document.getElementById("container"),t=new u,x=t.get(h),e=x.create();e.scene=new k(t);e.renderer=new v(t,l);e.camera=new w(t);t.init();e.camera.controls.setLookAt(5,5,5,0,0,0);e.scene.setup();const A=t.get(g);A.create(e);e.scene.three.background=null;const C=new m(3,3,3),D=new d({color:"#6528D7"}),i=new b(C,D);i.position.set(0,1.5,0);e.scene.three.add(i);e.meshes.add(i);const n=t.get(y);n.world=e;n.enabled=!0;l.ondblclick=()=>n.create();l.oncontextmenu=()=>n.endCreation();window.onkeydown=o=>{(o.code==="Delete"||o.code==="Backspace")&&n.deleteAll()};const a=new p;a.showPanel(2);document.body.append(a.dom);a.dom.style.left="0px";a.dom.style.zIndex="unset";e.renderer.onBeforeUpdate.add(()=>a.begin());e.renderer.onAfterUpdate.add(()=>a.end());f.init();const s=c.create(()=>r`
+
+
+ Create area dimension: Double click
+ Calculate selected area: Right click
+ Delete dimension: Delete
+
+
+
+ {n.enabled=o.value}}">
+
+ {n.visible=o.value}}">
+
+
+ {n.deleteAll()}}">
+
+
+
+
+ `);document.body.append(s);const S=c.create(()=>r`
+ {s.classList.contains("options-menu-visible")?s.classList.remove("options-menu-visible"):s.classList.add("options-menu-visible")}}">
+
+ `);document.body.append(S);
diff --git a/examples/assets/edgeMeasurement.js b/examples/assets/edgeMeasurement.js
index 41d52e7d1..005e6d11e 100644
--- a/examples/assets/edgeMeasurement.js
+++ b/examples/assets/edgeMeasurement.js
@@ -1 +1,21 @@
-import{a as c}from"./web-ifc-api-r1ed24cU.js";import{S as i}from"./stats.min-GTpOrGrX.js";import{C as l,W as m,S as f,a as p,G as w,F as g}from"./index-4oEgnBmA.js";import{W as h,N as u}from"./index-CDKMALq_.js";import"./_commonjsHelpers-Cpj98o6Y.js";const r=document.getElementById("container"),t=new l,y=t.get(m),e=y.create();e.scene=new f(t);e.renderer=new h(t,r);e.camera=new p(t);t.init();e.camera.controls.setLookAt(5,5,5,0,0,0);e.scene.setup();const b=t.get(w);b.create(e);e.scene.three.background=null;const S=new g(t),k=await fetch("https://thatopen.github.io/engine_components/resources/small.frag"),A=await k.arrayBuffer(),W=new Uint8Array(A),d=S.load(W);e.scene.three.add(d);for(const o of d.children)o instanceof c&&e.meshes.add(o);const n=t.get(u);n.world=e;n.enabled=!0;r.ondblclick=()=>n.create();let a;window.addEventListener("keydown",o=>{o.code==="KeyO"?n.delete():o.code==="KeyS"?(a=n.get(),n.deleteAll()):o.code==="KeyL"&&a&&n.set(a)});const s=new i;s.showPanel(2);document.body.append(s.dom);s.dom.style.left="0px";s.dom.style.zIndex="unset";e.renderer.onBeforeUpdate.add(()=>s.begin());e.renderer.onAfterUpdate.add(()=>s.end());
+import{a as r}from"./web-ifc-api-r1ed24cU.js";import{S as c}from"./stats.min-GTpOrGrX.js";import{C as d,W as m,S as b,a as p,G as f,F as u}from"./index-4oEgnBmA.js";import{T as h,L as w,m as g}from"./index-ByMLC5eT.js";import{W as y,N as S}from"./index-CDKMALq_.js";import"./_commonjsHelpers-Cpj98o6Y.js";const l=document.getElementById("container"),a=new d,k=a.get(m),e=k.create();e.scene=new b(a);e.renderer=new y(a,l);e.camera=new p(a);a.init();e.camera.controls.setLookAt(5,5,5,0,0,0);e.scene.setup();const L=a.get(f);L.create(e);e.scene.three.background=null;const A=new u(a),C=await fetch("https://thatopen.github.io/engine_components/resources/small.frag"),D=await C.arrayBuffer(),x=new Uint8Array(D),i=A.load(x);e.scene.three.add(i);for(const t of i.children)t instanceof r&&e.meshes.add(t);const n=a.get(S);n.world=e;n.enabled=!0;l.ondblclick=()=>n.create();let s;window.addEventListener("keydown",t=>{t.code==="KeyO"?n.delete():t.code==="KeyS"?(s=n.get(),n.deleteAll()):t.code==="KeyL"&&s&&n.set(s)});const o=new c;o.showPanel(2);document.body.append(o.dom);o.dom.style.left="0px";o.dom.style.zIndex="unset";e.renderer.onBeforeUpdate.add(()=>o.begin());e.renderer.onAfterUpdate.add(()=>o.end());h.init();const P=w.create(()=>g`
+
+
+ Create dimension: Double click
+ Delete dimension: Press O
+ Delete all dimensions: Press S
+ Set/Show saved dimensions: Press L
+
+
+
+ {n.enabled=t.value}}">
+
+
+ {n.deleteAll()}}">
+
+
+
+
+ `);document.body.append(P);
diff --git a/examples/assets/faceMeasurement.js b/examples/assets/faceMeasurement.js
index 5989a841b..9fd28074a 100644
--- a/examples/assets/faceMeasurement.js
+++ b/examples/assets/faceMeasurement.js
@@ -1 +1,25 @@
-import{a as c}from"./web-ifc-api-r1ed24cU.js";import{S as i}from"./stats.min-GTpOrGrX.js";import{C as l,W as m,S as f,a as p,G as w,F as g}from"./index-4oEgnBmA.js";import{W as h,P as u}from"./index-CDKMALq_.js";import"./_commonjsHelpers-Cpj98o6Y.js";const r=document.getElementById("container"),t=new l,y=t.get(m),e=y.create();e.scene=new f(t);e.renderer=new h(t,r);e.camera=new p(t);t.init();e.camera.controls.setLookAt(5,5,5,0,0,0);e.scene.setup();const b=t.get(w);b.create(e);e.scene.three.background=null;const S=new g(t),k=await fetch("https://thatopen.github.io/engine_components/resources/small.frag"),A=await k.arrayBuffer(),W=new Uint8Array(A),d=S.load(W);e.scene.three.add(d);for(const o of d.children)o instanceof c&&e.meshes.add(o);const n=t.get(u);n.world=e;n.enabled=!0;r.ondblclick=()=>n.create();let a;window.addEventListener("keydown",o=>{o.code==="KeyO"?n.delete():o.code==="KeyS"?(a=n.get(),n.deleteAll()):o.code==="KeyL"&&a&&n.set(a)});const s=new i;s.showPanel(2);document.body.append(s.dom);s.dom.style.left="0px";s.dom.style.zIndex="unset";e.renderer.onBeforeUpdate.add(()=>s.begin());e.renderer.onAfterUpdate.add(()=>s.end());
+import{a as m}from"./web-ifc-api-r1ed24cU.js";import{S as b}from"./stats.min-GTpOrGrX.js";import{C as p,W as u,S as f,a as g,G as h,F as w}from"./index-4oEgnBmA.js";import{T as y,L as i,m as c}from"./index-ByMLC5eT.js";import{W as k,P as S}from"./index-CDKMALq_.js";import"./_commonjsHelpers-Cpj98o6Y.js";const r=document.getElementById("container"),s=new p,L=s.get(u),e=L.create();e.scene=new f(s);e.renderer=new k(s,r);e.camera=new g(s);s.init();e.camera.controls.setLookAt(5,5,5,0,0,0);e.scene.setup();const v=s.get(h);v.create(e);e.scene.three.background=null;const P=new w(s),A=await fetch("https://thatopen.github.io/engine_components/resources/small.frag"),C=await A.arrayBuffer(),D=new Uint8Array(C),d=P.load(D);e.scene.three.add(d);for(const t of d.children)t instanceof m&&e.meshes.add(t);const n=s.get(S);n.world=e;n.enabled=!0;r.ondblclick=()=>n.create();let l;window.addEventListener("keydown",t=>{t.code==="KeyO"?n.delete():t.code==="KeyS"?(l=n.get(),n.deleteAll()):t.code==="KeyL"&&l&&n.set(l)});const o=new b;o.showPanel(2);document.body.append(o.dom);o.dom.style.left="0px";o.dom.style.zIndex="unset";e.renderer.onBeforeUpdate.add(()=>o.begin());e.renderer.onAfterUpdate.add(()=>o.end());y.init();const a=i.create(()=>c`
+
+
+ Create dimension: Double click
+ Delete dimension: Press O
+ Delete all dimensions: Press S
+ Set/Show saved dimensions: Press L
+
+
+
+ {n.enabled=t.value}}">
+
+
+ {n.deleteAll()}}">
+
+
+
+
+ `);document.body.append(a);const x=i.create(()=>c`
+ {a.classList.contains("options-menu-visible")?a.classList.remove("options-menu-visible"):a.classList.add("options-menu-visible")}}">
+
+ `);document.body.append(x);
diff --git a/examples/assets/ifcGeometryTiler.js b/examples/assets/ifcGeometryTiler.js
index c1281093c..d2d53dd5a 100644
--- a/examples/assets/ifcGeometryTiler.js
+++ b/examples/assets/ifcGeometryTiler.js
@@ -1,16 +1,16 @@
-import"./web-ifc-api-r1ed24cU.js";import{S as w}from"./stats.min-GTpOrGrX.js";import{T as y,L as b,m as g}from"./index-ByMLC5eT.js";import{C as h,W as F,S,d as L,a as I,G as B,F as U,p as k}from"./index-4oEgnBmA.js";import"./_commonjsHelpers-Cpj98o6Y.js";const v=document.getElementById("container"),a=new h,A=a.get(F),t=A.create();t.scene=new S(a);t.renderer=new L(a,v);t.camera=new I(a);a.init();t.camera.controls.setLookAt(12,6,8,0,0,-10);t.scene.setup();const C=a.get(B);C.create(t);t.scene.three.background=null;const D=new U(a),G=await fetch("https://thatopen.github.io/engine_components/resources/small.frag"),T=await G.arrayBuffer(),R=new Uint8Array(T),j=D.load(R);t.scene.three.add(j);const r=a.get(k),x={path:"https://unpkg.com/web-ifc@0.0.66/",absolute:!0};r.settings.wasm=x;r.settings.minGeometrySize=20;r.settings.minAssetsSize=1e3;let l=[],f={},p=1;r.onGeometryStreamed.add(e=>{const{buffer:s,data:n}=e,o=`small.ifc-processed-geometries-${p}`;for(const c in n){const u=n[c];u.geometryFile=o,f[c]=u}l.push({name:o,bits:[s]}),p++});let d=[];r.onAssetStreamed.add(e=>{d=[...d,...e]});r.onIfcLoaded.add(e=>{l.push({name:"small.ifc-processed-global",bits:[e]})});function z(e,...s){const n=new File(s,e),o=document.createElement("a"),c=URL.createObjectURL(n);o.href=c,o.download=n.name,o.click(),URL.revokeObjectURL(c)}async function O(e){for(const{name:s,bits:n}of e)z(s,...n),await new Promise(o=>{setTimeout(o,100)})}r.onProgress.add(e=>{e===1&&setTimeout(async()=>{const s={geometries:f,assets:d,globalDataFileId:"small.ifc-processed-global"};l.push({name:"small.ifc-processed.json",bits:[JSON.stringify(s)]}),await O(l),d=[],f={},l=[],p=1})});async function P(){const s=await(await fetch("https://thatopen.github.io/engine_components/resources/small.ifc")).arrayBuffer(),n=new Uint8Array(s);await r.streamFromBuffer(n)}const i=new w;i.showPanel(2);document.body.append(i.dom);i.dom.style.left="0px";i.dom.style.zIndex="unset";t.renderer.onBeforeUpdate.add(()=>i.begin());t.renderer.onAfterUpdate.add(()=>i.end());y.init();const m=b.create(()=>g`
+import"./web-ifc-api-r1ed24cU.js";import{S as w}from"./stats.min-GTpOrGrX.js";import{T as y,L as b,m as g}from"./index-ByMLC5eT.js";import{C as h,W as F,S,d as L,a as I,G as B,F as U,p as k}from"./index-4oEgnBmA.js";import"./_commonjsHelpers-Cpj98o6Y.js";const v=document.getElementById("container"),a=new h,A=a.get(F),t=A.create();t.scene=new S(a);t.renderer=new L(a,v);t.camera=new I(a);a.init();t.camera.controls.setLookAt(12,6,8,0,0,-10);t.scene.setup();const G=a.get(B);G.create(t);t.scene.three.background=null;const T=new U(a),C=await fetch("https://thatopen.github.io/engine_components/resources/small.frag"),D=await C.arrayBuffer(),R=new Uint8Array(D),x=T.load(R);t.scene.three.add(x);const r=a.get(k),j={path:"https://unpkg.com/web-ifc@0.0.66/",absolute:!0};r.settings.wasm=j;r.settings.minGeometrySize=20;r.settings.minAssetsSize=1e3;let l=[],f={},p=1;r.onGeometryStreamed.add(e=>{const{buffer:s,data:n}=e,o=`small.ifc-processed-geometries-${p}`;for(const c in n){const u=n[c];u.geometryFile=o,f[c]=u}l.push({name:o,bits:[s]}),p++});let d=[];r.onAssetStreamed.add(e=>{d=[...d,...e]});r.onIfcLoaded.add(e=>{l.push({name:"small.ifc-processed-global",bits:[e]})});function z(e,...s){const n=new File(s,e),o=document.createElement("a"),c=URL.createObjectURL(n);o.href=c,o.download=n.name,o.click(),URL.revokeObjectURL(c)}async function E(e){for(const{name:s,bits:n}of e)z(s,...n),await new Promise(o=>{setTimeout(o,100)})}r.onProgress.add(e=>{e===1&&setTimeout(async()=>{const s={geometries:f,assets:d,globalDataFileId:"small.ifc-processed-global"};l.push({name:"small.ifc-processed.json",bits:[JSON.stringify(s)]}),await E(l),d=[],f={},l=[],p=1})});async function O(){const s=await(await fetch("https://thatopen.github.io/engine_components/resources/small.ifc")).arrayBuffer(),n=new Uint8Array(s);await r.streamFromBuffer(n)}const i=new w;i.showPanel(2);document.body.append(i.dom);i.dom.style.left="0px";i.dom.style.zIndex="unset";t.renderer.onBeforeUpdate.add(()=>i.begin());t.renderer.onAfterUpdate.add(()=>i.end());y.init();const m=b.create(()=>g`
- {P()}}">
+ {O()}}">
- `);document.body.append(m);const $=b.create(()=>g`
+ `);document.body.append(m);const P=b.create(()=>g`
{m.classList.contains("options-menu-visible")?m.classList.remove("options-menu-visible"):m.classList.add("options-menu-visible")}}">
- `);document.body.append($);
+ `);document.body.append(P);
diff --git a/examples/assets/ifcPropertiesTiler.js b/examples/assets/ifcPropertiesTiler.js
index e913d2311..8094f2b72 100644
--- a/examples/assets/ifcPropertiesTiler.js
+++ b/examples/assets/ifcPropertiesTiler.js
@@ -1,18 +1,18 @@
-import"./web-ifc-api-r1ed24cU.js";import{S as b}from"./stats.min-GTpOrGrX.js";import{T as g,L as f,m as u}from"./index-ByMLC5eT.js";import{C as w,W as y,S as h,d as S,a as B,G as F,F as L,o as I,I as R}from"./index-4oEgnBmA.js";import"./_commonjsHelpers-Cpj98o6Y.js";const U=document.getElementById("container"),s=new w,k=s.get(y),n=k.create();n.scene=new h(s);n.renderer=new S(s,U);n.camera=new B(s);s.init();n.camera.controls.setLookAt(12,6,8,0,0,-10);n.scene.setup();const x=s.get(F);x.create(n);n.scene.three.background=null;const v=new L(s),P=await fetch("https://thatopen.github.io/engine_components/resources/small.frag"),T=await P.arrayBuffer(),A=new Uint8Array(T),C=v.load(A);n.scene.three.add(C);function j(e,o){const t=new File([o],e),a=document.createElement("a"),p=URL.createObjectURL(t);a.href=p,a.download=t.name,a.click(),URL.revokeObjectURL(p)}async function O(e){for(const{name:o,bits:t}of e)j(o,t),await new Promise(a=>{setTimeout(a,100)})}const c=s.get(I);c.settings.wasm={path:"https://unpkg.com/web-ifc@0.0.66/",absolute:!0};const r={types:{},ids:{},indexesFile:"small.ifc-processed-properties-indexes"};let l=0;const d=[];c.onPropertiesStreamed.add(async e=>{r.types[e.type]||(r.types[e.type]=[]),r.types[e.type].push(l);for(const a in e.data)r.ids[a]=l;const o=`small.ifc-processed-properties-${l}`,t=new Blob([JSON.stringify(e.data)]);d.push({bits:t,name:o}),l++});c.onProgress.add(async e=>{console.log(e)});c.onIndicesStreamed.add(async e=>{d.push({name:"small.ifc-processed-properties.json",bits:new Blob([JSON.stringify(r)])});const t=s.get(R).serializeRelations(e);d.push({name:"small.ifc-processed-properties-indexes",bits:new Blob([t])}),await O(d)});async function z(){const o=await(await fetch("https://thatopen.github.io/engine_components/resources/small.ifc")).arrayBuffer(),t=new Uint8Array(o);await c.streamFromBuffer(t)}const i=new b;i.showPanel(2);document.body.append(i.dom);i.dom.style.left="0px";i.dom.style.zIndex="unset";n.renderer.onBeforeUpdate.add(()=>i.begin());n.renderer.onAfterUpdate.add(()=>i.end());g.init();const m=f.create(()=>u`
+import"./web-ifc-api-r1ed24cU.js";import{S as b}from"./stats.min-GTpOrGrX.js";import{T as g,L as f,m as u}from"./index-ByMLC5eT.js";import{C as y,W as w,S as h,d as S,a as B,G as F,F as I,o as L,I as x}from"./index-4oEgnBmA.js";import"./_commonjsHelpers-Cpj98o6Y.js";const R=document.getElementById("container"),s=new y,U=s.get(w),n=U.create();n.scene=new h(s);n.renderer=new S(s,R);n.camera=new B(s);s.init();n.camera.controls.setLookAt(12,6,8,0,0,-10);n.scene.setup();const k=s.get(F);k.create(n);n.scene.three.background=null;const P=new I(s),T=await fetch("https://thatopen.github.io/engine_components/resources/small.frag"),v=await T.arrayBuffer(),A=new Uint8Array(v),C=P.load(A);n.scene.three.add(C);function j(e,o){const t=new File([o],e),a=document.createElement("a"),p=URL.createObjectURL(t);a.href=p,a.download=t.name,a.click(),URL.revokeObjectURL(p)}async function O(e){for(const{name:o,bits:t}of e)j(o,t),await new Promise(a=>{setTimeout(a,100)})}const c=s.get(L);c.settings.wasm={path:"https://unpkg.com/web-ifc@0.0.66/",absolute:!0};const r={types:{},ids:{},indexesFile:"small.ifc-processed-properties-indexes"};let l=0;const d=[];c.onPropertiesStreamed.add(async e=>{r.types[e.type]||(r.types[e.type]=[]),r.types[e.type].push(l);for(const a in e.data)r.ids[a]=l;const o=`small.ifc-processed-properties-${l}`,t=new Blob([JSON.stringify(e.data)]);d.push({bits:t,name:o}),l++});c.onProgress.add(async e=>{console.log(e)});c.onIndicesStreamed.add(async e=>{d.push({name:"small.ifc-processed-properties.json",bits:new Blob([JSON.stringify(r)])});const t=s.get(x).serializeRelations(e);d.push({name:"small.ifc-processed-properties-indexes",bits:new Blob([t])}),await O(d)});async function z(){const o=await(await fetch("https://thatopen.github.io/engine_components/resources/small.ifc")).arrayBuffer(),t=new Uint8Array(o);await c.streamFromBuffer(t)}const i=new b;i.showPanel(2);document.body.append(i.dom);i.dom.style.left="0px";i.dom.style.zIndex="unset";n.renderer.onBeforeUpdate.add(()=>i.begin());n.renderer.onAfterUpdate.add(()=>i.end());g.init();const m=f.create(()=>u`
- {z()}}">
- `);document.body.append(m);const $=f.create(()=>u`
+ `);document.body.append(m);const E=f.create(()=>u`
{m.classList.contains("options-menu-visible")?m.classList.remove("options-menu-visible"):m.classList.add("options-menu-visible")}}">
- `);document.body.append($);
+ `);document.body.append(E);
diff --git a/examples/assets/volumeMeasurement.js b/examples/assets/volumeMeasurement.js
index e506871a1..1212bba2c 100644
--- a/examples/assets/volumeMeasurement.js
+++ b/examples/assets/volumeMeasurement.js
@@ -1 +1,20 @@
-import"./web-ifc-api-r1ed24cU.js";import{S as c}from"./stats.min-GTpOrGrX.js";import{C as d,W as m,S as l,a as i,G as g,F as p}from"./index-4oEgnBmA.js";import{W as f,O as u,L as w}from"./index-CDKMALq_.js";import"./_commonjsHelpers-Cpj98o6Y.js";const h=document.getElementById("container"),t=new d,b=t.get(m),e=b.create();e.scene=new l(t);e.renderer=new f(t,h);e.camera=new i(t);t.init();e.camera.controls.setLookAt(5,5,5,0,0,0);e.scene.setup();const y=t.get(g);y.create(e);e.scene.three.background=null;const S=new p(t),C=await fetch("https://thatopen.github.io/engine_components/resources/small.frag"),F=await C.arrayBuffer(),W=new Uint8Array(F),v=S.load(W);e.scene.three.add(v);const o=t.get(u);o.world=e;o.enabled=!0;const s=t.get(w);s.setup({world:e});s.events.select.onHighlight.add(a=>{const r=o.getVolumeFromFragments(a);console.log(r)});s.events.select.onClear.add(()=>{o.clear()});const n=new c;n.showPanel(2);document.body.append(n.dom);n.dom.style.left="0px";n.dom.style.zIndex="unset";e.renderer.onBeforeUpdate.add(()=>n.begin());e.renderer.onAfterUpdate.add(()=>n.end());
+import"./web-ifc-api-r1ed24cU.js";import{S as m}from"./stats.min-GTpOrGrX.js";import{C as d,W as b,S as p,a as u,G as g,F as f}from"./index-4oEgnBmA.js";import{T as h,L as l,m as i}from"./index-ByMLC5eT.js";import{W as w,O as L,L as v}from"./index-CDKMALq_.js";import"./_commonjsHelpers-Cpj98o6Y.js";const y=document.getElementById("container"),t=new d,k=t.get(b),e=k.create();e.scene=new p(t);e.renderer=new w(t,y);e.camera=new u(t);t.init();e.camera.controls.setLookAt(5,5,5,0,0,0);e.scene.setup();const C=t.get(g);C.create(e);e.scene.three.background=null;const S=new f(t),F=await fetch("https://thatopen.github.io/engine_components/resources/small.frag"),W=await F.arrayBuffer(),A=new Uint8Array(W),B=S.load(A);e.scene.three.add(B);const o=t.get(L);o.world=e;o.enabled=!0;const a=t.get(v);a.setup({world:e});a.events.select.onHighlight.add(r=>{const c=o.getVolumeFromFragments(r);console.log(c)});a.events.select.onClear.add(()=>{o.clear()});const n=new m;n.showPanel(2);document.body.append(n.dom);n.dom.style.left="0px";n.dom.style.zIndex="unset";e.renderer.onBeforeUpdate.add(()=>n.begin());e.renderer.onAfterUpdate.add(()=>n.end());h.init();const s=l.create(()=>i`
+
+
+ Create dimension: Left click
+ Delete dimension: Left click el
+
+
+
+
+ {o.clear(),a.clear()}}">
+
+
+
+
+ `);document.body.append(s);const O=l.create(()=>i`
+ {s.classList.contains("options-menu-visible")?s.classList.remove("options-menu-visible"):s.classList.add("options-menu-visible")}}">
+
+ `);document.body.append(O);
diff --git a/packages/core/src/fragments/IfcGeometryTiler/example.ts b/packages/core/src/fragments/IfcGeometryTiler/example.ts
index a263b5879..12359f285 100644
--- a/packages/core/src/fragments/IfcGeometryTiler/example.ts
+++ b/packages/core/src/fragments/IfcGeometryTiler/example.ts
@@ -323,7 +323,7 @@ const panel = BUI.Component.create(() => {
- {
processFile();
}}">
diff --git a/packages/core/src/fragments/IfcPropertiesTiler/example.ts b/packages/core/src/fragments/IfcPropertiesTiler/example.ts
index c1776f829..d8d50dabd 100644
--- a/packages/core/src/fragments/IfcPropertiesTiler/example.ts
+++ b/packages/core/src/fragments/IfcPropertiesTiler/example.ts
@@ -262,7 +262,7 @@ const panel = BUI.Component.create(() => {
- {
processFile();
}}">
diff --git a/packages/front/src/measurement/AngleMeasurement/example.ts b/packages/front/src/measurement/AngleMeasurement/example.ts
index 3969cf5e3..aa535c827 100644
--- a/packages/front/src/measurement/AngleMeasurement/example.ts
+++ b/packages/front/src/measurement/AngleMeasurement/example.ts
@@ -14,6 +14,7 @@ We will import:
import * as THREE from "three";
import * as OBC from "@thatopen/components";
+import * as BUI from "@thatopen/ui";
import * as OBCF from "@thatopen/components-front";
import Stats from "stats.js";
@@ -94,7 +95,7 @@ container.ondblclick = () => angles.create();
### ๐งน Deleting the Dimensions
---
- Now that we know how to make multiple dimensions, we'll learn how to delete them when necessary. Dimensions can be removed using the `deleteAll()` method, which deletes all the created dimensions. Again, we'll keep it simple and bind this event to the keydown event. Specifically, it will fire when the user presses the `Delete` or `Backspace` key.
+ Now that we know how to make multiple angle, we'll learn how to delete them when necessary. angle can be removed using the `deleteAll()` method, which deletes all the created angle. Again, we'll keep it simple and bind this event to the keydown event. Specifically, it will fire when the user presses the `Delete` or `Backspace` key.
*/
window.onkeydown = (event) => {
@@ -118,6 +119,67 @@ stats.dom.style.zIndex = "unset";
world.renderer.onBeforeUpdate.add(() => stats.begin());
world.renderer.onAfterUpdate.add(() => stats.end());
+/* MD
+ ### ๐งฉ Adding some UI
+ ---
+
+ We will use the `@thatopen/ui` library to add some simple and cool UI elements to our app. First, we need to call the `init` method of the `BUI.Manager` class to initialize the library:
+*/
+
+BUI.Manager.init();
+
+/* MD
+Now we will add some UI to have some control over the angles we create. For more information about the UI library, you can check the specific documentation for it!
+*/
+
+const panel = BUI.Component.create(() => {
+ return BUI.html`
+
+
+ Create angle: Double click
+ Delete angle: Delete
+
+
+
+ {
+ angles.enabled = target.value;
+ }}">
+
+
+ {
+ angles.deleteAll();
+ }}">
+
+
+
+
+ `;
+});
+
+document.body.append(panel);
+
+/* MD
+ And we will make some logic that adds a button to the screen when the user is visiting our app from their phone, allowing to show or hide the menu. Otherwise, the menu would make the app unusable.
+*/
+
+const button = BUI.Component.create(() => {
+ return BUI.html`
+ {
+ if (panel.classList.contains("options-menu-visible")) {
+ panel.classList.remove("options-menu-visible");
+ } else {
+ panel.classList.add("options-menu-visible");
+ }
+ }}">
+
+ `;
+});
+
+document.body.append(button);
+
/* MD
### ๐ Wrap up
---
diff --git a/packages/front/src/measurement/AreaMeasurement/example.ts b/packages/front/src/measurement/AreaMeasurement/example.ts
index 6ff60ccd4..9c076d08a 100644
--- a/packages/front/src/measurement/AreaMeasurement/example.ts
+++ b/packages/front/src/measurement/AreaMeasurement/example.ts
@@ -14,6 +14,7 @@ We will import:
import Stats from "stats.js";
import * as OBC from "@thatopen/components";
+import * as BUI from "@thatopen/ui";
import * as THREE from "three";
import * as OBCF from "@thatopen/components-front";
@@ -119,6 +120,73 @@ stats.dom.style.zIndex = "unset";
world.renderer.onBeforeUpdate.add(() => stats.begin());
world.renderer.onAfterUpdate.add(() => stats.end());
+/* MD
+ ### ๐งฉ Adding some UI
+ ---
+
+ We will use the `@thatopen/ui` library to add some simple and cool UI elements to our app. First, we need to call the `init` method of the `BUI.Manager` class to initialize the library:
+*/
+
+BUI.Manager.init();
+
+/* MD
+Now we will add some UI to have some control over the dimensions we create. For more information about the UI library, you can check the specific documentation for it!
+*/
+
+const panel = BUI.Component.create(() => {
+ return BUI.html`
+
+
+ Create area dimension: Double click
+ Calculate selected area: Right click
+ Delete dimension: Delete
+
+
+
+ {
+ areaDims.enabled = target.value;
+ }}">
+
+ {
+ areaDims.visible = target.value;
+ }}">
+
+
+ {
+ areaDims.deleteAll();
+ }}">
+
+
+
+
+ `;
+});
+
+document.body.append(panel);
+
+/* MD
+ And we will make some logic that adds a button to the screen when the user is visiting our app from their phone, allowing to show or hide the menu. Otherwise, the menu would make the app unusable.
+*/
+
+const button = BUI.Component.create(() => {
+ return BUI.html`
+ {
+ if (panel.classList.contains("options-menu-visible")) {
+ panel.classList.remove("options-menu-visible");
+ } else {
+ panel.classList.add("options-menu-visible");
+ }
+ }}">
+
+ `;
+});
+
+document.body.append(button);
+
/* MD
### ๐ Wrap up
---
diff --git a/packages/front/src/measurement/EdgeMeasurement/example.ts b/packages/front/src/measurement/EdgeMeasurement/example.ts
index bce8d0295..cc88ff252 100644
--- a/packages/front/src/measurement/EdgeMeasurement/example.ts
+++ b/packages/front/src/measurement/EdgeMeasurement/example.ts
@@ -15,6 +15,7 @@ We will import:
import Stats from "stats.js";
import * as THREE from "three";
import * as OBC from "@thatopen/components";
+import * as BUI from "@thatopen/ui";
import * as OBCF from "@thatopen/components-front";
/* MD
@@ -144,6 +145,49 @@ stats.dom.style.zIndex = "unset";
world.renderer.onBeforeUpdate.add(() => stats.begin());
world.renderer.onAfterUpdate.add(() => stats.end());
+/* MD
+ ### ๐งฉ Adding some UI
+ ---
+
+ We will use the `@thatopen/ui` library to add some simple and cool UI elements to our app. First, we need to call the `init` method of the `BUI.Manager` class to initialize the library:
+*/
+
+BUI.Manager.init();
+
+/* MD
+Now we will add some UI to have some control over the dimensions we create. For more information about the UI library, you can check the specific documentation for it!
+*/
+
+const panel = BUI.Component.create(() => {
+ return BUI.html`
+
+
+ Create dimension: Double click
+ Delete dimension: Press O
+ Delete all dimensions: Press S
+ Set/Show saved dimensions: Press L
+
+
+
+ {
+ dimensions.enabled = target.value;
+ }}">
+
+
+ {
+ dimensions.deleteAll();
+ }}">
+
+
+
+
+ `;
+});
+
+document.body.append(panel);
+
/* MD
### ๐ Wrap up
---
diff --git a/packages/front/src/measurement/FaceMeasurement/example.ts b/packages/front/src/measurement/FaceMeasurement/example.ts
index a83e1d8b1..7b6c5b264 100644
--- a/packages/front/src/measurement/FaceMeasurement/example.ts
+++ b/packages/front/src/measurement/FaceMeasurement/example.ts
@@ -15,6 +15,7 @@ We will import:
import Stats from "stats.js";
import * as THREE from "three";
import * as OBC from "@thatopen/components";
+import * as BUI from "@thatopen/ui";
import * as OBCF from "@thatopen/components-front";
/* MD
@@ -144,6 +145,69 @@ stats.dom.style.zIndex = "unset";
world.renderer.onBeforeUpdate.add(() => stats.begin());
world.renderer.onAfterUpdate.add(() => stats.end());
+/* MD
+ ### ๐งฉ Adding some UI
+ ---
+
+ We will use the `@thatopen/ui` library to add some simple and cool UI elements to our app. First, we need to call the `init` method of the `BUI.Manager` class to initialize the library:
+*/
+
+BUI.Manager.init();
+
+/* MD
+Now we will add some UI to have some control over the dimensions we create. For more information about the UI library, you can check the specific documentation for it!
+*/
+
+const panel = BUI.Component.create(() => {
+ return BUI.html`
+
+
+ Create dimension: Double click
+ Delete dimension: Press O
+ Delete all dimensions: Press S
+ Set/Show saved dimensions: Press L
+
+
+
+ {
+ dimensions.enabled = target.value;
+ }}">
+
+
+ {
+ dimensions.deleteAll();
+ }}">
+
+
+
+
+ `;
+});
+
+document.body.append(panel);
+
+/* MD
+ And we will make some logic that adds a button to the screen when the user is visiting our app from their phone, allowing to show or hide the menu. Otherwise, the menu would make the app unusable.
+*/
+
+const button = BUI.Component.create(() => {
+ return BUI.html`
+ {
+ if (panel.classList.contains("options-menu-visible")) {
+ panel.classList.remove("options-menu-visible");
+ } else {
+ panel.classList.add("options-menu-visible");
+ }
+ }}">
+
+ `;
+});
+
+document.body.append(button);
+
/* MD
### ๐ Wrap up
---
diff --git a/packages/front/src/measurement/VolumeMeasurement/example.ts b/packages/front/src/measurement/VolumeMeasurement/example.ts
index 8246ce792..2600a1c5e 100644
--- a/packages/front/src/measurement/VolumeMeasurement/example.ts
+++ b/packages/front/src/measurement/VolumeMeasurement/example.ts
@@ -13,6 +13,7 @@ We will import:
import Stats from "stats.js";
import * as OBC from "@thatopen/components";
+import * as BUI from "@thatopen/ui";
import * as OBCF from "@thatopen/components-front";
/* MD
@@ -132,6 +133,63 @@ stats.dom.style.zIndex = "unset";
world.renderer.onBeforeUpdate.add(() => stats.begin());
world.renderer.onAfterUpdate.add(() => stats.end());
+/* MD
+ ### ๐งฉ Adding some UI
+ ---
+
+ We will use the `@thatopen/ui` library to add some simple and cool UI elements to our app. First, we need to call the `init` method of the `BUI.Manager` class to initialize the library:
+*/
+
+BUI.Manager.init();
+
+/* MD
+Now we will add some UI to have some control over the dimensions we create. For more information about the UI library, you can check the specific documentation for it!
+*/
+
+const panel = BUI.Component.create(() => {
+ return BUI.html`
+
+
+ Create dimension: Left click
+ Delete dimension: Left click el
+
+
+
+
+ {
+ dimensions.clear();
+ highlighter.clear();
+ }}">
+
+
+
+
+ `;
+});
+
+document.body.append(panel);
+
+/* MD
+ And we will make some logic that adds a button to the screen when the user is visiting our app from their phone, allowing to show or hide the menu. Otherwise, the menu would make the app unusable.
+*/
+
+const button = BUI.Component.create(() => {
+ return BUI.html`
+ {
+ if (panel.classList.contains("options-menu-visible")) {
+ panel.classList.remove("options-menu-visible");
+ } else {
+ panel.classList.add("options-menu-visible");
+ }
+ }}">
+
+ `;
+});
+
+document.body.append(button);
+
/* MD
### ๐ Wrap up
---