@giro3d/piero 1.0.0-beta.3 → 1.0.0-beta.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.
- package/dist/Components.cjs.js +3 -2
- package/dist/Components.cjs.js.map +1 -1
- package/dist/Components.es.js +3193 -1776
- package/dist/Components.es.js.map +1 -1
- package/dist/assets/piero.css +1 -1
- package/dist/index.cjs.js +7 -7
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.es.js +3041 -4078
- package/dist/index.es.js.map +1 -1
- package/dist/modules.cjs.js +1 -2
- package/dist/modules.cjs.js.map +1 -1
- package/dist/modules.es.js +732 -900
- package/dist/modules.es.js.map +1 -1
- package/dist/src/api/ViewApi.d.ts +2 -0
- package/dist/src/components/CoordinateInput.vue.d.ts +31 -0
- package/dist/src/modules/crossSectionAnalysis/CrossSection.vue.d.ts +1 -1
- package/dist/src/modules/crossSectionAnalysis/CrossSectionHelper.d.ts +4 -0
- package/dist/src/modules/crossSectionAnalysis/CrossSectionManager.d.ts +7 -0
- package/dist/src/modules/crossSectionAnalysis/store.d.ts +22 -2
- package/dist/src/services/CameraController.d.ts +3 -3
- package/dist/src/services/Giro3DManager.d.ts +2 -0
- package/dist/src/services/SceneCursorManager.d.ts +19 -0
- package/dist/src/utils/Types.d.ts +1 -0
- package/package.json +1 -1
package/dist/modules.cjs.js
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
"use strict";var J=Object.defineProperty;var Q=(a,t,e)=>t in a?J(a,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):a[t]=e;var h=(a,t,e)=>Q(a,typeof t!="symbol"?t+"":t,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const d=require("./Components.cjs.js"),r=require("vue"),q=require("pinia"),O=require("@giro3d/giro3d/core/geographic/Coordinates"),j=require("@giro3d/giro3d/entities/Entity3D"),K=require("@giro3d/giro3d/utils/Fetcher"),ee=require("@giro3d/giro3d/gui/EntityPanel"),B=require("openbim-components"),te=require("@giro3d/giro3d/gui/EntityInspector"),$=require("ol"),ne=require("ol/layer/Tile"),G=require("ol/proj"),se=require("ol/source"),oe=require("@giro3d/giro3d/entities/PointCloud"),ie=require("@giro3d/giro3d/sources/PotreeSource"),N=require("shepherd.js"),Y=q.defineStore("crossSection",()=>{const a=r.ref(0),t=r.ref(new d.Vector3(0,0,0)),e=r.ref(!1);function n(s){e.value=s}function o(s){a.value=s}function i(s){t.value=s}return{center:t,enable:e,orientation:a,setCenter:i,setEnabled:n,setOrientation:o}}),re={class:"input-group mb-3"},ae={class:"input-group mb-3"},le=["value"],ce={class:"input-group mb-3"},ue=["value"],de={class:"input-group"},pe={class:"input-group"},me=["value"],he=["value"],fe=r.defineComponent({__name:"CrossSection",setup(a){const t=Y();function e(i){t.setOrientation(i)}function n(i){const s=t.center.clone();s.setX(i),t.setCenter(s)}function o(i){const s=t.center.clone();s.setY(i),t.setCenter(s)}return(i,s)=>(r.openBlock(),r.createElementBlock("div",null,[r.createElementVNode("div",re,[r.createVNode(d._sfc_main,{"model-value":r.unref(t).enable,"onUpdate:modelValue":s[0]||(s[0]=c=>r.unref(t).setEnabled(c)),id:"cross-section-enable",title:"foo"},null,8,["model-value"]),s[5]||(s[5]=r.createElementVNode("label",{for:"cross-section-enable",class:"form-label"},"Enable cross section",-1))]),r.createElementVNode("div",ae,[s[6]||(s[6]=r.createElementVNode("label",{for:"plane-orientation-range",class:"form-label"},"Plane orientation (0-360°)",-1)),r.createElementVNode("input",{id:"plane-orientation-range",title:"Altitude",type:"range",class:"form-range",min:"0",step:"0.1",max:"360",value:r.unref(t).orientation,onInput:s[1]||(s[1]=c=>e(Number.parseFloat(c.target.value)))},null,40,le)]),r.createElementVNode("div",ce,[r.createElementVNode("input",{type:"number",class:"form-control",id:"plane-orientation-number",step:"0.1",value:r.unref(t).orientation,onInput:s[2]||(s[2]=c=>e(Number.parseFloat(c.target.value)))},null,40,ue)]),s[8]||(s[8]=r.createElementVNode("hr",null,null,-1)),r.createElementVNode("div",de,[s[7]||(s[7]=r.createElementVNode("label",{class:"form-label"},"Center (x, y)",-1)),r.createElementVNode("div",pe,[r.createElementVNode("input",{type:"number",class:"form-control",id:"plane-center-x",value:r.unref(t).center.x,onInput:s[3]||(s[3]=c=>n(Number.parseFloat(c.target.value)))},null,40,me),r.createElementVNode("input",{type:"number",class:"form-control",id:"plane-center-y",value:r.unref(t).center.y,onInput:s[4]||(s[4]=c=>o(Number.parseFloat(c.target.value)))},null,40,he)])])]))}});class ge{constructor(t){h(this,"_store",Y());this.context=t,t.events.addEventListener("ready",()=>{const e=t.configuration.default_crs,n=t.configuration.analysis.cross_section;this._store.setOrientation(n.orientation);const o=n.pivot,i=new O(o.crs??e,o.x,o.y,0).as(e);this._store.setCenter(i.toVector3()),this._store.$onAction(({after:s,name:c})=>{s(()=>{switch(c){case"setCenter":case"setEnabled":case"setOrientation":this.updateCrossSection();break}})}),this.updateCrossSection()})}dispose(){}updateCrossSection(){const t=[];if(this._store.enable){const n=d.MathUtils.DEG2RAD*this._store.orientation,o=Math.cos(n),i=Math.sin(n),s=new d.Vector3(o,i,0),c=new d.Plane(s,0).distanceToPoint(this._store.center),y=new d.Plane(s,-c);t.push(y)}const e=this.context.view.getInstance();e.renderer.clippingPlanes=t;for(const n of this.context.view.getInstance().getEntities())j.isEntity3D(n)&&n.dispatchEvent({clippingPlanes:t,type:"clippingPlanes-property-changed"});e.notifyChange()}}class ye{constructor(){h(this,"id","builtin-cross-section-analysis");h(this,"name","Cross section");h(this,"_manager",null)}initialize(t){t.analysis.registerTool({component:fe,icon:"bi-circle-half",name:"Cross section"}),this._manager=new ge(t)}}function R(a){if("url"in a.config&&typeof a.config.url=="string")return a.config.url;if("source"in a.config&&typeof a.config.source=="object"&&"url"in a.config.source&&typeof a.config.source.url=="string")return a.config.source.url}function be(a){return R(a)!=null}class ve{constructor(){h(this,"id","builtin-download-dataset");h(this,"name","Download dataset");h(this,"_context",null)}initialize(t){this._context=t,t.datasets.registerDatasetAction({action:this.download.bind(this),icon:"bi-download",predicate:be,title:"Download dataset"})}download(t){const e=R(t);if(e==null){console.warn("invalid");return}const n=this._context,o=new URL(e).pathname.split("/"),i=o[o.length-1];console.info(`download ${R(t)}`),d.Fetcher.fetch(e).then(s=>{if(!s.ok)throw new Error(`${s.status} ${s.statusText}`);return s.blob()}).then(s=>{d.Download.downloadBlob(s,i),n.notifications.pushNotification({level:"success",text:i,title:"Download successful"})}).catch(s=>{console.error(s);const c=s instanceof Error?s.message:"Download failed";n.notifications.pushNotification({level:"error",text:c,title:t.name})})}}const H=q.defineStore("floodingPlane",()=>{const a=r.ref(0),t=r.ref(!1);function e(){return a.value}function n(i){a.value=i}function o(i){t.value=i}return{enable:t,getHeight:e,setEnabled:o,setHeight:n}}),_e={class:"input-group mb-3"},we={class:"input-group mb-3"},xe=["value"],Ce={class:"input-group mb-3"},Pe=["value"],Ie=r.defineComponent({__name:"FloodingPlane",setup(a){const t=H();function e(n){t.setHeight(n)}return(n,o)=>(r.openBlock(),r.createElementBlock(r.Fragment,null,[r.createElementVNode("div",_e,[r.createVNode(d._sfc_main,{"model-value":r.unref(t).enable,"onUpdate:modelValue":o[0]||(o[0]=i=>r.unref(t).setEnabled(i)),id:"flooding-plane-enable",title:"foo"},null,8,["model-value"]),o[3]||(o[3]=r.createElementVNode("label",{for:"flooding-plane-enable",class:"form-label"},"Enable flooding plane",-1))]),r.createElementVNode("div",we,[o[5]||(o[5]=r.createElementVNode("label",{for:"flooding-altitude-range",class:"form-label"},"Altitude",-1)),r.createElementVNode("input",{id:"flooding-altitude-range",title:"Altitude",type:"range",class:"form-range",min:"0",step:"0.1",max:"500",value:r.unref(t).getHeight(),onInput:o[1]||(o[1]=i=>e(Number.parseFloat(i.target.value)))},null,40,xe),r.createElementVNode("div",Ce,[r.createElementVNode("input",{type:"number",class:"form-control",id:"flooding-altitude-number",step:"0.1",value:r.unref(t).getHeight(),onInput:o[2]||(o[2]=i=>e(Number.parseFloat(i.target.value)))},null,40,Pe),o[4]||(o[4]=r.createElementVNode("span",{class:"input-group-text"},"m",-1))])])],64))}});class Se{constructor(){h(this,"geometry");h(this,"material");h(this,"object3D");h(this,"_height");this.geometry=new d.PlaneGeometry(1,1,1,1),this.material=new d.MeshBasicMaterial({color:43690,opacity:.5,transparent:!0}),this.object3D=new d.Mesh(this.geometry,this.material),this.object3D.renderOrder=2,this.visible=!1,this._height=0}set height(t){this._height=t}get height(){return this._height}set visible(t){this.object3D.visible=t}get visible(){return this.object3D.visible}dispose(){this.object3D.removeFromParent(),this.geometry.dispose(),this.material.dispose()}setPosition(t,e,n,o,i){this.object3D.scale.set(o,i,1),this.object3D.position.set(t,e,n),this.object3D.updateMatrixWorld()}}class Ee{constructor(t){h(this,"_context");h(this,"_plane");h(this,"_store",H());this._context=t,this._plane=null,t.events.addEventListener("ready",()=>{this._store.$onAction(({after:e,name:n})=>{e(()=>{switch(n){case"setEnabled":this.updatePlane();break;case"setHeight":this.updatePlane();break}})})})}dispose(){this._plane&&(this._context.view.getInstance().remove(this._plane.object3D),this._plane.dispose())}async updatePlane(){this._plane||(this._plane=new Se,await this._context.view.getInstance().add(this._plane.object3D));const t=this._context.view.getBoundingBox(),e=t.getCenter(new d.Vector3),n=t.getSize(new d.Vector3);this._plane.visible=this._store.enable,this._plane.setPosition(e.x,e.y,this._store.getHeight(),n.x,n.y),this._context.view.getInstance().notifyChange()}}class Be{constructor(){h(this,"id","builtin-flooding-plane-analysis");h(this,"name","Flooding plane");h(this,"_manager",null)}initialize(t){t.analysis.registerTool({component:Ie,icon:"bi-layers-half",name:"Flooding plane"}),this._manager=new Ee(t)}}const Te=/^(\d+\.\d+)\s*,\s*(\d+\.\d+)$/;class Fe{constructor(){h(this,"name","Go to coordinates")}search(t){const e=Te.exec(t);if(e){const n=Number.parseFloat(e[1]),o=Number.parseFloat(e[2]),s={coordinates:O.WGS84(n,o),label:`${n.toFixed(6)}, ${o.toFixed(6)}`,provider:this};return Promise.resolve([s])}else return Promise.resolve([])}}class Ne{constructor(){h(this,"id","builtin-coordinates-search");h(this,"name","Coordinates search")}initialize(t){t.search.registerProvider(new Fe)}}const ke=/[a-z]{3}/;class Le{constructor(){h(this,"name","Base adresse nationale (BAN)")}async search(t){if(!ke.test(t))return[];try{const n=(await d.Fetcher.fetchJson(`https://api-adresse.data.gouv.fr/search/?q=${t}`)).features.map(o=>{const i=o.properties,s=o.geometry,[c,y]=s.coordinates;return{coordinates:new O("EPSG:4326",c,y,0),label:i.label,provider:this}});return await Me(n.map(o=>o.coordinates)),n}catch(e){if(e instanceof K.HttpError)return[];throw e}}}async function Me(a){const t=new URL("https://data.geopf.fr/altimetrie/1.0/calcul/alti/rest/elevation.json");t.searchParams.append("lon",a.map(n=>n.longitude).join("|")),t.searchParams.append("lat",a.map(n=>n.latitude).join("|")),t.searchParams.append("zonly","true"),t.searchParams.append("resource","ign_rge_alti_wld"),t.searchParams.append("delimiter","|"),t.searchParams.append("indent","false");const e=await d.Fetcher.fetchJson(t.toString());for(let n=0;n<a.length;n++)a[n].setAltitude(e.elevations[n]);return e}class De{constructor(){h(this,"id","builtin-geocoding-ban");h(this,"name","Base adresse nationale")}initialize(t){t.search.registerProvider(new Le)}}const M=new d.Matrix4,Ve={bbox:new d.MeshBasicMaterial({color:"#FFFF00",depthTest:!0,opacity:.2,transparent:!0}),selection:new d.MeshBasicMaterial({color:"#FF0000",depthTest:!1,opacity:.6,transparent:!0})},Ae=4186316022,ze=781010003,Oe=2655215786,je=3242617779,Re=919958153,Ue=1307041759,W=1451395588,Z=1883228015,$e=[W,Z],Ge=[Ae,ze,Oe,je,Re,Ue],X=a=>d.isObject(a)&&a.isIFCPickResult,D=class D extends j{constructor(e){super(new d.Group);h(this,"isIfcEntity",!0);h(this,"isPickableFeatures",!0);h(this,"type","IfcEntity");h(this,"_classificationCache");h(this,"_components");h(this,"_fragmentBoundingBox");h(this,"_fragmentClassifier");h(this,"_fragmentManager");h(this,"_ifcSelection");h(this,"_indexMap");h(this,"_model");h(this,"_source");this._source=e,this._components=new B.Components,this._components.ui.enabled=!1,this._components.scene=new B.SimpleScene(this._components),this._components.renderer=new B.SimpleRenderer(this._components,document.createElement("div")),this._components.camera=new B.SimpleCamera(this._components),this._components.raycaster=new B.SimpleRaycaster(this._components),this._components.init(),this._ifcSelection={bbox:{},selection:{}},this._indexMap={},this._classificationCache=null,this._fragmentBoundingBox=null}clearHighlight(e="selection"){for(const n of Object.keys(this._ifcSelection[e])){const o=this._fragmentManager.list[n],i=o==null?void 0:o.fragments[e];i!=null&&i.mesh.removeFromParent()}this.notifyChange(this),this._ifcSelection[e]={}}getBoundingBoxById(e){this.clearHighlight("bbox"),this.highlightById(e,"bbox");const n=this._fragmentBoundingBox;if(n===null)throw new Error("Must call initClassification before getBoundingBoxById");const o=this._fragmentManager;n.reset();const i=this._ifcSelection.bbox;if(!Object.keys(i).length)return;for(const f of Object.keys(i)){const S=o.list[f].fragments.bbox;n.addMesh(S.mesh)}const s=n.get(),{y:c,z:y}=s.min,{y:w,z:u}=s.max;return s.min.y=-u,s.max.y=-y,s.min.z=c,s.max.z=w,s.translate(this._model.position),this.clearHighlight("bbox"),s}getClassification(){if(this._classificationCache===null)throw new Error("Must call initClassification before getClassification");return this._classificationCache}getProperties(e){const n=[],o=this._model.properties;if(!o)return[];for(const i of this._indexMap[e]){const s=o[i];if(s==null)continue;const{name:c}=B.IfcPropertiesUtils.getEntityName(o,i);if(c!==null){if(s.type===W){const y=B.IfcPropertiesUtils.getPsetProps(o,i);if(y!==null)for(const w of y){if(o[w]==null)continue;const f=this.getProperty(w);f!==null&&n.push({parentName:c,...f})}}else if(s.type===Z){const y=B.IfcPropertiesUtils.getQsetQuantities(o,i);if(y!==null)for(const w of y){const{key:u}=B.IfcPropertiesUtils.getQuantityValue(o,w);if(u===null)continue;const f=this.getProperty(w);f!==null&&n.push({parentName:c,...f})}}}}return n}getProperty(e){const n=this._model.properties;if(n===void 0)return null;const{name:o}=B.IfcPropertiesUtils.getEntityName(n,e);if(o===null)return null;const{value:i}=B.IfcPropertiesUtils.getQuantityValue(n,e);return{name:o,value:i}}highlight(e,n,o){this._ifcSelection[e][n.uuid]=new Set;const i=parseInt(o,10);this._ifcSelection[e][n.uuid].add(o),this.addComposites(e,n,i),this.regenerate(e,n.uuid);const s=n.fragment.group;if(s){const c=s.data[i][0];for(let y=0;y<c.length;y++){const w=c[y],u=s.keyFragments[w],f=this._fragmentManager.list[u];u in this._ifcSelection[e]||(this._ifcSelection[e][u]=new Set),this._ifcSelection[e][u].add(o),this.addComposites(e,f.mesh,i),this.regenerate(e,u)}}this.notifyChange(this)}highlightById(e,n="selection"){for(const o of Object.keys(e)){o in this._ifcSelection[n]||(this._ifcSelection[n][o]=new Set);const i=this._fragmentManager.list[o],s=new Set;for(const c of e[o])this._ifcSelection[n][o].add(c),s.add(parseInt(c,10));for(const c of s)this.addComposites(n,i.mesh,c);this.regenerate(n,o)}this.notifyChange(this)}pick(e,n){return super.pick(e,n).map(o=>({...o,entity:this,features:o.features,isIFCPickResult:!0,object:o.object}))}pickFeaturesFrom(e){var o,i,s;const n=e.object;if(n.fragment!=null&&e.instanceId!=null&&e.face){const c=n.fragment.getVertexBlockID(n.geometry,e.face.a),y=(o=n.fragment.getItemID(e.instanceId,c))==null?void 0:o.replace(/\..*/,"");if(y&&((s=(i=n.fragment.group)==null?void 0:i.properties)==null?void 0:s[y])!=null){const u=n.fragment.group.properties[y],C=[{ifcProperties:this.getProperties(y),itemProperties:u}];return e.features=C,C}}return[]}async initClassification(){this._classificationCache=await this.regenerateClassification(["storeys","entities"]),this._classificationCache.length===0&&(this._classificationCache=await this.regenerateClassification(["entities"])),this._fragmentBoundingBox=await this._components.tools.get(B.FragmentBoundingBox)}async preprocess(){const e=await d.Fetcher.fetchArrayBuffer(this._source.url);this._fragmentManager=await this._components.tools.get(B.FragmentManager),this._fragmentClassifier=await this._components.tools.get(B.FragmentClassifier);const n=new B.FragmentIfcLoader(this._components);n.settings.webIfc.COORDINATE_TO_ORIGIN=!0,n.settings.webIfc.OPTIMIZE_PROFILES=!0;const o=new Uint8Array(e);this._model=await n.load(o,this._source.name),this._model.rotateX(Math.PI/2);const i=new d.Vector3;if(this._source.at)this._source.at.toVector3(i),this._model.position.copy(i);else{const c=this._model.coordinationMatrix.clone().invert();i.applyMatrix4(c),this._model.position.set(i.x,-i.z,i.y)}this._model.updateWorldMatrix(!0,!0),this._model.updateMatrix(),this._model.updateMatrixWorld(!0),this.initializeEntityIndexes(),this._fragmentClassifier.byStorey(this._model),this._fragmentClassifier.byEntity(this._model),await this.initClassification(),this.object3d.add(this._model),this.onObjectCreated(this._model);const s=d.Fetcher.getContext(this._source.url);d.fillObject3DUserData(this,{filename:s.filename}),this.notifyChange(this.object3d)}addComposites(e,n,o){this.addHighlightToFragment(e,n.fragment);const i=n.fragment.composites[o];if(i)for(let s=1;s<i;s++){const c=B.toCompositeID(o,s);this._ifcSelection[e][n.uuid].add(c)}}addHighlightToFragment(e,n){if(!(e in n.fragments)){const o=n.addFragment(e,[Ve[e]]);n.blocks.count>1&&(o.setInstance(0,{ids:Array.from(n.ids),transform:M}),o.blocks.setVisibility(!1)),this._model.add(o.mesh),o.mesh.renderOrder=30,o.mesh.frustumCulled=!1,o.mesh.name=e,o.mesh.updateMatrixWorld(!0)}}initializeEntityIndexes(){this._indexMap={};const e=this._model.properties;if(e!==void 0)for(const n of Ge)B.IfcPropertiesUtils.getRelationMap(e,n,(o,i)=>{const s=e[o];$e.includes(s.type)||this.setEntityIndex(o);for(const c of i)this.setEntityIndex(c).add(o)})}regenerate(e,n){this.updateFragmentFill(e,n)}async regenerateClassification(e,n={}){const o=this._fragmentClassifier.get(),i=[],s=e[0],c=o[s];if(s==null||c==null)return i;for(const y of Object.keys(c)){const w={...n,[s]:[y]},u=await this._fragmentClassifier.find(w);if(Object.keys(u).length>0){const S=s[0].toUpperCase()+s.slice(1),I=await this.regenerateClassification(e.slice(1),w);i.push({children:I,fragments:u,name:y,treeItemName:S})}}return i}setEntityIndex(e){return e in this._indexMap||(this._indexMap[e]=new Set),this._indexMap[e]}updateFragmentFill(e,n){const o=this._ifcSelection[e][n],i=this._fragmentManager.list[n];if(i==null)return;const s=i.fragments[e];if(s==null)return;const c=i.mesh.parent;if(c==null)return;if(c.add(s.mesh),s.blocks.count>1)i.getInstance(0,M),s.setInstance(0,{ids:Array.from(i.ids),transform:M}),s.blocks.setVisibility(!0,o,!0);else{let w=0;for(const u of o){s.mesh.count=w+1;const{instanceID:f}=i.getInstanceAndBlockID(u);i.getInstance(f,M),s.setInstance(w,{ids:[u],transform:M}),w++}}}};h(D,"isIFCEntity",e=>d.isObject(e)&&e.isIfcEntity),h(D,"isIFCPickResult",e=>d.isObject(e)&&D.isIFCEntity(e.entity));let U=D;class qe extends te{constructor(t,e,n){super(t,e,n,{visibility:!0})}}const Ye={class:"d-flex"},He=["title"],We=["id"],Ze={class:"list-unstyled border-start"},Xe=r.defineComponent({__name:"IfcSubtree",props:{classificationElement:{},ifcEntity:{}},setup(a){const t=a,e=d.MathUtils.generateUUID(),n=`#${e}`,o=r.ref(!1),i=d.useCameraStore(),c=d.useModuleStore().getModule(d.moduleId);function y(){if(c==null){console.warn("Cannot clip IFC element, ClippingBoxAnalysis module is not present");return}const f=t.ifcEntity.getBoundingBoxById(t.classificationElement.fragments);f&&!f.isEmpty()&&c.setClippingBox(f)}function w(){o.value=!0,t.ifcEntity.clearHighlight(),t.ifcEntity.highlightById(t.classificationElement.fragments),setTimeout(()=>o.value=!1,2e3)}function u(){const f=t.ifcEntity.getBoundingBoxById(t.classificationElement.fragments);f&&!f.isEmpty()&&i.lookTopDownAt(f)}return(f,C)=>{const S=r.resolveComponent("IfcSubtree",!0);return r.openBlock(),r.createElementBlock("div",null,[r.createElementVNode("div",Ye,[r.createElementVNode("span",{class:r.normalizeClass(["border rounded px-1 py-0 fw-normal",o.value?"text-danger border-danger":"text-secondary border-secondary"]),title:f.classificationElement.treeItemName},r.toDisplayString(f.classificationElement.treeItemName),11,He),f.classificationElement.children.length>0?(r.openBlock(),r.createBlock(d.IconList,{key:0},{default:r.withCtx(()=>[r.createVNode(d.IconListButton,{title:"Expand group",icon:"bi-chevron-down","data-bs-toggle":"collapse","data-bs-target":n,"aria-controls":r.unref(e),"aria-expanded":"true"},null,8,["aria-controls"])]),_:1})):r.createCommentVNode("",!0),r.createVNode(d._sfc_main$3,{class:r.normalizeClass(["label",o.value?"text-danger-emphasis":"text-muted"]),text:f.classificationElement.name,title:`Zoom to ${f.classificationElement.name}`,onClick:u},null,8,["class","text","title"]),r.createVNode(d.IconList,{class:"ms-1"},{default:r.withCtx(()=>[r.createVNode(d.IconListButton,{title:"Highlight",icon:"bi-highlighter",onClick:w}),r.unref(c)!=null?(r.openBlock(),r.createBlock(d.IconListButton,{key:0,title:"Clip to",icon:"bi-bounding-box",onClick:y})):r.createCommentVNode("",!0)]),_:1})]),f.classificationElement.children.length>0?(r.openBlock(),r.createElementBlock("div",{key:0,id:r.unref(e),class:"collapse show"},[r.createElementVNode("ul",Ze,[(r.openBlock(!0),r.createElementBlock(r.Fragment,null,r.renderList(f.classificationElement.children,(I,T)=>(r.openBlock(),r.createElementBlock("li",{key:T},[r.createVNode(S,{"ifc-entity":t.ifcEntity,"classification-element":I},null,8,["ifc-entity","classification-element"])]))),128))])],8,We)):r.createCommentVNode("",!0)])}}}),Je=d._export_sfc(Xe,[["__scopeId","data-v-804ca598"]]),Qe={key:0},Ke=r.defineComponent({__name:"IfcPropertyView",props:{dataset:{}},setup(a){const t=d.useDatasetStore(),e=a,n=d.refAndWatch(e.dataset,"isPreloaded");function o(){const s=i();return s==null?null:s.getClassification()}function i(){const s=t.getEntity(e.dataset);return s??null}return(s,c)=>r.unref(n)?(r.openBlock(),r.createElementBlock("div",Qe,[r.createElementVNode("ul",null,[(r.openBlock(!0),r.createElementBlock(r.Fragment,null,r.renderList(o(),(y,w)=>(r.openBlock(),r.createElementBlock("li",{key:w},[r.createVNode(Je,{"ifc-entity":i(),"classification-element":y},null,8,["ifc-entity","classification-element"])]))),128))])])):r.createCommentVNode("",!0)}}),et=d._export_sfc(Ke,[["__scopeId","data-v-d2d82ae7"]]),tt=a=>{if(X(a)){const t=a.object;if(t.fragment!=null&&a.face&&a.instanceId!=null){const e=t.fragment.getVertexBlockID(t.geometry,a.face.a),n=t.fragment.getItemID(a.instanceId,e).replace(/\..*/,"");return a.entity.highlight("selection",t,n),()=>a.entity.clearHighlight()}}return null},nt=a=>({name:a.filename,source:{url:a.file},type:"ifc",visible:!0}),st=(a,t)=>{var y,w,u,f,C,S,I,T,l;if(!X(a))return;const e=(y=a.features)==null?void 0:y.at(0);if(!e)return;t.has("IFC")||t.set("IFC",[]);const n=t.get("IFC"),{ifcProperties:o,itemProperties:i}=e,s="NULL",c=((w=i.Name)==null?void 0:w.value)??s;n.push({key:"Site",value:((f=(u=a.entity.object3d.userData)==null?void 0:u.dataset)==null?void 0:f.name)??s}),n.push({key:"IFCType",value:B.IfcCategoryMap[i.type]??s}),n.push({key:"Name",value:c}),n.push({key:"ID",value:i.expressID}),n.push({key:"GlobalId",value:((C=i.GlobalId)==null?void 0:C.value)??s}),((S=i.Description)==null?void 0:S.value)!=null&&n.push({key:"Description",value:i.Description.value}),((I=i.PredefinedType)==null?void 0:I.value)!=null&&n.push({key:"PredefinedType",value:i.PredefinedType.value}),((T=i.ObjectType)==null?void 0:T.value)!=null&&n.push({key:"ObjectType",value:i.ObjectType.value});for(const{name:g,parentName:m,value:p}of o)t.has(m)||t.set(m,[]),(l=t.get(m))==null||l.push({key:g,value:p})},ot=a=>{const t=a.dataset,e=t.config,n=d.getCoordinates(e.source.position??t.get("position")),o=new U({...e.source,at:n,name:t.name});return Promise.resolve(o)};class it{constructor(){h(this,"id","builtin-ifc-loader");h(this,"name","IFC")}async initialize(t){t.datasets.registerDatasetType("ifc",{attributeExtractor:st,entityBuilder:ot,fileExtensions:["ifc"],highlight:tt,icon:"bi-building",loader:nt,name:"IFC",propertyView:et}),ee.registerInspector("IfcEntity",qe),await d.Fetcher.fetch("web-ifc.wasm").catch(e=>{console.warn("Could not load web-ifc.wasm",e)})}}const rt=r.defineComponent({__name:"OpenLayersMinimapComponent",props:{context:{}},setup(a){const t=r.ref(),e=r.shallowRef(),n=a,o=[[3e4,12],[5e4,10],[1e5,8],[4e5,6],[8e5,4]];function i(s){for(const[c,y]of o)if(s<c)return y;return o[o.length-1][1]}return r.onMounted(()=>{e.value=new $.Map({controls:[],layers:[new ne({source:new se.OSM})],target:t.value,view:new $.View({center:G.fromLonLat([4,44]),projection:"EPSG:3857",zoom:5})});let s=new d.Vector3;const c=()=>{var S;const w=n.context.view.getInstance(),f=n.context.view.getCameraController().getCameraPosition(),C=f.camera.z;if(!f.camera.equals(s)){s=f.camera.clone();const I=new O(w.referenceCrs,s.x,s.y).as("EPSG:4326"),T=i(C),l=(S=e.value)==null?void 0:S.getView();l==null||l.setCenter(G.fromLonLat([I.longitude,I.latitude])),l==null||l.setZoom(T)}};n.context.events.addEventListener("updated",c);let y=!1;t.value&&(t.value.onclick=()=>{var w,u,f,C;y=!y,y?((w=t.value)==null||w.classList.add("collapsed"),(u=t.value)==null||u.classList.remove("expanded")):((f=t.value)==null||f.classList.remove("collapsed"),(C=t.value)==null||C.classList.add("expanded"))})}),r.onUnmounted(()=>{var s;(s=e.value)==null||s.dispose(),e.value=void 0}),(s,c)=>(r.openBlock(),r.createElementBlock("div",{ref_key:"target",ref:t,title:"Toggle minimap",class:"minimap expanded"},null,512))}}),at=d._export_sfc(rt,[["__scopeId","data-v-38ee3c04"]]);class lt{constructor(){h(this,"id","builtin-minimap-openlayers");h(this,"name","Minimap")}initialize(t){t.widgets.addWidget({component:at,id:"minimap-ol"})}}const k=new d.Color;let ct=class extends d.Loader{constructor(t){super(t),this.propertyNameMapping={},this.customPropertyMapping={}}load(t,e,n,o){const i=this,s=new d.FileLoader(this.manager);s.setPath(this.path),s.setResponseType("arraybuffer"),s.setRequestHeader(this.requestHeader),s.setWithCredentials(this.withCredentials),s.load(t,function(c){try{e(i.parse(c))}catch(y){o?o(y):console.error(y),i.manager.itemError(t)}},n,o)}setPropertyNameMapping(t){this.propertyNameMapping=t}setCustomPropertyNameMapping(t){this.customPropertyMapping=t}parse(t){function e(l,g=0){const m=/^ply([\s\S]*)end_header(\r\n|\r|\n)/;let p="";const b=m.exec(l);b!==null&&(p=b[1]);const v={comments:[],elements:[],headerLength:g,objInfo:""},x=p.split(/\r\n|\r|\n/);let _;function L(E,F){const P={type:E[0]};return P.type==="list"?(P.name=E[3],P.countType=E[1],P.itemType=E[2]):P.name=E[1],P.name in F&&(P.name=F[P.name]),P}for(let E=0;E<x.length;E++){let F=x[E];if(F=F.trim(),F==="")continue;const P=F.split(/\s+/),A=P.shift();switch(F=P.join(" "),A){case"format":v.format=P[0],v.version=P[1];break;case"comment":v.comments.push(F);break;case"element":_!==void 0&&v.elements.push(_),_={},_.name=P[0],_.count=parseInt(P[1]),_.properties=[];break;case"property":_.properties.push(L(P,T.propertyNameMapping));break;case"obj_info":v.objInfo=F;break;default:console.log("unhandled",A,P)}}return _!==void 0&&v.elements.push(_),v}function n(l,g){switch(g){case"char":case"uchar":case"short":case"ushort":case"int":case"uint":case"int8":case"uint8":case"int16":case"uint16":case"int32":case"uint32":return parseInt(l);case"float":case"double":case"float32":case"float64":return parseFloat(l)}}function o(l,g){const m={};for(let p=0;p<l.length;p++){if(g.empty())return null;if(l[p].type==="list"){const b=[],v=n(g.next(),l[p].countType);for(let x=0;x<v;x++){if(g.empty())return null;b.push(n(g.next(),l[p].itemType))}m[l[p].name]=b}else m[l[p].name]=n(g.next(),l[p].type)}return m}function i(){const l={indices:[],vertices:[],normals:[],uvs:[],faceVertexUvs:[],colors:[],faceVertexColors:[]};for(const g of Object.keys(T.customPropertyMapping))l[g]=[];return l}function s(l){const g=l.map(p=>p.name);function m(p){for(let b=0,v=p.length;b<v;b++){const x=p[b];if(g.includes(x))return x}return null}return{attrX:m(["x","px","posx"])||"x",attrY:m(["y","py","posy"])||"y",attrZ:m(["z","pz","posz"])||"z",attrNX:m(["nx","normalx"]),attrNY:m(["ny","normaly"]),attrNZ:m(["nz","normalz"]),attrS:m(["s","u","texture_u","tx"]),attrT:m(["t","v","texture_v","ty"]),attrR:m(["red","diffuse_red","r","diffuse_r"]),attrG:m(["green","diffuse_green","g","diffuse_g"]),attrB:m(["blue","diffuse_blue","b","diffuse_b"])}}function c(l,g){const m=i(),p=/end_header\s+(\S[\s\S]*\S|\S)\s*$/;let b,v;(v=p.exec(l))!==null?b=v[1].split(/\s+/):b=[];const x=new ut(b);e:for(let _=0;_<g.elements.length;_++){const L=g.elements[_],E=s(L.properties);for(let F=0;F<L.count;F++){const P=o(L.properties,x);if(!P)break e;w(m,L.name,P,E)}}return y(m)}function y(l){let g=new d.BufferGeometry;l.indices.length>0&&g.setIndex(l.indices),g.setAttribute("position",new d.Float32BufferAttribute(l.vertices,3)),l.normals.length>0&&g.setAttribute("normal",new d.Float32BufferAttribute(l.normals,3)),l.uvs.length>0&&g.setAttribute("uv",new d.Float32BufferAttribute(l.uvs,2)),l.colors.length>0&&g.setAttribute("color",new d.Float32BufferAttribute(l.colors,3)),(l.faceVertexUvs.length>0||l.faceVertexColors.length>0)&&(g=g.toNonIndexed(),l.faceVertexUvs.length>0&&g.setAttribute("uv",new d.Float32BufferAttribute(l.faceVertexUvs,2)),l.faceVertexColors.length>0&&g.setAttribute("color",new d.Float32BufferAttribute(l.faceVertexColors,3)));for(const m of Object.keys(T.customPropertyMapping))l[m].length>0&&g.setAttribute(m,new d.Float32BufferAttribute(l[m],T.customPropertyMapping[m].length));return g.computeBoundingSphere(),g}function w(l,g,m,p){if(g==="vertex"){l.vertices.push(m[p.attrX],m[p.attrY],m[p.attrZ]),p.attrNX!==null&&p.attrNY!==null&&p.attrNZ!==null&&l.normals.push(m[p.attrNX],m[p.attrNY],m[p.attrNZ]),p.attrS!==null&&p.attrT!==null&&l.uvs.push(m[p.attrS],m[p.attrT]),p.attrR!==null&&p.attrG!==null&&p.attrB!==null&&(k.setRGB(m[p.attrR]/255,m[p.attrG]/255,m[p.attrB]/255,d.SRGBColorSpace),l.colors.push(k.r,k.g,k.b));for(const b of Object.keys(T.customPropertyMapping))for(const v of T.customPropertyMapping[b])l[b].push(m[v])}else if(g==="face"){const b=m.vertex_indices||m.vertex_index,v=m.texcoord;b.length===3?(l.indices.push(b[0],b[1],b[2]),v&&v.length===6&&(l.faceVertexUvs.push(v[0],v[1]),l.faceVertexUvs.push(v[2],v[3]),l.faceVertexUvs.push(v[4],v[5]))):b.length===4&&(l.indices.push(b[0],b[1],b[3]),l.indices.push(b[1],b[2],b[3])),p.attrR!==null&&p.attrG!==null&&p.attrB!==null&&(k.setRGB(m[p.attrR]/255,m[p.attrG]/255,m[p.attrB]/255,d.SRGBColorSpace),l.faceVertexColors.push(k.r,k.g,k.b),l.faceVertexColors.push(k.r,k.g,k.b),l.faceVertexColors.push(k.r,k.g,k.b))}}function u(l,g){const m={};let p=0;for(let b=0;b<g.length;b++){const v=g[b],x=v.valueReader;if(v.type==="list"){const _=[],L=v.countReader.read(l+p);p+=v.countReader.size;for(let E=0;E<L;E++)_.push(x.read(l+p)),p+=x.size;m[v.name]=_}else m[v.name]=x.read(l+p),p+=x.size}return[m,p]}function f(l,g,m){function p(b,v,x){switch(v){case"int8":case"char":return{read:_=>b.getInt8(_),size:1};case"uint8":case"uchar":return{read:_=>b.getUint8(_),size:1};case"int16":case"short":return{read:_=>b.getInt16(_,x),size:2};case"uint16":case"ushort":return{read:_=>b.getUint16(_,x),size:2};case"int32":case"int":return{read:_=>b.getInt32(_,x),size:4};case"uint32":case"uint":return{read:_=>b.getUint32(_,x),size:4};case"float32":case"float":return{read:_=>b.getFloat32(_,x),size:4};case"float64":case"double":return{read:_=>b.getFloat64(_,x),size:8}}}for(let b=0,v=l.length;b<v;b++){const x=l[b];x.type==="list"?(x.countReader=p(g,x.countType,m),x.valueReader=p(g,x.itemType,m)):x.valueReader=p(g,x.type,m)}}function C(l,g){const m=i(),p=g.format==="binary_little_endian",b=new DataView(l,g.headerLength);let v,x=0;for(let _=0;_<g.elements.length;_++){const L=g.elements[_],E=L.properties,F=s(E);f(E,b,p);for(let P=0;P<L.count;P++){v=u(x,E),x+=v[1];const A=v[0];w(m,L.name,A,F)}}return y(m)}function S(l){let g=0,m=!0,p="";const b=[],v=new TextDecoder().decode(l.subarray(0,5)),x=/^ply\r\n/.test(v);do{const _=String.fromCharCode(l[g++]);_!==`
|
|
2
|
-
`&&_!=="\r"?p+=_:(p==="end_header"&&(m=!1),p!==""&&(b.push(p),p=""))}while(m&&g<l.length);return x===!0&&g++,{headerText:b.join("\r")+"\r",headerLength:g}}let I;const T=this;if(t instanceof ArrayBuffer){const l=new Uint8Array(t),{headerText:g,headerLength:m}=S(l),p=e(g,m);if(p.format==="ascii"){const b=new TextDecoder().decode(l);I=c(b,p)}else I=C(t,p)}else I=c(t,e(t));return I}};class ut{constructor(t){this.arr=t,this.i=0}empty(){return this.i>=this.arr.length}next(){return this.arr[this.i++]}}const V=class V extends d.Mesh{constructor(){super(...arguments);h(this,"isPickableFeatures",!0);h(this,"isPlyMesh",!0)}pickFeaturesFrom(e){if(this.geometry.hasAttribute("color")&&e.face){const n=this.geometry.getAttribute("color").array,o=e.face,s=[{color:new d.Color(n[o.a*3],n[o.a*3+1],n[o.a*3+2])}];return e.features=s,s}return[]}};h(V,"isPlyMesh",e=>d.isObject(e)&&e.isPlyMesh),h(V,"isPlyPickResult",e=>d.isObject(e)&&V.isPlyMesh(e==null?void 0:e.object));let z=V;class dt extends j{constructor(e){super(new d.Group);h(this,"isPlyEntity",!0);h(this,"source");this.source=e}async preprocess(){const e=await d.Fetcher.fetchArrayBuffer(this.source.url),n=this.source.at.as(this.source.featureProjection).toVector3(),i=new ct().parse(e),s=new d.MeshLambertMaterial({side:d.DoubleSide});i.hasAttribute("color")&&(s.vertexColors=!0),i.computeVertexNormals();const c=new z(i,s);c.name="plyModel",i.computeBoundingBox(),c.position.copy(n),c.updateWorldMatrix(!0,!0),this.object3d.add(c),this.onObjectCreated(c);const y=d.Fetcher.getContext(this.source.url);d.fillObject3DUserData(this,{filename:y.filename}),this.notifyChange(this.object3d)}}const pt=a=>{const{dataset:t,instance:e}=a,n=t.config,o=d.getCoordinates(n.source.position??t.get("position")),i=new dt({...n.source,at:o,featureProjection:e.referenceCrs});return Promise.resolve(i)},mt=(a,t)=>{var o;if(!z.isPlyPickResult(a))return;const e=(o=a.features)==null?void 0:o.at(0);if(!e)return;t.has("PLY")||t.set("PLY",[]),t.get("PLY").push({key:"Color",value:e.color})};class ht{constructor(){h(this,"id","builtin-ply-loader");h(this,"name","PLY")}initialize(t){t.datasets.registerDatasetType("ply",{attributeExtractor:mt,entityBuilder:pt,icon:"bi-file-earmark-binary",name:"PLY"})}}const ft=a=>{a.addEventListener("object-created",t=>{t.obj.traverse(n=>{var o;((o=n.userData)==null?void 0:o.class)==="IfcSpace"&&(n.visible=!1)})})};class gt{constructor(){h(this,"id","builtin-post-process-entities");h(this,"name","Post-process 3D Tiles");h(this,"_alreadyProcessedEntities",new Set);h(this,"_processings",[ft])}initialize(t){t.events.addEventListener("ready",()=>{const e=t.view.getInstance();e.addEventListener("entity-added",()=>this.processEntities(e)),this.processEntities(e)})}processEntities(t){for(const e of t.getEntities())this._alreadyProcessedEntities.has(e.id)||(j.isEntity3D(e)&&this.processEntity(e,t),this._alreadyProcessedEntities.add(e.id))}processEntity(t,e){const n={instance:e};for(const o of this._processings)o(t,n)}}const yt=a=>{const t=a.dataset.config,e=new oe({source:new ie({url:`${t.source.url}/${t.source.filename}`})});return d.fillObject3DUserData(e,{filename:t.source.url}),Promise.resolve(e)};class bt{constructor(){h(this,"id","builtin-potree-loader");h(this,"name","Potree")}initialize(t){t.datasets.registerDatasetType("potree",{entityBuilder:yt,icon:"fg-multipoint",name:"Potree Point Cloud"})}}class vt{constructor(){h(this,"id","builtin-tour");h(this,"name","Tour");h(this,"_camera",null);h(this,"_cameraCallback",null);h(this,"_context",null);h(this,"_tours",null)}initialize(t){this._context=t,t.events.addEventListener("ready",this.start.bind(this))}buildTours(){const t=this._camera,e=new N.Tour({tourName:"main",useModalOverlay:!0}),n=new N.Tour({tourName:"navigating",useModalOverlay:!0}),o=new N.Tour({tourName:"analyzing",useModalOverlay:!0}),i=[{action:()=>{var u;return(u=N.activeTour)==null?void 0:u.next()},text:"Next"},{action:()=>{var u;return(u=N.activeTour)==null?void 0:u.cancel()},secondary:!0,text:"Exit"}],s=()=>{var l,g;const u=(l=N.activeTour)==null?void 0:l.getCurrentStep(),f=u==null?void 0:u.getElement(),C=f==null?void 0:f.querySelector(".shepherd-text"),S=(g=N.activeTour)==null?void 0:g.steps;if(u==null||f==null||C==null||S==null)return;const I=document.createElement("div");I.className="progress mt-3",I.setAttribute("role","progressbar"),I.style.height="2px";const T=document.createElement("div");T.className="progress-bar bg-success",T.style.width=`${100*(S.indexOf(u)/S.length)}%`,I.appendChild(T),C.appendChild(I)},c=async(u,f)=>new Promise(C=>{const S=document.getElementById(u);if(S&&!S.classList.contains("active")&&S.click(),document.querySelector(f))return C(document.querySelector(f));const I=new MutationObserver(()=>{document.querySelector(f)&&(I.disconnect(),C(document.querySelector(f)))});I.observe(document.body,{childList:!0,subtree:!0})});e.addStep({buttons:[{action:()=>{var u;(u=N.activeTour)==null||u.complete(),n.show(0)},text:"Navigating"},{action:()=>{var u;(u=N.activeTour)==null||u.complete(),o.show(0)},text:"Analyzing data"},{action:()=>{var u;return(u=N.activeTour)==null?void 0:u.cancel()},secondary:!0,text:"Exit"}],cancelIcon:{enabled:!0,label:"Exit tutorial"},id:"example-step",text:"<p>Welcome to <strong>Piero</strong>, the Giro3D application.<br/>We can guide you through the different features.</p>",title:"Welcome!",when:{show:s}}),n.addStep({attachTo:{element:"#main-view",on:"bottom"},buttons:i,id:"view",text:"<p>This is the <b>main view</b>.</p><p>Giro3D natively supports a broad range of data sources, from 2D raster and vector data, to 3D point clouds and tilesets.</p><p>Piero adds support for CityJSON and IFC files.</p>",when:{show:s}}),n.addStep({attachTo:{element:"#main-view",on:"bottom"},buttons:i,id:"navigate",text:'<p>This application integrates <a href="https://github.com/yomotsu/camera-controls">camera-controls</a>, a camera control for three.js.</p><p><b>Click</b> to move the camera. <b>Right-click</b> to rotate around a point. <b>Scroll</b> to zoom in or out.</p>',when:{hide:()=>{this._cameraCallback&&t.removeEventListener("interaction-end",this._cameraCallback),this._cameraCallback=null},show:()=>{let u=0;this._cameraCallback=()=>{var f;u+=1,u>2&&((f=N.activeTour)==null||f.next())},t.addEventListener("interaction-end",this._cameraCallback),s()}}}),n.addStep({attachTo:{element:"#toolbar",on:"right"},beforeShowPromise:()=>c("toolbar-datasets","#datasets-drop-zone"),buttons:i,id:"toolbar-layers",text:"<p>Giro3D supports multiple datasets.</p><p>You can toggle datasets as you wish with the <b>Datasets</b> panel.</p>",when:{show:s}}),n.addStep({attachTo:{element:"#basemap-list",on:"right"},beforeShowPromise:()=>c("toolbar-datasets","#datasets-drop-zone"),buttons:i,id:"basemaps",text:"<p><b>Basemaps</b> are color and elevation layers that make the basic shape and aspect of the <b>Map</b>.</p>",when:{show:s}}),n.addStep({attachTo:{element:"#overlay-list",on:"right"},beforeShowPromise:()=>c("toolbar-datasets","#datasets-drop-zone"),buttons:i,id:"overlays",text:"<p><b>Overlays</b> are vector layers in various formats (WFS, GML, GeoJSON...).</p>",when:{show:s}}),n.addStep({attachTo:{element:"#dataset-list",on:"right"},beforeShowPromise:()=>c("toolbar-datasets","#datasets-drop-zone"),buttons:i,id:"layers",text:"<p>The <b>Datasets</b> panel contains all 3D objects in the scene.</><p>You can toggle their visibility and delete them.<p><p>Most objects leverage Giro3D's adaptive resolution to optimize their display.</p>",when:{show:s}}),n.addStep({attachTo:{element:"#datasets-drop-zone",on:"right"},beforeShowPromise:()=>c("toolbar-datasets","#datasets-drop-zone"),buttons:i,id:"adddata",text:"<p>You can add your own data from your computer by <b>dragging the file</b> into this page.</p><p>While you won't benefit from Giro3D's tiling mechanism, this can be a great way to quickly visualize datasets up to 100MB.</p><p>This application supports CityJSONs, IFCs, LAS/LAZs, CSV pointclouds, and simple GeoJSON features.</p>",when:{show:s}}),n.addStep({attachTo:{element:"#main-view",on:"bottom"},buttons:i,id:"attributes",text:"<p>By clicking on any feature on the map, you can see its <strong>Attribute table</strong>. Clickable features display a cursor when hovered.</p>",when:{show:s}}),n.addStep({attachTo:{element:"#search-place-autocomplete",on:"bottom"},buttons:[{action:()=>{var u;(u=N.activeTour)==null||u.complete(),o.show(0)},text:"Analyzing data"},{action:()=>{var u;return(u=N.activeTour)==null?void 0:u.complete()},secondary:!0,text:"Exit"}],id:"widgets",text:"Giro3D is highly extensible. Here we added a widget to search and navigate to locations based on the French address database.",when:{show:s}}),o.addStep({attachTo:{element:"#annotations-fieldset",on:"right"},beforeShowPromise:()=>c("toolbar-annotations","#annotations-fieldset"),buttons:i,id:"annotation",text:"<p>You can <strong>annotate</strong> any data displayed using Giro3D native tools.<br>Select the <strong>geometry</strong> of your annotation, and <strong>click</strong> on the scene to add points. <strong>Right-click</strong> to end the shape.</p>",when:{show:s}}),o.addStep({attachTo:{element:"#annotations-fieldset",on:"right"},beforeShowPromise:()=>c("toolbar-annotations","#annotations-fieldset"),buttons:i,id:"annotations",text:"You can download your annotations as GeoJSON files. You can also upload your own by dragging them into this panel.",when:{show:s}}),d.hasExperimentalFeature("measurements")&&o.addStep({attachTo:{element:"#panel-container",on:"right"},beforeShowPromise:()=>c("toolbar-measures","#measures-fieldset"),buttons:i,id:"measurements",text:"You can add <strong>measurements</strong> to easily get distances betwween objects.<br>Once started, moving the mouse will display the measure. <strong>Click</strong> to save the measurement. <strong>Right-click</strong> to end.",when:{show:s}}),o.addStep({attachTo:{element:"#panel-container",on:"right"},beforeShowPromise:()=>c("toolbar-analysis","#panel-container .card"),buttons:[{action:()=>{var u;return(u=N.activeTour)==null?void 0:u.complete()},text:"Done!"}],id:"analysis",text:"In the <strong>Analysis</strong> panel you'll find some advanced analysis tools.",when:{show:s}});const y=()=>{const u=new URL(document.URL);u.searchParams.delete("tourStep"),u.searchParams.set("tour","none"),window.history.replaceState({},"",u.toString())},w=u=>{const f=new URL(document.URL);let C="main";u.tour.id.startsWith("navigating")?C="navigating":u.tour.id.startsWith("analyzing")&&(C="analyzing"),f.searchParams.set("tour",C),f.searchParams.set("tourStep",u.step.id),window.history.replaceState({},"",f.toString())};return e.on("cancel",y),e.on("complete",y),e.on("show",w),n.on("cancel",y),n.on("complete",y),n.on("show",w),o.on("cancel",y),o.on("complete",y),o.on("show",w),{analyzingTour:o,mainTour:e,navigatingTour:n}}getTours(){return this._tours||(this._tours=this.buildTours()),this._tours}restart(){const{mainTour:t}=this.getTours();t.show(0)}start(){if(!this._context)throw new Error("module is not initialized");const{analyzingTour:t,mainTour:e,navigatingTour:n}=this.getTours();this._camera=this._context.view.getCameraController();const o=new URL(document.URL),i=o.searchParams.get("tour")??"main";if(i!=="none"){const s=o.searchParams.get("tourStep")??0;i==="navigating"?n.show(s):i==="analyzing"?t.show(s):e.show(s)}}}exports.ClippingBoxAnalysis=d.ClippingBoxAnalysis;exports.CoordinatesSearch=Ne;exports.CrossSectionAnalysis=ye;exports.DownloadDataset=ve;exports.FloodingPlaneAnalysis=Be;exports.FrenchBanGeocoder=De;exports.IFCLoader=it;exports.OpenLayersMinimap=lt;exports.PLYLoader=ht;exports.PostProcessEntities=gt;exports.PotreeLoader=bt;exports.Tour=vt;
|
|
1
|
+
"use strict";var Y=Object.defineProperty;var W=(r,t,e)=>t in r?Y(r,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):r[t]=e;var d=(r,t,e)=>W(r,typeof t!="symbol"?t+"":t,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("./Components.cjs.js"),i=require("vue"),T=require("@giro3d/giro3d/core/geographic/Coordinates"),H=require("pinia"),L=require("@giro3d/giro3d/entities/Entity3D"),Z=require("@giro3d/giro3d/utils/Fetcher"),J=require("@giro3d/giro3d/gui/EntityPanel"),_=require("openbim-components"),Q=require("@giro3d/giro3d/gui/EntityInspector"),z=require("ol"),X=require("ol/layer/Tile"),j=require("ol/proj"),K=require("ol/source"),ee=require("@giro3d/giro3d/entities/PointCloud"),te=require("@giro3d/giro3d/sources/PotreeSource"),w=require("shepherd.js"),ne={class:"input-group"},oe={class:"form-label"},se={class:"input-group"},ie=["value"],ae=["value"],re=["value"],le=i.defineComponent({__name:"CoordinateInput",props:{cursorManager:{},initialValue:{},instance:{},label:{},showZ:{type:Boolean}},emits:["update:coordinates"],setup(r,{emit:t}){var y,C,v;const e=r,n=i.ref(((y=e.initialValue)==null?void 0:y.x)??0),o=i.ref(((C=e.initialValue)==null?void 0:C.y)??0),s=i.ref(((v=e.initialValue)==null?void 0:v.z)??0),a=t,u=new c.Picker,h=i.ref(!1),m=()=>{a("update:coordinates",new T(c.nonNull(e.instance).referenceCrs,n.value,o.value,s.value))},l=()=>{const b=c.nonNull(e.instance);h.value=!0;const E=V=>{var I,S,k,A;const P=(S=(I=u.getFirstFeatureAt(b,V))==null?void 0:I.at(0))==null?void 0:S.point;P&&(n.value=P.x,o.value=P.y,s.value=P.z,(k=e.cursorManager)==null||k.setCursor("location"),(A=e.cursorManager)==null||A.setCursorLocation(P))},x=V=>{var I,S,k;(I=e.cursorManager)==null||I.setCursor(null),b.domElement.removeEventListener("click",x),b.domElement.removeEventListener("mousemove",E),h.value=!1;const P=(k=(S=u.getFirstFeatureAt(b,V))==null?void 0:S.at(0))==null?void 0:k.point;P&&(n.value=P.x,o.value=P.y,s.value=P.z,m())};b.domElement.addEventListener("mousemove",E),b.domElement.addEventListener("click",x)};function p(b){n.value=b,m()}function f(b){o.value=b,m()}function g(b){s.value=b,m()}return(b,E)=>(i.openBlock(),i.createElementBlock("div",ne,[i.createElementVNode("label",oe,i.toDisplayString(e.label),1),i.createElementVNode("div",se,[i.createElementVNode("input",{type:"number",class:"form-control",id:"plane-center-x",value:n.value.toFixed(2),onInput:E[0]||(E[0]=x=>p(Number.parseFloat(x.target.value)))},null,40,ie),i.createElementVNode("input",{type:"number",class:"form-control",id:"plane-center-y",value:o.value.toFixed(2),onInput:E[1]||(E[1]=x=>f(Number.parseFloat(x.target.value)))},null,40,ae),e.showZ===!0?(i.openBlock(),i.createElementBlock("input",{key:0,type:"number",class:"form-control",id:"plane-center-z",value:s.value.toFixed(2),onInput:E[2]||(E[2]=x=>g(Number.parseFloat(x.target.value)))},null,40,re)):i.createCommentVNode("",!0),e.instance!=null?(i.openBlock(),i.createBlock(c._sfc_main$1,{key:1,title:"Pick point in scene",icon:"fg-location",disabled:h.value,onClick:l,class:"btn-primary"},null,8,["disabled"])):i.createCommentVNode("",!0)])]))}}),$=H.defineStore("crossSection",()=>{const r=i.ref(0),t=i.shallowRef(),e=i.shallowRef(),n=i.ref(new c.Vector3(0,0,0)),o=i.ref(!1),s=i.ref(!1);function a(f){o.value=f}function u(f){r.value=f}function h(f){n.value=f}function m(f){s.value=f}function l(f){t.value=f}function p(f){e.value=f}return{center:n,cursorManager:e,enable:o,instance:t,orientation:r,setCenter:h,setCursorManager:p,setEnabled:a,setInstance:l,setOrientation:u,setShowHelper:m,showHelper:s}}),ce={class:"input-group"},ue={class:"input-group"},de={class:"input-group my-3"},pe=["value"],he={class:"input-group mb-3"},me=["value"],fe=i.defineComponent({__name:"CrossSection",setup(r){const t=$();function e(o){t.setOrientation(o)}const n=o=>{t.setCenter(o.toVector3())};return(o,s)=>(i.openBlock(),i.createElementBlock(i.Fragment,null,[i.createElementVNode("div",ce,[i.createVNode(c._sfc_main,{"model-value":i.unref(t).enable,"onUpdate:modelValue":s[0]||(s[0]=a=>i.unref(t).setEnabled(a)),id:"cross-section-enable",title:"Enable cross-section"},null,8,["model-value"]),s[4]||(s[4]=i.createElementVNode("label",{for:"cross-section-enable",class:"form-check-label"},"Enable cross section",-1))]),i.createElementVNode("div",ue,[i.createVNode(c._sfc_main,{"model-value":i.unref(t).showHelper,"onUpdate:modelValue":s[1]||(s[1]=a=>i.unref(t).setShowHelper(a)),id:"cross-section-helper-enable",title:"Show plane helper"},null,8,["model-value"]),s[5]||(s[5]=i.createElementVNode("label",{for:"cross-section-helper-enable",class:"form-check-label"},"Show plane helper",-1))]),i.createElementVNode("div",de,[s[6]||(s[6]=i.createElementVNode("label",{for:"plane-orientation-range",class:"form-check-label"},"Plane orientation (0-360°)",-1)),i.createElementVNode("input",{id:"plane-orientation-range",title:"Altitude",type:"range",class:"form-range",min:"0",step:"0.1",max:"360",value:i.unref(t).orientation,onInput:s[2]||(s[2]=a=>e(Number.parseFloat(a.target.value)))},null,40,pe)]),i.createElementVNode("div",he,[i.createElementVNode("input",{type:"number",class:"form-control",id:"plane-orientation-number",step:"0.1",value:i.unref(t).orientation,onInput:s[3]||(s[3]=a=>e(Number.parseFloat(a.target.value)))},null,40,me)]),s[7]||(s[7]=i.createElementVNode("hr",null,null,-1)),i.unref(t).instance!=null?(i.openBlock(),i.createBlock(le,{key:0,label:"Center","initial-value":i.unref(t).center,instance:i.unref(t).instance,"cursor-manager":i.unref(t).cursorManager,"onUpdate:coordinates":n},null,8,["initial-value","instance","cursor-manager"])):i.createCommentVNode("",!0)],64))}});class ge extends c.Object3D{constructor(){super();const t=new c.Mesh(new c.PlaneGeometry(50,100,1,10),new c.MeshBasicMaterial({color:"#6bf904",depthTest:!1,depthWrite:!1,wireframe:!0})),e=new c.ArrowHelper(new c.Vector3(0,1,0),new c.Vector3(0,0,0),200);t.renderOrder=999,t.rotateY(Math.PI/2),this.add(t),this.add(e),this.updateMatrixWorld(!0)}}class ye{constructor(t){d(this,"_clippingPlanes",null);d(this,"_helper");d(this,"_instance");d(this,"_store",$());this.context=t,t.events.addEventListener("ready",()=>{this._instance=t.view.getInstance();const e=t.configuration.default_crs,n=t.configuration.analysis.cross_section;this._store.setCursorManager(t.view.getSceneCursorManager()),this._store.setInstance(t.view.getInstance()),this._store.setOrientation(n.orientation);const o=n.pivot,s=new T(o.crs??e,o.x,o.y,0).as(e);this._store.setCenter(s.toVector3()),this._instance.addEventListener("entity-added",this.updateCrossSection.bind(this)),this._store.$onAction(({after:a,name:u})=>{a(()=>{switch(u){case"setCenter":case"setEnabled":case"setOrientation":case"setShowHelper":this.updateCrossSection(),this.updateHelper(),this.showHelper(this._store.showHelper);break}})}),this.updateCrossSection(),this.updateHelper(),this.showHelper(this._store.showHelper)})}dispose(){}createHelperIfNecessary(){this._store.showHelper&&this._helper==null&&this._instance&&(this._helper=new ge,this._instance.add(this._helper).catch(console.error))}showHelper(t){this.createHelperIfNecessary(),this._helper&&(this._helper.visible=t),this.updateHelper()}updateCrossSection(){if(this._store.enable){const t=[],e=c.MathUtils.DEG2RAD*this._store.orientation,n=Math.cos(e),o=Math.sin(e),s=new c.Vector3(n,o,0),a=new c.Plane(s,0).distanceToPoint(this._store.center),u=new c.Plane(s,-a);t.push(u),this._clippingPlanes=t}else this._clippingPlanes=null;this.updateEntities()}updateEntities(){const t=this.context.view.getInstance();for(const e of t.getEntities())L.isEntity3D(e)&&(e.clippingPlanes=this._clippingPlanes);t.notifyChange()}updateHelper(){var t,e,n,o;this.createHelperIfNecessary(),(t=this._helper)==null||t.position.copy(this._store.center),(e=this._helper)==null||e.updateMatrixWorld(!0),(n=this._helper)==null||n.setRotationFromAxisAngle(new c.Vector3(0,0,1),c.MathUtils.degToRad(this._store.orientation)),(o=this._instance)==null||o.notifyChange()}}class be{constructor(){d(this,"id","builtin-cross-section-analysis");d(this,"name","Cross section");d(this,"_manager",null)}initialize(t){t.analysis.registerTool({component:fe,icon:"bi-circle-half",name:"Cross section"}),this._manager=new ye(t)}}function D(r){if("url"in r.config&&typeof r.config.url=="string")return r.config.url;if("source"in r.config&&typeof r.config.source=="object"&&"url"in r.config.source&&typeof r.config.source.url=="string")return r.config.source.url}function _e(r){return D(r)!=null}class ve{constructor(){d(this,"id","builtin-download-dataset");d(this,"name","Download dataset");d(this,"_context",null)}initialize(t){this._context=t,t.datasets.registerDatasetAction({action:this.download.bind(this),icon:"bi-download",predicate:_e,title:"Download dataset"})}download(t){const e=D(t);if(e==null){console.warn("invalid");return}const n=this._context,o=new URL(e).pathname.split("/"),s=o[o.length-1];console.info(`download ${D(t)}`),c.Fetcher.fetch(e).then(a=>{if(!a.ok)throw new Error(`${a.status} ${a.statusText}`);return a.blob()}).then(a=>{c.Download.downloadBlob(a,s),n.notifications.pushNotification({level:"success",text:s,title:"Download successful"})}).catch(a=>{console.error(a);const u=a instanceof Error?a.message:"Download failed";n.notifications.pushNotification({level:"error",text:u,title:t.name})})}}const R=H.defineStore("floodingPlane",()=>{const r=i.ref(0),t=i.ref(!1);function e(){return r.value}function n(s){r.value=s}function o(s){t.value=s}return{enable:t,getHeight:e,setEnabled:o,setHeight:n}}),we={class:"input-group mb-3"},Ce={class:"input-group mb-3"},Ee=["value"],xe={class:"input-group mb-3"},Pe=["value"],Ie=i.defineComponent({__name:"FloodingPlane",setup(r){const t=R();function e(n){t.setHeight(n)}return(n,o)=>(i.openBlock(),i.createElementBlock(i.Fragment,null,[i.createElementVNode("div",we,[i.createVNode(c._sfc_main,{"model-value":i.unref(t).enable,"onUpdate:modelValue":o[0]||(o[0]=s=>i.unref(t).setEnabled(s)),id:"flooding-plane-enable",title:"foo"},null,8,["model-value"]),o[3]||(o[3]=i.createElementVNode("label",{for:"flooding-plane-enable",class:"form-label"},"Enable flooding plane",-1))]),i.createElementVNode("div",Ce,[o[5]||(o[5]=i.createElementVNode("label",{for:"flooding-altitude-range",class:"form-label"},"Altitude",-1)),i.createElementVNode("input",{id:"flooding-altitude-range",title:"Altitude",type:"range",class:"form-range",min:"0",step:"0.1",max:"500",value:i.unref(t).getHeight(),onInput:o[1]||(o[1]=s=>e(Number.parseFloat(s.target.value)))},null,40,Ee),i.createElementVNode("div",xe,[i.createElementVNode("input",{type:"number",class:"form-control",id:"flooding-altitude-number",step:"0.1",value:i.unref(t).getHeight(),onInput:o[2]||(o[2]=s=>e(Number.parseFloat(s.target.value)))},null,40,Pe),o[4]||(o[4]=i.createElementVNode("span",{class:"input-group-text"},"m",-1))])])],64))}});class Se{constructor(){d(this,"geometry");d(this,"material");d(this,"object3D");d(this,"_height");this.geometry=new c.PlaneGeometry(1,1,1,1),this.material=new c.MeshBasicMaterial({color:43690,opacity:.5,transparent:!0}),this.object3D=new c.Mesh(this.geometry,this.material),this.object3D.renderOrder=2,this.visible=!1,this._height=0}set height(t){this._height=t}get height(){return this._height}set visible(t){this.object3D.visible=t}get visible(){return this.object3D.visible}dispose(){this.object3D.removeFromParent(),this.geometry.dispose(),this.material.dispose()}setPosition(t,e,n,o,s){this.object3D.scale.set(o,s,1),this.object3D.position.set(t,e,n),this.object3D.updateMatrixWorld()}}class ke{constructor(t){d(this,"_context");d(this,"_plane");d(this,"_store",R());this._context=t,this._plane=null,t.events.addEventListener("ready",()=>{this._store.$onAction(({after:e,name:n})=>{e(()=>{switch(n){case"setEnabled":this.updatePlane();break;case"setHeight":this.updatePlane();break}})})})}dispose(){this._plane&&(this._context.view.getInstance().remove(this._plane.object3D),this._plane.dispose())}async updatePlane(){this._plane||(this._plane=new Se,await this._context.view.getInstance().add(this._plane.object3D));const t=this._context.view.getBoundingBox(),e=t.getCenter(new c.Vector3),n=t.getSize(new c.Vector3);this._plane.visible=this._store.enable,this._plane.setPosition(e.x,e.y,this._store.getHeight(),n.x,n.y),this._context.view.getInstance().notifyChange()}}class Fe{constructor(){d(this,"id","builtin-flooding-plane-analysis");d(this,"name","Flooding plane");d(this,"_manager",null)}initialize(t){t.analysis.registerTool({component:Ie,icon:"bi-layers-half",name:"Flooding plane"}),this._manager=new ke(t)}}const Be=/^(\d+\.\d+)\s*,\s*(\d+\.\d+)$/;class Ne{constructor(){d(this,"name","Go to coordinates")}search(t){const e=Be.exec(t);if(e){const n=Number.parseFloat(e[1]),o=Number.parseFloat(e[2]),a={coordinates:T.WGS84(n,o),label:`${n.toFixed(6)}, ${o.toFixed(6)}`,provider:this};return Promise.resolve([a])}else return Promise.resolve([])}}class Te{constructor(){d(this,"id","builtin-coordinates-search");d(this,"name","Coordinates search")}initialize(t){t.search.registerProvider(new Ne)}}const Me=/[a-z]{3}/;class Le{constructor(){d(this,"name","Base adresse nationale (BAN)")}async search(t){if(!Me.test(t))return[];try{const n=(await c.Fetcher.fetchJson(`https://api-adresse.data.gouv.fr/search/?q=${t}`)).features.map(o=>{const s=o.properties,a=o.geometry,[u,h]=a.coordinates;return{coordinates:new T("EPSG:4326",u,h,0),label:s.label,provider:this}});return await Ve(n.map(o=>o.coordinates)),n}catch(e){if(e instanceof Z.HttpError)return[];throw e}}}async function Ve(r){const t=new URL("https://data.geopf.fr/altimetrie/1.0/calcul/alti/rest/elevation.json");t.searchParams.append("lon",r.map(n=>n.longitude).join("|")),t.searchParams.append("lat",r.map(n=>n.latitude).join("|")),t.searchParams.append("zonly","true"),t.searchParams.append("resource","ign_rge_alti_wld"),t.searchParams.append("delimiter","|"),t.searchParams.append("indent","false");const e=await c.Fetcher.fetchJson(t.toString());for(let n=0;n<r.length;n++)r[n].setAltitude(e.elevations[n]);return e}class De{constructor(){d(this,"id","builtin-geocoding-ban");d(this,"name","Base adresse nationale")}initialize(t){t.search.registerProvider(new Le)}}const F=new c.Matrix4,Oe={bbox:new c.MeshBasicMaterial({color:"#FFFF00",depthTest:!0,opacity:.2,transparent:!0}),selection:new c.MeshBasicMaterial({color:"#FF0000",depthTest:!1,opacity:.6,transparent:!0})},Ae=4186316022,ze=781010003,je=2655215786,He=3242617779,$e=919958153,Re=1307041759,U=1451395588,q=1883228015,Ue=[U,q],qe=[Ae,ze,je,He,$e,Re],G=r=>c.isObject(r)&&r.isIFCPickResult,B=class B extends L{constructor(e){super(new c.Group);d(this,"isIfcEntity",!0);d(this,"isPickableFeatures",!0);d(this,"type","IfcEntity");d(this,"_classificationCache");d(this,"_components");d(this,"_fragmentBoundingBox");d(this,"_fragmentClassifier");d(this,"_fragmentManager");d(this,"_ifcSelection");d(this,"_indexMap");d(this,"_model");d(this,"_source");this._source=e,this._components=new _.Components,this._components.ui.enabled=!1,this._components.scene=new _.SimpleScene(this._components),this._components.renderer=new _.SimpleRenderer(this._components,document.createElement("div")),this._components.camera=new _.SimpleCamera(this._components),this._components.raycaster=new _.SimpleRaycaster(this._components),this._components.init(),this._ifcSelection={bbox:{},selection:{}},this._indexMap={},this._classificationCache=null,this._fragmentBoundingBox=null}clearHighlight(e="selection"){for(const n of Object.keys(this._ifcSelection[e])){const o=this._fragmentManager.list[n],s=o==null?void 0:o.fragments[e];s!=null&&s.mesh.removeFromParent()}this.notifyChange(this),this._ifcSelection[e]={}}getBoundingBoxById(e){this.clearHighlight("bbox"),this.highlightById(e,"bbox");const n=this._fragmentBoundingBox;if(n===null)throw new Error("Must call initClassification before getBoundingBoxById");const o=this._fragmentManager;n.reset();const s=this._ifcSelection.bbox;if(!Object.keys(s).length)return;for(const p of Object.keys(s)){const g=o.list[p].fragments.bbox;n.addMesh(g.mesh)}const a=n.get(),{y:u,z:h}=a.min,{y:m,z:l}=a.max;return a.min.y=-l,a.max.y=-h,a.min.z=u,a.max.z=m,a.translate(this._model.position),this.clearHighlight("bbox"),a}getClassification(){if(this._classificationCache===null)throw new Error("Must call initClassification before getClassification");return this._classificationCache}getProperties(e){const n=[],o=this._model.properties;if(!o)return[];for(const s of this._indexMap[e]){const a=o[s];if(a==null)continue;const{name:u}=_.IfcPropertiesUtils.getEntityName(o,s);if(u!==null){if(a.type===U){const h=_.IfcPropertiesUtils.getPsetProps(o,s);if(h!==null)for(const m of h){if(o[m]==null)continue;const p=this.getProperty(m);p!==null&&n.push({parentName:u,...p})}}else if(a.type===q){const h=_.IfcPropertiesUtils.getQsetQuantities(o,s);if(h!==null)for(const m of h){const{key:l}=_.IfcPropertiesUtils.getQuantityValue(o,m);if(l===null)continue;const p=this.getProperty(m);p!==null&&n.push({parentName:u,...p})}}}}return n}getProperty(e){const n=this._model.properties;if(n===void 0)return null;const{name:o}=_.IfcPropertiesUtils.getEntityName(n,e);if(o===null)return null;const{value:s}=_.IfcPropertiesUtils.getQuantityValue(n,e);return{name:o,value:s}}highlight(e,n,o){this._ifcSelection[e][n.uuid]=new Set;const s=parseInt(o,10);this._ifcSelection[e][n.uuid].add(o),this.addComposites(e,n,s),this.regenerate(e,n.uuid);const a=n.fragment.group;if(a){const u=a.data[s][0];for(let h=0;h<u.length;h++){const m=u[h],l=a.keyFragments[m],p=this._fragmentManager.list[l];l in this._ifcSelection[e]||(this._ifcSelection[e][l]=new Set),this._ifcSelection[e][l].add(o),this.addComposites(e,p.mesh,s),this.regenerate(e,l)}}this.notifyChange(this)}highlightById(e,n="selection"){for(const o of Object.keys(e)){o in this._ifcSelection[n]||(this._ifcSelection[n][o]=new Set);const s=this._fragmentManager.list[o],a=new Set;for(const u of e[o])this._ifcSelection[n][o].add(u),a.add(parseInt(u,10));for(const u of a)this.addComposites(n,s.mesh,u);this.regenerate(n,o)}this.notifyChange(this)}pick(e,n){return super.pick(e,n).map(o=>({...o,entity:this,features:o.features,isIFCPickResult:!0,object:o.object}))}pickFeaturesFrom(e){var o,s,a;const n=e.object;if(n.fragment!=null&&e.instanceId!=null&&e.face){const u=n.fragment.getVertexBlockID(n.geometry,e.face.a),h=(o=n.fragment.getItemID(e.instanceId,u))==null?void 0:o.replace(/\..*/,"");if(h&&((a=(s=n.fragment.group)==null?void 0:s.properties)==null?void 0:a[h])!=null){const l=n.fragment.group.properties[h],f=[{ifcProperties:this.getProperties(h),itemProperties:l}];return e.features=f,f}}return[]}async initClassification(){this._classificationCache=await this.regenerateClassification(["storeys","entities"]),this._classificationCache.length===0&&(this._classificationCache=await this.regenerateClassification(["entities"])),this._fragmentBoundingBox=await this._components.tools.get(_.FragmentBoundingBox)}async preprocess(){const e=await c.Fetcher.fetchArrayBuffer(this._source.url);this._fragmentManager=await this._components.tools.get(_.FragmentManager),this._fragmentClassifier=await this._components.tools.get(_.FragmentClassifier);const n=new _.FragmentIfcLoader(this._components);n.settings.webIfc.COORDINATE_TO_ORIGIN=!0,n.settings.webIfc.OPTIMIZE_PROFILES=!0;const o=new Uint8Array(e);this._model=await n.load(o,this._source.name),this._model.rotateX(Math.PI/2);const s=new c.Vector3;if(this._source.at)this._source.at.toVector3(s),this._model.position.copy(s);else{const u=this._model.coordinationMatrix.clone().invert();s.applyMatrix4(u),this._model.position.set(s.x,-s.z,s.y)}this._model.updateWorldMatrix(!0,!0),this._model.updateMatrix(),this._model.updateMatrixWorld(!0),this.initializeEntityIndexes(),this._fragmentClassifier.byStorey(this._model),this._fragmentClassifier.byEntity(this._model),await this.initClassification(),this.object3d.add(this._model),this.onObjectCreated(this._model);const a=c.Fetcher.getContext(this._source.url);c.fillObject3DUserData(this,{filename:a.filename}),this.notifyChange(this.object3d)}addComposites(e,n,o){this.addHighlightToFragment(e,n.fragment);const s=n.fragment.composites[o];if(s)for(let a=1;a<s;a++){const u=_.toCompositeID(o,a);this._ifcSelection[e][n.uuid].add(u)}}addHighlightToFragment(e,n){if(!(e in n.fragments)){const o=n.addFragment(e,[Oe[e]]);n.blocks.count>1&&(o.setInstance(0,{ids:Array.from(n.ids),transform:F}),o.blocks.setVisibility(!1)),this._model.add(o.mesh),o.mesh.renderOrder=30,o.mesh.frustumCulled=!1,o.mesh.name=e,o.mesh.updateMatrixWorld(!0)}}initializeEntityIndexes(){this._indexMap={};const e=this._model.properties;if(e!==void 0)for(const n of qe)_.IfcPropertiesUtils.getRelationMap(e,n,(o,s)=>{const a=e[o];Ue.includes(a.type)||this.setEntityIndex(o);for(const u of s)this.setEntityIndex(u).add(o)})}regenerate(e,n){this.updateFragmentFill(e,n)}async regenerateClassification(e,n={}){const o=this._fragmentClassifier.get(),s=[],a=e[0],u=o[a];if(a==null||u==null)return s;for(const h of Object.keys(u)){const m={...n,[a]:[h]},l=await this._fragmentClassifier.find(m);if(Object.keys(l).length>0){const g=a[0].toUpperCase()+a.slice(1),y=await this.regenerateClassification(e.slice(1),m);s.push({children:y,fragments:l,name:h,treeItemName:g})}}return s}setEntityIndex(e){return e in this._indexMap||(this._indexMap[e]=new Set),this._indexMap[e]}updateFragmentFill(e,n){const o=this._ifcSelection[e][n],s=this._fragmentManager.list[n];if(s==null)return;const a=s.fragments[e];if(a==null)return;const u=s.mesh.parent;if(u==null)return;if(u.add(a.mesh),a.blocks.count>1)s.getInstance(0,F),a.setInstance(0,{ids:Array.from(s.ids),transform:F}),a.blocks.setVisibility(!0,o,!0);else{let m=0;for(const l of o){a.mesh.count=m+1;const{instanceID:p}=s.getInstanceAndBlockID(l);s.getInstance(p,F),a.setInstance(m,{ids:[l],transform:F}),m++}}}};d(B,"isIFCEntity",e=>c.isObject(e)&&e.isIfcEntity),d(B,"isIFCPickResult",e=>c.isObject(e)&&B.isIFCEntity(e.entity));let O=B;class Ge extends Q{constructor(t,e,n){super(t,e,n,{visibility:!0})}}const Ye={class:"d-flex"},We=["title"],Ze=["id"],Je={class:"list-unstyled border-start"},Qe=i.defineComponent({__name:"IfcSubtree",props:{classificationElement:{},ifcEntity:{}},setup(r){const t=r,e=c.MathUtils.generateUUID(),n=`#${e}`,o=i.ref(!1),s=c.useCameraStore(),u=c.useModuleStore().getModule(c.moduleId);function h(){if(u==null){console.warn("Cannot clip IFC element, ClippingBoxAnalysis module is not present");return}const p=t.ifcEntity.getBoundingBoxById(t.classificationElement.fragments);p&&!p.isEmpty()&&u.setClippingBox(p)}function m(){o.value=!0,t.ifcEntity.clearHighlight(),t.ifcEntity.highlightById(t.classificationElement.fragments),setTimeout(()=>o.value=!1,2e3)}function l(){const p=t.ifcEntity.getBoundingBoxById(t.classificationElement.fragments);p&&!p.isEmpty()&&s.lookTopDownAt(p)}return(p,f)=>{const g=i.resolveComponent("IfcSubtree",!0);return i.openBlock(),i.createElementBlock("div",null,[i.createElementVNode("div",Ye,[i.createElementVNode("span",{class:i.normalizeClass(["border rounded px-1 py-0 fw-normal",o.value?"text-danger border-danger":"text-secondary border-secondary"]),title:p.classificationElement.treeItemName},i.toDisplayString(p.classificationElement.treeItemName),11,We),p.classificationElement.children.length>0?(i.openBlock(),i.createBlock(c.IconList,{key:0},{default:i.withCtx(()=>[i.createVNode(c.IconListButton,{title:"Expand group",icon:"bi-chevron-down","data-bs-toggle":"collapse","data-bs-target":n,"aria-controls":i.unref(e),"aria-expanded":"true"},null,8,["aria-controls"])]),_:1})):i.createCommentVNode("",!0),i.createVNode(c._sfc_main$3,{class:i.normalizeClass(["label",o.value?"text-danger-emphasis":"text-muted"]),text:p.classificationElement.name,title:`Zoom to ${p.classificationElement.name}`,onClick:l},null,8,["class","text","title"]),i.createVNode(c.IconList,{class:"ms-1"},{default:i.withCtx(()=>[i.createVNode(c.IconListButton,{title:"Highlight",icon:"bi-highlighter",onClick:m}),i.unref(u)!=null?(i.openBlock(),i.createBlock(c.IconListButton,{key:0,title:"Clip to",icon:"bi-bounding-box",onClick:h})):i.createCommentVNode("",!0)]),_:1})]),p.classificationElement.children.length>0?(i.openBlock(),i.createElementBlock("div",{key:0,id:i.unref(e),class:"collapse show"},[i.createElementVNode("ul",Je,[(i.openBlock(!0),i.createElementBlock(i.Fragment,null,i.renderList(p.classificationElement.children,(y,C)=>(i.openBlock(),i.createElementBlock("li",{key:C},[i.createVNode(g,{"ifc-entity":t.ifcEntity,"classification-element":y},null,8,["ifc-entity","classification-element"])]))),128))])],8,Ze)):i.createCommentVNode("",!0)])}}}),Xe=c._export_sfc(Qe,[["__scopeId","data-v-804ca598"]]),Ke={key:0},et=i.defineComponent({__name:"IfcPropertyView",props:{dataset:{}},setup(r){const t=c.useDatasetStore(),e=r,n=c.refAndWatch(e.dataset,"isPreloaded");function o(){const a=s();return a==null?null:a.getClassification()}function s(){const a=t.getEntity(e.dataset);return a??null}return(a,u)=>i.unref(n)?(i.openBlock(),i.createElementBlock("div",Ke,[i.createElementVNode("ul",null,[(i.openBlock(!0),i.createElementBlock(i.Fragment,null,i.renderList(o(),(h,m)=>(i.openBlock(),i.createElementBlock("li",{key:m},[i.createVNode(Xe,{"ifc-entity":s(),"classification-element":h},null,8,["ifc-entity","classification-element"])]))),128))])])):i.createCommentVNode("",!0)}}),tt=c._export_sfc(et,[["__scopeId","data-v-d2d82ae7"]]),nt=r=>{if(G(r)){const t=r.object;if(t.fragment!=null&&r.face&&r.instanceId!=null){const e=t.fragment.getVertexBlockID(t.geometry,r.face.a),n=t.fragment.getItemID(r.instanceId,e).replace(/\..*/,"");return r.entity.highlight("selection",t,n),()=>r.entity.clearHighlight()}}return null},ot=r=>({name:r.filename,source:{url:r.file},type:"ifc",visible:!0}),st=(r,t)=>{var h,m,l,p,f,g,y,C,v;if(!G(r))return;const e=(h=r.features)==null?void 0:h.at(0);if(!e)return;t.has("IFC")||t.set("IFC",[]);const n=t.get("IFC"),{ifcProperties:o,itemProperties:s}=e,a="NULL",u=((m=s.Name)==null?void 0:m.value)??a;n.push({key:"Site",value:((p=(l=r.entity.object3d.userData)==null?void 0:l.dataset)==null?void 0:p.name)??a}),n.push({key:"IFCType",value:_.IfcCategoryMap[s.type]??a}),n.push({key:"Name",value:u}),n.push({key:"ID",value:s.expressID}),n.push({key:"GlobalId",value:((f=s.GlobalId)==null?void 0:f.value)??a}),((g=s.Description)==null?void 0:g.value)!=null&&n.push({key:"Description",value:s.Description.value}),((y=s.PredefinedType)==null?void 0:y.value)!=null&&n.push({key:"PredefinedType",value:s.PredefinedType.value}),((C=s.ObjectType)==null?void 0:C.value)!=null&&n.push({key:"ObjectType",value:s.ObjectType.value});for(const{name:b,parentName:E,value:x}of o)t.has(E)||t.set(E,[]),(v=t.get(E))==null||v.push({key:b,value:x})},it=r=>{const t=r.dataset,e=t.config,n=c.getCoordinates(e.source.position??t.get("position")),o=new O({...e.source,at:n,name:t.name});return Promise.resolve(o)};class at{constructor(){d(this,"id","builtin-ifc-loader");d(this,"name","IFC")}async initialize(t){t.datasets.registerDatasetType("ifc",{attributeExtractor:st,entityBuilder:it,fileExtensions:["ifc"],highlight:nt,icon:"bi-building",loader:ot,name:"IFC",propertyView:tt}),J.registerInspector("IfcEntity",Ge),await c.Fetcher.fetch("web-ifc.wasm").catch(e=>{console.warn("Could not load web-ifc.wasm",e)})}}const rt=i.defineComponent({__name:"OpenLayersMinimapComponent",props:{context:{}},setup(r){const t=i.ref(),e=i.shallowRef(),n=r,o=[[3e4,12],[5e4,10],[1e5,8],[4e5,6],[8e5,4]];function s(a){for(const[u,h]of o)if(a<u)return h;return o[o.length-1][1]}return i.onMounted(()=>{e.value=new z.Map({controls:[],layers:[new X({source:new K.OSM})],target:t.value,view:new z.View({center:j.fromLonLat([4,44]),projection:"EPSG:3857",zoom:5})});let a=new c.Vector3;const u=()=>{var g;const m=n.context.view.getInstance(),p=n.context.view.getCameraController().getCameraPosition(),f=p.camera.z;if(!p.camera.equals(a)){a=p.camera.clone();const y=new T(m.referenceCrs,a.x,a.y).as("EPSG:4326"),C=s(f),v=(g=e.value)==null?void 0:g.getView();v==null||v.setCenter(j.fromLonLat([y.longitude,y.latitude])),v==null||v.setZoom(C)}};n.context.events.addEventListener("updated",u);let h=!1;t.value&&(t.value.onclick=()=>{var m,l,p,f;h=!h,h?((m=t.value)==null||m.classList.add("collapsed"),(l=t.value)==null||l.classList.remove("expanded")):((p=t.value)==null||p.classList.remove("collapsed"),(f=t.value)==null||f.classList.add("expanded"))})}),i.onUnmounted(()=>{var a;(a=e.value)==null||a.dispose(),e.value=void 0}),(a,u)=>(i.openBlock(),i.createElementBlock("div",{ref_key:"target",ref:t,title:"Toggle minimap",class:"minimap expanded"},null,512))}}),lt=c._export_sfc(rt,[["__scopeId","data-v-38ee3c04"]]);class ct{constructor(){d(this,"id","builtin-minimap-openlayers");d(this,"name","Minimap")}initialize(t){t.widgets.addWidget({component:lt,id:"minimap-ol"})}}const N=class N extends c.Mesh{constructor(){super(...arguments);d(this,"isPickableFeatures",!0);d(this,"isPlyMesh",!0)}pickFeaturesFrom(e){if(this.geometry.hasAttribute("color")&&e.face){const n=this.geometry.getAttribute("color").array,o=e.face,a=[{color:new c.Color(n[o.a*3],n[o.a*3+1],n[o.a*3+2])}];return e.features=a,a}return[]}};d(N,"isPlyMesh",e=>c.isObject(e)&&e.isPlyMesh),d(N,"isPlyPickResult",e=>c.isObject(e)&&N.isPlyMesh(e==null?void 0:e.object));let M=N;class ut extends L{constructor(e){super(new c.Group);d(this,"isPlyEntity",!0);d(this,"source");this.source=e}async preprocess(){const e=await c.Fetcher.fetchArrayBuffer(this.source.url),n=this.source.at.as(this.source.featureProjection).toVector3(),s=new c.PLYLoader().parse(e),a=new c.MeshLambertMaterial({side:c.DoubleSide});s.hasAttribute("color")&&(a.vertexColors=!0),s.computeVertexNormals();const u=new M(s,a);u.name="plyModel",s.computeBoundingBox(),u.position.copy(n),u.updateWorldMatrix(!0,!0),this.object3d.add(u),this.onObjectCreated(u);const h=c.Fetcher.getContext(this.source.url);c.fillObject3DUserData(this,{filename:h.filename}),this.notifyChange(this.object3d)}}const dt=r=>{const{dataset:t,instance:e}=r,n=t.config,o=c.getCoordinates(n.source.position??t.get("position")),s=new ut({...n.source,at:o,featureProjection:e.referenceCrs});return Promise.resolve(s)},pt=(r,t)=>{var o;if(!M.isPlyPickResult(r))return;const e=(o=r.features)==null?void 0:o.at(0);if(!e)return;t.has("PLY")||t.set("PLY",[]),t.get("PLY").push({key:"Color",value:e.color})};class ht{constructor(){d(this,"id","builtin-ply-loader");d(this,"name","PLY")}initialize(t){t.datasets.registerDatasetType("ply",{attributeExtractor:pt,entityBuilder:dt,icon:"bi-file-earmark-binary",name:"PLY"})}}const mt=r=>{r.addEventListener("object-created",t=>{t.obj.traverse(n=>{var o;((o=n.userData)==null?void 0:o.class)==="IfcSpace"&&(n.visible=!1)})})};class ft{constructor(){d(this,"id","builtin-post-process-entities");d(this,"name","Post-process 3D Tiles");d(this,"_alreadyProcessedEntities",new Set);d(this,"_processings",[mt])}initialize(t){t.events.addEventListener("ready",()=>{const e=t.view.getInstance();e.addEventListener("entity-added",()=>this.processEntities(e)),this.processEntities(e)})}processEntities(t){for(const e of t.getEntities())this._alreadyProcessedEntities.has(e.id)||(L.isEntity3D(e)&&this.processEntity(e,t),this._alreadyProcessedEntities.add(e.id))}processEntity(t,e){const n={instance:e};for(const o of this._processings)o(t,n)}}const gt=r=>{const t=r.dataset.config,e=new ee({source:new te({url:`${t.source.url}/${t.source.filename}`})});return c.fillObject3DUserData(e,{filename:t.source.url}),Promise.resolve(e)};class yt{constructor(){d(this,"id","builtin-potree-loader");d(this,"name","Potree")}initialize(t){t.datasets.registerDatasetType("potree",{entityBuilder:gt,icon:"fg-multipoint",name:"Potree Point Cloud"})}}class bt{constructor(){d(this,"id","builtin-tour");d(this,"name","Tour");d(this,"_camera",null);d(this,"_cameraCallback",null);d(this,"_context",null);d(this,"_tours",null)}initialize(t){this._context=t,t.events.addEventListener("ready",this.start.bind(this))}buildTours(){const t=this._camera,e=new w.Tour({tourName:"main",useModalOverlay:!0}),n=new w.Tour({tourName:"navigating",useModalOverlay:!0}),o=new w.Tour({tourName:"analyzing",useModalOverlay:!0}),s=[{action:()=>{var l;return(l=w.activeTour)==null?void 0:l.next()},text:"Next"},{action:()=>{var l;return(l=w.activeTour)==null?void 0:l.cancel()},secondary:!0,text:"Exit"}],a=()=>{var v,b;const l=(v=w.activeTour)==null?void 0:v.getCurrentStep(),p=l==null?void 0:l.getElement(),f=p==null?void 0:p.querySelector(".shepherd-text"),g=(b=w.activeTour)==null?void 0:b.steps;if(l==null||p==null||f==null||g==null)return;const y=document.createElement("div");y.className="progress mt-3",y.setAttribute("role","progressbar"),y.style.height="2px";const C=document.createElement("div");C.className="progress-bar bg-success",C.style.width=`${100*(g.indexOf(l)/g.length)}%`,y.appendChild(C),f.appendChild(y)},u=async(l,p)=>new Promise(f=>{const g=document.getElementById(l);if(g&&!g.classList.contains("active")&&g.click(),document.querySelector(p))return f(document.querySelector(p));const y=new MutationObserver(()=>{document.querySelector(p)&&(y.disconnect(),f(document.querySelector(p)))});y.observe(document.body,{childList:!0,subtree:!0})});e.addStep({buttons:[{action:()=>{var l;(l=w.activeTour)==null||l.complete(),n.show(0)},text:"Navigating"},{action:()=>{var l;(l=w.activeTour)==null||l.complete(),o.show(0)},text:"Analyzing data"},{action:()=>{var l;return(l=w.activeTour)==null?void 0:l.cancel()},secondary:!0,text:"Exit"}],cancelIcon:{enabled:!0,label:"Exit tutorial"},id:"example-step",text:"<p>Welcome to <strong>Piero</strong>, the Giro3D application.<br/>We can guide you through the different features.</p>",title:"Welcome!",when:{show:a}}),n.addStep({attachTo:{element:"#main-view",on:"bottom"},buttons:s,id:"view",text:"<p>This is the <b>main view</b>.</p><p>Giro3D natively supports a broad range of data sources, from 2D raster and vector data, to 3D point clouds and tilesets.</p><p>Piero adds support for CityJSON and IFC files.</p>",when:{show:a}}),n.addStep({attachTo:{element:"#main-view",on:"bottom"},buttons:s,id:"navigate",text:'<p>This application integrates <a href="https://github.com/yomotsu/camera-controls">camera-controls</a>, a camera control for three.js.</p><p><b>Click</b> to move the camera. <b>Right-click</b> to rotate around a point. <b>Scroll</b> to zoom in or out.</p>',when:{hide:()=>{this._cameraCallback&&t.removeEventListener("interaction-end",this._cameraCallback),this._cameraCallback=null},show:()=>{let l=0;this._cameraCallback=()=>{var p;l+=1,l>2&&((p=w.activeTour)==null||p.next())},t.addEventListener("interaction-end",this._cameraCallback),a()}}}),n.addStep({attachTo:{element:"#toolbar",on:"right"},beforeShowPromise:()=>u("toolbar-datasets","#datasets-drop-zone"),buttons:s,id:"toolbar-layers",text:"<p>Giro3D supports multiple datasets.</p><p>You can toggle datasets as you wish with the <b>Datasets</b> panel.</p>",when:{show:a}}),n.addStep({attachTo:{element:"#basemap-list",on:"right"},beforeShowPromise:()=>u("toolbar-datasets","#datasets-drop-zone"),buttons:s,id:"basemaps",text:"<p><b>Basemaps</b> are color and elevation layers that make the basic shape and aspect of the <b>Map</b>.</p>",when:{show:a}}),n.addStep({attachTo:{element:"#overlay-list",on:"right"},beforeShowPromise:()=>u("toolbar-datasets","#datasets-drop-zone"),buttons:s,id:"overlays",text:"<p><b>Overlays</b> are vector layers in various formats (WFS, GML, GeoJSON...).</p>",when:{show:a}}),n.addStep({attachTo:{element:"#dataset-list",on:"right"},beforeShowPromise:()=>u("toolbar-datasets","#datasets-drop-zone"),buttons:s,id:"layers",text:"<p>The <b>Datasets</b> panel contains all 3D objects in the scene.</><p>You can toggle their visibility and delete them.<p><p>Most objects leverage Giro3D's adaptive resolution to optimize their display.</p>",when:{show:a}}),n.addStep({attachTo:{element:"#datasets-drop-zone",on:"right"},beforeShowPromise:()=>u("toolbar-datasets","#datasets-drop-zone"),buttons:s,id:"adddata",text:"<p>You can add your own data from your computer by <b>dragging the file</b> into this page.</p><p>While you won't benefit from Giro3D's tiling mechanism, this can be a great way to quickly visualize datasets up to 100MB.</p><p>This application supports CityJSONs, IFCs, LAS/LAZs, CSV pointclouds, and simple GeoJSON features.</p>",when:{show:a}}),n.addStep({attachTo:{element:"#main-view",on:"bottom"},buttons:s,id:"attributes",text:"<p>By clicking on any feature on the map, you can see its <strong>Attribute table</strong>. Clickable features display a cursor when hovered.</p>",when:{show:a}}),n.addStep({attachTo:{element:"#search-place-autocomplete",on:"bottom"},buttons:[{action:()=>{var l;(l=w.activeTour)==null||l.complete(),o.show(0)},text:"Analyzing data"},{action:()=>{var l;return(l=w.activeTour)==null?void 0:l.complete()},secondary:!0,text:"Exit"}],id:"widgets",text:"Giro3D is highly extensible. Here we added a widget to search and navigate to locations based on the French address database.",when:{show:a}}),o.addStep({attachTo:{element:"#annotations-fieldset",on:"right"},beforeShowPromise:()=>u("toolbar-annotations","#annotations-fieldset"),buttons:s,id:"annotation",text:"<p>You can <strong>annotate</strong> any data displayed using Giro3D native tools.<br>Select the <strong>geometry</strong> of your annotation, and <strong>click</strong> on the scene to add points. <strong>Right-click</strong> to end the shape.</p>",when:{show:a}}),o.addStep({attachTo:{element:"#annotations-fieldset",on:"right"},beforeShowPromise:()=>u("toolbar-annotations","#annotations-fieldset"),buttons:s,id:"annotations",text:"You can download your annotations as GeoJSON files. You can also upload your own by dragging them into this panel.",when:{show:a}}),c.hasExperimentalFeature("measurements")&&o.addStep({attachTo:{element:"#panel-container",on:"right"},beforeShowPromise:()=>u("toolbar-measures","#measures-fieldset"),buttons:s,id:"measurements",text:"You can add <strong>measurements</strong> to easily get distances betwween objects.<br>Once started, moving the mouse will display the measure. <strong>Click</strong> to save the measurement. <strong>Right-click</strong> to end.",when:{show:a}}),o.addStep({attachTo:{element:"#panel-container",on:"right"},beforeShowPromise:()=>u("toolbar-analysis","#panel-container .card"),buttons:[{action:()=>{var l;return(l=w.activeTour)==null?void 0:l.complete()},text:"Done!"}],id:"analysis",text:"In the <strong>Analysis</strong> panel you'll find some advanced analysis tools.",when:{show:a}});const h=()=>{const l=new URL(document.URL);l.searchParams.delete("tourStep"),l.searchParams.set("tour","none"),window.history.replaceState({},"",l.toString())},m=l=>{const p=new URL(document.URL);let f="main";l.tour.id.startsWith("navigating")?f="navigating":l.tour.id.startsWith("analyzing")&&(f="analyzing"),p.searchParams.set("tour",f),p.searchParams.set("tourStep",l.step.id),window.history.replaceState({},"",p.toString())};return e.on("cancel",h),e.on("complete",h),e.on("show",m),n.on("cancel",h),n.on("complete",h),n.on("show",m),o.on("cancel",h),o.on("complete",h),o.on("show",m),{analyzingTour:o,mainTour:e,navigatingTour:n}}getTours(){return this._tours||(this._tours=this.buildTours()),this._tours}restart(){const{mainTour:t}=this.getTours();t.show(0)}start(){if(!this._context)throw new Error("module is not initialized");const{analyzingTour:t,mainTour:e,navigatingTour:n}=this.getTours();this._camera=this._context.view.getCameraController();const o=new URL(document.URL),s=o.searchParams.get("tour")??"main";if(s!=="none"){const a=o.searchParams.get("tourStep")??0;s==="navigating"?n.show(a):s==="analyzing"?t.show(a):e.show(a)}}}exports.ClippingBoxAnalysis=c.ClippingBoxAnalysis;exports.CoordinatesSearch=Te;exports.CrossSectionAnalysis=be;exports.DownloadDataset=ve;exports.FloodingPlaneAnalysis=Fe;exports.FrenchBanGeocoder=De;exports.IFCLoader=at;exports.OpenLayersMinimap=ct;exports.PLYLoader=ht;exports.PostProcessEntities=ft;exports.PotreeLoader=yt;exports.Tour=bt;
|
|
3
2
|
//# sourceMappingURL=modules.cjs.js.map
|