@selvajs/visualization 1.6.0-beta.6 → 1.6.0-beta.8

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/scene.cjs CHANGED
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./gpu-ownership-ilj3JEdn.cjs"),t=require("./merged-draw-SXYrxFt4.cjs");let n=require("three");n=e.s(n,1);const r=/* @__PURE__ */ new Set([`grid`,`floor`,`label-layer`,`measure`]);function i(e){return!(e instanceof n.Camera)&&!(e instanceof n.Light)&&!r.has(e.userData?.id)}function a(e){return e.children.filter(i)}function o(e){return e.replace(/^Line(Segments)?2$/,`Curve`).replace(`Mesh`,``).replace(`Object3D`,`Obj`)||e}function s(e){return e.userData?.name||e.userData?.fileName||e.name||o(e.type)}function c(e){return o(e.type)}function l(e){let t=e.userData;if(!t)return null;if(typeof t.trackingKey==`string`&&t.trackingKey)return t.trackingKey;if(typeof t.id==`string`&&t.id)return t.id;let n=typeof t.name==`string`?t.name:e.name,r=typeof t.layer==`string`?t.layer:``;return n?`name${r}${n}`:null}function u(e){return l(e)??e.uuid}function d(e){let t=e.userData?.members;return!Array.isArray(t)||t.length===0?[u(e)]:t.map((t,n)=>typeof t.trackingKey==`string`&&t.trackingKey?t.trackingKey:t.name?`name${t.layer}${t.name}`:`${e.uuid}${n}`)}function f(e){let t=e.userData?.members;return Array.isArray(t)&&t.length>0?t:null}const p=(e,t)=>e.userData?.layer||e.userData?.category||t;function m(e,t){let n=[],r=/* @__PURE__ */ new Map,i=e=>{let t=r.get(e)??0;return r.set(e,t+1),t===0?e:`${e}#${t}`};for(let r of a(e)){let e=f(r);if(!e){let e=u(r);n.push({object:r,memberIndex:null,key:e,rowKey:i(e),label:s(r),layer:p(r,t)});continue}let a=d(r);e.forEach((e,s)=>{let c=a[s]??`${r.uuid}:${s}`;n.push({object:r,memberIndex:s,key:c,rowKey:i(c),label:e.name||o(r.type),layer:e.layer||p(r,t)})})}return n}const h=`Default`;function g(e){let t=/* @__PURE__ */ new Map;for(let n of e){let e=n.userData?.layer||n.userData?.category||`Default`,r=t.get(e);r||(r=[],t.set(e,r)),r.push(n)}return t}function _(e,t){if(!t.trim())return e;let n=t.toLowerCase(),r=/* @__PURE__ */ new Map;for(let[t,i]of e){let e=t.toLowerCase().includes(n)?i:i.filter(e=>s(e).toLowerCase().includes(n));e.length>0&&r.set(t,e)}return r}function v(e){let t=/* @__PURE__ */ new Map;for(let n of e){let e=t.get(n.layer);e||(e=[],t.set(n.layer,e)),e.push(n)}return t}function y(e,t){if(!t.trim())return e;let n=t.toLowerCase(),r=/* @__PURE__ */ new Map;for(let[t,i]of e){let e=t.toLowerCase().includes(n)?i:i.filter(e=>e.label.toLowerCase().includes(n));e.length>0&&r.set(t,e)}return r}function b(e,n){let r=e;if(!r.isMesh||!Array.isArray(r.userData?.members))return;let i=/* @__PURE__ */ new Set;d(r).forEach((e,t)=>{n.has(e)&&i.add(t)}),t.a(r,i)}function x(e=/* @__PURE__ */ new Set){let t=t=>d(t).every(t=>e.has(t)),n={hidden:e,isHidden:t,setVisible(t,n){t.visible=n,t.traverse(e=>{e.visible=n});for(let r of d(t))n?e.delete(r):e.add(r);b(t,e)},isEntryHidden:n=>n.memberIndex===null?t(n.object):e.has(n.key),setEntryVisible(t,r){t.memberIndex===null?n.setVisible(t.object,r):(r?e.delete(t.key):e.add(t.key),b(t.object,e),r&&!t.object.visible&&t.object.traverse(e=>{e.visible=!0}))},isLayerHidden:e=>e.length>0&&e.every(e=>n.isHidden(e)),isLayerPartial(e){let t=e.filter(e=>n.isHidden(e)).length;return t>0&&t<e.length},toggleLayer(e){let t=n.isLayerHidden(e);for(let r of e)n.setVisible(r,t)},applyTo(n){for(let r of n)b(r,e),t(r)&&(r.visible=!1,r.traverse(e=>{e.visible=!1}))},reset:()=>e.clear()};return n}function S(e=/* @__PURE__ */ new Set){let t=null,n=/* @__PURE__ */ new Set,r=e=>{t=e;for(let t of n)t(e)};return{selected:e,get anchor(){return t},isSelected:t=>e.has(t),select(n,i,a){if(i.shiftKey&&t){let r=a(),o=r.indexOf(t),s=r.indexOf(n);if(o!==-1&&s!==-1){let[t,n]=o<s?[o,s]:[s,o];i.toggleKey||e.clear();for(let i=t;i<=n;i++)e.add(r[i])}}else i.toggleKey?e.has(n)?e.delete(n):e.add(n):(e.clear(),e.add(n)),r(n)},clear(){e.clear(),r(null)},onAnchorChange(e){return n.add(e),()=>n.delete(e)}}}function C(e,t={}){let n=t.sets?.collapsed??/* @__PURE__ */ new Set,r=x(t.sets?.hidden),i=S(t.sets?.selected),o={visibility:r,selection:i,collapsed:n,objects:()=>a(e),entries:()=>m(e,h),entryGroups:(t=``)=>y(v(m(e,h)),t),layerGroups:(t=``)=>_(g(a(e)),t),isCollapsed:e=>n.has(e),toggleCollapsed(e){n.has(e)?n.delete(e):n.add(e)},toggleObject(e){if(i.isSelected(e.uuid)&&i.selected.size>1){let e=o.objects().filter(e=>i.isSelected(e.uuid)),t=e.every(e=>r.isHidden(e));for(let n of e)r.setVisible(n,t)}else r.setVisible(e,r.isHidden(e))},toggleEntry(e){if(i.isSelected(e.key)&&i.selected.size>1){let e=o.entries().filter(e=>i.isSelected(e.key)),t=e.every(e=>r.isEntryHidden(e));for(let n of e)r.setEntryVisible(n,t)}else r.setEntryVisible(e,r.isEntryHidden(e))},select(e,t,n){i.select(e,t,()=>o.flatVisibleUuids(n))},onAnchorChange:e=>i.onAnchorChange(e),flatVisibleUuids(e){let t=[];for(let[r,i]of o.entryGroups(e))if(!n.has(r))for(let e of i)t.push(e.key);return t},applyTo(){r.applyTo(o.objects()),i.clear()},reset(){r.reset(),i.clear()}};return o}exports.createSceneOutliner=C,exports.getMemberKeys=d,exports.getObjectLabel=s,exports.getTrackingKey=u,exports.getTypeLabel=c;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./gpu-ownership-ilj3JEdn.cjs"),t=require("./merged-draw-oKAKlXCQ.cjs");let n=require("three");n=e.s(n,1);const r=/* @__PURE__ */ new Set([`grid`,`floor`,`label-layer`,`measure`]);function i(e){return!(e instanceof n.Camera)&&!(e instanceof n.Light)&&!r.has(e.userData?.id)}function a(e){return e.children.filter(i)}function o(e){return e.replace(/^Line(Segments)?2$/,`Curve`).replace(`Mesh`,``).replace(`Object3D`,`Obj`)||e}function s(e){return e.userData?.name||e.userData?.fileName||e.name||o(e.type)}function c(e){return o(e.type)}function l(e){let t=e.userData;if(!t)return null;if(typeof t.trackingKey==`string`&&t.trackingKey)return t.trackingKey;if(typeof t.id==`string`&&t.id)return t.id;let n=typeof t.name==`string`?t.name:e.name,r=typeof t.layer==`string`?t.layer:``;return n?`name${r}${n}`:null}function u(e){return l(e)??e.uuid}function d(e){let t=e.userData?.members;return!Array.isArray(t)||t.length===0?[u(e)]:t.map((t,n)=>typeof t.trackingKey==`string`&&t.trackingKey?t.trackingKey:t.name?`name${t.layer}${t.name}`:`${e.uuid}${n}`)}function f(e){let t=e.userData?.members;return Array.isArray(t)&&t.length>0?t:null}const p=(e,t)=>e.userData?.layer||e.userData?.category||t;function m(e,t){let n=[],r=/* @__PURE__ */ new Map,i=e=>{let t=r.get(e)??0;return r.set(e,t+1),t===0?e:`${e}#${t}`};for(let r of a(e)){let e=f(r);if(!e){let e=u(r);n.push({object:r,memberIndex:null,key:e,rowKey:i(e),label:s(r),layer:p(r,t)});continue}let a=d(r);e.forEach((e,s)=>{let c=a[s]??`${r.uuid}:${s}`;n.push({object:r,memberIndex:s,key:c,rowKey:i(c),label:e.name||o(r.type),layer:e.layer||p(r,t)})})}return n}const h=`Default`;function g(e){let t=/* @__PURE__ */ new Map;for(let n of e){let e=n.userData?.layer||n.userData?.category||`Default`,r=t.get(e);r||(r=[],t.set(e,r)),r.push(n)}return t}function _(e,t){if(!t.trim())return e;let n=t.toLowerCase(),r=/* @__PURE__ */ new Map;for(let[t,i]of e){let e=t.toLowerCase().includes(n)?i:i.filter(e=>s(e).toLowerCase().includes(n));e.length>0&&r.set(t,e)}return r}function v(e){let t=/* @__PURE__ */ new Map;for(let n of e){let e=t.get(n.layer);e||(e=[],t.set(n.layer,e)),e.push(n)}return t}function y(e,t){if(!t.trim())return e;let n=t.toLowerCase(),r=/* @__PURE__ */ new Map;for(let[t,i]of e){let e=t.toLowerCase().includes(n)?i:i.filter(e=>e.label.toLowerCase().includes(n));e.length>0&&r.set(t,e)}return r}function b(e,n){let r=e;if(!r.isMesh||!Array.isArray(r.userData?.members))return;let i=/* @__PURE__ */ new Set;d(r).forEach((e,t)=>{n.has(e)&&i.add(t)}),t.a(r,i)}function x(e=/* @__PURE__ */ new Set){let t=t=>d(t).every(t=>e.has(t)),n={hidden:e,isHidden:t,setVisible(t,n){t.visible=n,t.traverse(e=>{e.visible=n});for(let r of d(t))n?e.delete(r):e.add(r);b(t,e)},isEntryHidden:n=>n.memberIndex===null?t(n.object):e.has(n.key),setEntryVisible(t,r){t.memberIndex===null?n.setVisible(t.object,r):(r?e.delete(t.key):e.add(t.key),b(t.object,e),r&&!t.object.visible&&t.object.traverse(e=>{e.visible=!0}))},isLayerHidden:e=>e.length>0&&e.every(e=>n.isHidden(e)),isLayerPartial(e){let t=e.filter(e=>n.isHidden(e)).length;return t>0&&t<e.length},toggleLayer(e){let t=n.isLayerHidden(e);for(let r of e)n.setVisible(r,t)},applyTo(n){for(let r of n)b(r,e),t(r)&&(r.visible=!1,r.traverse(e=>{e.visible=!1}))},reset:()=>e.clear()};return n}function S(e=/* @__PURE__ */ new Set){let t=null,n=/* @__PURE__ */ new Set,r=e=>{t=e;for(let t of n)t(e)};return{selected:e,get anchor(){return t},isSelected:t=>e.has(t),select(n,i,a){if(i.shiftKey&&t){let r=a(),o=r.indexOf(t),s=r.indexOf(n);if(o!==-1&&s!==-1){let[t,n]=o<s?[o,s]:[s,o];i.toggleKey||e.clear();for(let i=t;i<=n;i++)e.add(r[i])}}else i.toggleKey?e.has(n)?e.delete(n):e.add(n):(e.clear(),e.add(n)),r(n)},clear(){e.clear(),r(null)},onAnchorChange(e){return n.add(e),()=>n.delete(e)}}}function C(e,t={}){let n=t.sets?.collapsed??/* @__PURE__ */ new Set,r=x(t.sets?.hidden),i=S(t.sets?.selected),o={visibility:r,selection:i,collapsed:n,objects:()=>a(e),entries:()=>m(e,h),entryGroups:(t=``)=>y(v(m(e,h)),t),layerGroups:(t=``)=>_(g(a(e)),t),isCollapsed:e=>n.has(e),toggleCollapsed(e){n.has(e)?n.delete(e):n.add(e)},toggleObject(e){if(i.isSelected(e.uuid)&&i.selected.size>1){let e=o.objects().filter(e=>i.isSelected(e.uuid)),t=e.every(e=>r.isHidden(e));for(let n of e)r.setVisible(n,t)}else r.setVisible(e,r.isHidden(e))},toggleEntry(e){if(i.isSelected(e.key)&&i.selected.size>1){let e=o.entries().filter(e=>i.isSelected(e.key)),t=e.every(e=>r.isEntryHidden(e));for(let n of e)r.setEntryVisible(n,t)}else r.setEntryVisible(e,r.isEntryHidden(e))},select(e,t,n){i.select(e,t,()=>o.flatVisibleUuids(n))},onAnchorChange:e=>i.onAnchorChange(e),flatVisibleUuids(e){let t=[];for(let[r,i]of o.entryGroups(e))if(!n.has(r))for(let e of i)t.push(e.key);return t},applyTo(){r.applyTo(o.objects()),i.clear()},reset(){r.reset(),i.clear()}};return o}exports.createSceneOutliner=C,exports.getMemberKeys=d,exports.getObjectLabel=s,exports.getTrackingKey=u,exports.getTypeLabel=c;
2
2
  //# sourceMappingURL=scene.cjs.map
package/dist/scene.js CHANGED
@@ -1,2 +1,2 @@
1
- import{a as e}from"./merged-draw-CO5Ev9ia.js";import*as t from"three";const n=/* @__PURE__ */ new Set([`grid`,`floor`,`label-layer`,`measure`]);function r(e){return!(e instanceof t.Camera)&&!(e instanceof t.Light)&&!n.has(e.userData?.id)}function i(e){return e.children.filter(r)}function a(e){return e.replace(/^Line(Segments)?2$/,`Curve`).replace(`Mesh`,``).replace(`Object3D`,`Obj`)||e}function o(e){return e.userData?.name||e.userData?.fileName||e.name||a(e.type)}function s(e){return a(e.type)}function c(e){let t=e.userData;if(!t)return null;if(typeof t.trackingKey==`string`&&t.trackingKey)return t.trackingKey;if(typeof t.id==`string`&&t.id)return t.id;let n=typeof t.name==`string`?t.name:e.name,r=typeof t.layer==`string`?t.layer:``;return n?`name${r}${n}`:null}function l(e){return c(e)??e.uuid}function u(e){let t=e.userData?.members;return!Array.isArray(t)||t.length===0?[l(e)]:t.map((t,n)=>typeof t.trackingKey==`string`&&t.trackingKey?t.trackingKey:t.name?`name${t.layer}${t.name}`:`${e.uuid}${n}`)}function d(e){let t=e.userData?.members;return Array.isArray(t)&&t.length>0?t:null}const f=(e,t)=>e.userData?.layer||e.userData?.category||t;function p(e,t){let n=[],r=/* @__PURE__ */ new Map,s=e=>{let t=r.get(e)??0;return r.set(e,t+1),t===0?e:`${e}#${t}`};for(let r of i(e)){let e=d(r);if(!e){let e=l(r);n.push({object:r,memberIndex:null,key:e,rowKey:s(e),label:o(r),layer:f(r,t)});continue}let i=u(r);e.forEach((e,o)=>{let c=i[o]??`${r.uuid}:${o}`;n.push({object:r,memberIndex:o,key:c,rowKey:s(c),label:e.name||a(r.type),layer:e.layer||f(r,t)})})}return n}const m=`Default`;function h(e){let t=/* @__PURE__ */ new Map;for(let n of e){let e=n.userData?.layer||n.userData?.category||`Default`,r=t.get(e);r||(r=[],t.set(e,r)),r.push(n)}return t}function g(e,t){if(!t.trim())return e;let n=t.toLowerCase(),r=/* @__PURE__ */ new Map;for(let[t,i]of e){let e=t.toLowerCase().includes(n)?i:i.filter(e=>o(e).toLowerCase().includes(n));e.length>0&&r.set(t,e)}return r}function _(e){let t=/* @__PURE__ */ new Map;for(let n of e){let e=t.get(n.layer);e||(e=[],t.set(n.layer,e)),e.push(n)}return t}function v(e,t){if(!t.trim())return e;let n=t.toLowerCase(),r=/* @__PURE__ */ new Map;for(let[t,i]of e){let e=t.toLowerCase().includes(n)?i:i.filter(e=>e.label.toLowerCase().includes(n));e.length>0&&r.set(t,e)}return r}function y(t,n){let r=t;if(!r.isMesh||!Array.isArray(r.userData?.members))return;let i=/* @__PURE__ */ new Set;u(r).forEach((e,t)=>{n.has(e)&&i.add(t)}),e(r,i)}function b(e=/* @__PURE__ */ new Set){let t=t=>u(t).every(t=>e.has(t)),n={hidden:e,isHidden:t,setVisible(t,n){t.visible=n,t.traverse(e=>{e.visible=n});for(let r of u(t))n?e.delete(r):e.add(r);y(t,e)},isEntryHidden:n=>n.memberIndex===null?t(n.object):e.has(n.key),setEntryVisible(t,r){t.memberIndex===null?n.setVisible(t.object,r):(r?e.delete(t.key):e.add(t.key),y(t.object,e),r&&!t.object.visible&&t.object.traverse(e=>{e.visible=!0}))},isLayerHidden:e=>e.length>0&&e.every(e=>n.isHidden(e)),isLayerPartial(e){let t=e.filter(e=>n.isHidden(e)).length;return t>0&&t<e.length},toggleLayer(e){let t=n.isLayerHidden(e);for(let r of e)n.setVisible(r,t)},applyTo(n){for(let r of n)y(r,e),t(r)&&(r.visible=!1,r.traverse(e=>{e.visible=!1}))},reset:()=>e.clear()};return n}function x(e=/* @__PURE__ */ new Set){let t=null,n=/* @__PURE__ */ new Set,r=e=>{t=e;for(let t of n)t(e)};return{selected:e,get anchor(){return t},isSelected:t=>e.has(t),select(n,i,a){if(i.shiftKey&&t){let r=a(),o=r.indexOf(t),s=r.indexOf(n);if(o!==-1&&s!==-1){let[t,n]=o<s?[o,s]:[s,o];i.toggleKey||e.clear();for(let i=t;i<=n;i++)e.add(r[i])}}else i.toggleKey?e.has(n)?e.delete(n):e.add(n):(e.clear(),e.add(n)),r(n)},clear(){e.clear(),r(null)},onAnchorChange(e){return n.add(e),()=>n.delete(e)}}}function S(e,t={}){let n=t.sets?.collapsed??/* @__PURE__ */ new Set,r=b(t.sets?.hidden),a=x(t.sets?.selected),o={visibility:r,selection:a,collapsed:n,objects:()=>i(e),entries:()=>p(e,m),entryGroups:(t=``)=>v(_(p(e,m)),t),layerGroups:(t=``)=>g(h(i(e)),t),isCollapsed:e=>n.has(e),toggleCollapsed(e){n.has(e)?n.delete(e):n.add(e)},toggleObject(e){if(a.isSelected(e.uuid)&&a.selected.size>1){let e=o.objects().filter(e=>a.isSelected(e.uuid)),t=e.every(e=>r.isHidden(e));for(let n of e)r.setVisible(n,t)}else r.setVisible(e,r.isHidden(e))},toggleEntry(e){if(a.isSelected(e.key)&&a.selected.size>1){let e=o.entries().filter(e=>a.isSelected(e.key)),t=e.every(e=>r.isEntryHidden(e));for(let n of e)r.setEntryVisible(n,t)}else r.setEntryVisible(e,r.isEntryHidden(e))},select(e,t,n){a.select(e,t,()=>o.flatVisibleUuids(n))},onAnchorChange:e=>a.onAnchorChange(e),flatVisibleUuids(e){let t=[];for(let[r,i]of o.entryGroups(e))if(!n.has(r))for(let e of i)t.push(e.key);return t},applyTo(){r.applyTo(o.objects()),a.clear()},reset(){r.reset(),a.clear()}};return o}export{S as createSceneOutliner,u as getMemberKeys,o as getObjectLabel,l as getTrackingKey,s as getTypeLabel};
1
+ import{a as e}from"./merged-draw-DXJK-rdo.js";import*as t from"three";const n=/* @__PURE__ */ new Set([`grid`,`floor`,`label-layer`,`measure`]);function r(e){return!(e instanceof t.Camera)&&!(e instanceof t.Light)&&!n.has(e.userData?.id)}function i(e){return e.children.filter(r)}function a(e){return e.replace(/^Line(Segments)?2$/,`Curve`).replace(`Mesh`,``).replace(`Object3D`,`Obj`)||e}function o(e){return e.userData?.name||e.userData?.fileName||e.name||a(e.type)}function s(e){return a(e.type)}function c(e){let t=e.userData;if(!t)return null;if(typeof t.trackingKey==`string`&&t.trackingKey)return t.trackingKey;if(typeof t.id==`string`&&t.id)return t.id;let n=typeof t.name==`string`?t.name:e.name,r=typeof t.layer==`string`?t.layer:``;return n?`name${r}${n}`:null}function l(e){return c(e)??e.uuid}function u(e){let t=e.userData?.members;return!Array.isArray(t)||t.length===0?[l(e)]:t.map((t,n)=>typeof t.trackingKey==`string`&&t.trackingKey?t.trackingKey:t.name?`name${t.layer}${t.name}`:`${e.uuid}${n}`)}function d(e){let t=e.userData?.members;return Array.isArray(t)&&t.length>0?t:null}const f=(e,t)=>e.userData?.layer||e.userData?.category||t;function p(e,t){let n=[],r=/* @__PURE__ */ new Map,s=e=>{let t=r.get(e)??0;return r.set(e,t+1),t===0?e:`${e}#${t}`};for(let r of i(e)){let e=d(r);if(!e){let e=l(r);n.push({object:r,memberIndex:null,key:e,rowKey:s(e),label:o(r),layer:f(r,t)});continue}let i=u(r);e.forEach((e,o)=>{let c=i[o]??`${r.uuid}:${o}`;n.push({object:r,memberIndex:o,key:c,rowKey:s(c),label:e.name||a(r.type),layer:e.layer||f(r,t)})})}return n}const m=`Default`;function h(e){let t=/* @__PURE__ */ new Map;for(let n of e){let e=n.userData?.layer||n.userData?.category||`Default`,r=t.get(e);r||(r=[],t.set(e,r)),r.push(n)}return t}function g(e,t){if(!t.trim())return e;let n=t.toLowerCase(),r=/* @__PURE__ */ new Map;for(let[t,i]of e){let e=t.toLowerCase().includes(n)?i:i.filter(e=>o(e).toLowerCase().includes(n));e.length>0&&r.set(t,e)}return r}function _(e){let t=/* @__PURE__ */ new Map;for(let n of e){let e=t.get(n.layer);e||(e=[],t.set(n.layer,e)),e.push(n)}return t}function v(e,t){if(!t.trim())return e;let n=t.toLowerCase(),r=/* @__PURE__ */ new Map;for(let[t,i]of e){let e=t.toLowerCase().includes(n)?i:i.filter(e=>e.label.toLowerCase().includes(n));e.length>0&&r.set(t,e)}return r}function y(t,n){let r=t;if(!r.isMesh||!Array.isArray(r.userData?.members))return;let i=/* @__PURE__ */ new Set;u(r).forEach((e,t)=>{n.has(e)&&i.add(t)}),e(r,i)}function b(e=/* @__PURE__ */ new Set){let t=t=>u(t).every(t=>e.has(t)),n={hidden:e,isHidden:t,setVisible(t,n){t.visible=n,t.traverse(e=>{e.visible=n});for(let r of u(t))n?e.delete(r):e.add(r);y(t,e)},isEntryHidden:n=>n.memberIndex===null?t(n.object):e.has(n.key),setEntryVisible(t,r){t.memberIndex===null?n.setVisible(t.object,r):(r?e.delete(t.key):e.add(t.key),y(t.object,e),r&&!t.object.visible&&t.object.traverse(e=>{e.visible=!0}))},isLayerHidden:e=>e.length>0&&e.every(e=>n.isHidden(e)),isLayerPartial(e){let t=e.filter(e=>n.isHidden(e)).length;return t>0&&t<e.length},toggleLayer(e){let t=n.isLayerHidden(e);for(let r of e)n.setVisible(r,t)},applyTo(n){for(let r of n)y(r,e),t(r)&&(r.visible=!1,r.traverse(e=>{e.visible=!1}))},reset:()=>e.clear()};return n}function x(e=/* @__PURE__ */ new Set){let t=null,n=/* @__PURE__ */ new Set,r=e=>{t=e;for(let t of n)t(e)};return{selected:e,get anchor(){return t},isSelected:t=>e.has(t),select(n,i,a){if(i.shiftKey&&t){let r=a(),o=r.indexOf(t),s=r.indexOf(n);if(o!==-1&&s!==-1){let[t,n]=o<s?[o,s]:[s,o];i.toggleKey||e.clear();for(let i=t;i<=n;i++)e.add(r[i])}}else i.toggleKey?e.has(n)?e.delete(n):e.add(n):(e.clear(),e.add(n)),r(n)},clear(){e.clear(),r(null)},onAnchorChange(e){return n.add(e),()=>n.delete(e)}}}function S(e,t={}){let n=t.sets?.collapsed??/* @__PURE__ */ new Set,r=b(t.sets?.hidden),a=x(t.sets?.selected),o={visibility:r,selection:a,collapsed:n,objects:()=>i(e),entries:()=>p(e,m),entryGroups:(t=``)=>v(_(p(e,m)),t),layerGroups:(t=``)=>g(h(i(e)),t),isCollapsed:e=>n.has(e),toggleCollapsed(e){n.has(e)?n.delete(e):n.add(e)},toggleObject(e){if(a.isSelected(e.uuid)&&a.selected.size>1){let e=o.objects().filter(e=>a.isSelected(e.uuid)),t=e.every(e=>r.isHidden(e));for(let n of e)r.setVisible(n,t)}else r.setVisible(e,r.isHidden(e))},toggleEntry(e){if(a.isSelected(e.key)&&a.selected.size>1){let e=o.entries().filter(e=>a.isSelected(e.key)),t=e.every(e=>r.isEntryHidden(e));for(let n of e)r.setEntryVisible(n,t)}else r.setEntryVisible(e,r.isEntryHidden(e))},select(e,t,n){a.select(e,t,()=>o.flatVisibleUuids(n))},onAnchorChange:e=>a.onAnchorChange(e),flatVisibleUuids(e){let t=[];for(let[r,i]of o.entryGroups(e))if(!n.has(r))for(let e of i)t.push(e.key);return t},applyTo(){r.applyTo(o.objects()),a.clear()},reset(){r.reset(),a.clear()}};return o}export{S as createSceneOutliner,u as getMemberKeys,o as getObjectLabel,l as getTrackingKey,s as getTypeLabel};
2
2
  //# sourceMappingURL=scene.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@selvajs/visualization",
3
- "version": "1.6.0-beta.6",
3
+ "version": "1.6.0-beta.8",
4
4
  "description": "Headless, extensible viewer core for Selva — parse, render and scene layers over Three.js",
5
5
  "author": "VektorNode",
6
6
  "license": "MIT",
@@ -1,2 +0,0 @@
1
- import{i as e,t}from"./gpu-ownership-DcHWbATk.js";import*as n from"three";const r=/* @__PURE__ */ new WeakMap,i=/* @__PURE__ */ new WeakMap,a=/* @__PURE__ */ new Set;function o(e){let t=e.userData?.members;return!Array.isArray(t)||t.length===0||t.some(e=>e.indexStart==null||e.indexCount==null)?null:t}function s(e){let t=r.get(e);return t||(t={base:Array.isArray(e.material)?e.material[0]:e.material,hidden:a,highlight:null},r.set(e,t)),t}function c(r){let i=r.geometry;if(!e(i))return i;let a=new n.BufferGeometry;a.setIndex(i.index);for(let[e,t]of Object.entries(i.attributes))a.setAttribute(e,t);return a.boundingBox=i.boundingBox?.clone()??null,a.boundingSphere=i.boundingSphere?.clone()??null,t(a,i),r.geometry=a,a}function l(e,t,n){let i=c(e);if(i.clearGroups(),n.hidden.size===0&&!n.highlight){e.material=n.base,r.delete(e);return}let a=-1,o=0,s=0,l=()=>{a>=0&&i.addGroup(a,o-a,s),a=-1};for(let e=0;e<t.length;e++){if(n.hidden.has(e)){l();continue}let{indexStart:r,indexCount:i}=t[e],c=+(n.highlight?.index===e);(a<0||c!==s||r!==o)&&(l(),a=r,s=c),o=r+i}l(),e.material=n.highlight?[n.base,n.highlight.material]:[n.base]}function u(e,t){let n=o(e);if(!n)return;let r=s(e);t(r),l(e,n,r),i.get(e)?.forEach(e=>e())}function d(e){return r.get(e)?.hidden??a}function f(e,t){let n=d(e);n.size===t.size&&[...t].every(e=>n.has(e))||u(e,e=>{e.hidden=new Set(t)})}function p(e){return r.get(e)?.base??(Array.isArray(e.material)?e.material[0]:e.material)}function m(e,t,n){u(e,e=>{e.highlight={index:t,material:n}})}function h(e){r.get(e)?.highlight&&u(e,e=>{e.highlight=null})}function g(e,t){let n=i.get(e);return n||i.set(e,n=/* @__PURE__ */ new Set),n.add(t),()=>n.delete(t)}export{f as a,g as i,p as n,m as o,d as r,h as t};
2
- //# sourceMappingURL=merged-draw-CO5Ev9ia.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"merged-draw-CO5Ev9ia.js","names":["isCachedGeometry","THREE","states","listeners","NONE","windowsOf","members","mesh","m","stateOf","state","ownGeometry","shared","own","name","attribute","borrowGeometry","rebuild","geometry","runStart","runEnd","runMaterial","flush","i","windows","material","indexStart","indexCount","update","change","listener","getHiddenMembers","setHiddenMembers","current","hidden","getBaseMaterial","setMemberHighlight","clearMemberHighlight","onMemberDrawChange","set"],"sources":["../src/shared/merged-draw.ts"],"sourcesContent":["// ============================================================================\n// Which parts of a merged mesh draw, and with what material\n// ============================================================================\n//\n// A merged mesh draws many source members in one call. Two features draw only part of it: hiding\n// a member (`scene/`) and tinting the selected member (`render/`). Both need geometry groups, and\n// three honours groups only when `material` is an array: with a single material it draws the whole\n// index range and ignores them. So one owner builds the groups and the material array from both\n// states together. Two writers each replacing the groups would undo each other.\n//\n// Members are addressed by their index in `userData.members`, which carries each member's window\n// into the index buffer (`finalizeMergedMesh`).\n\nimport * as THREE from 'three';\n\nimport { borrowGeometry, isCachedGeometry } from './gpu-ownership.js';\n\ninterface MemberWindow {\n\tindexStart?: number;\n\tindexCount?: number;\n}\n\ninterface DrawState {\n\t/** The mesh's own material, restored once nothing is hidden or highlighted. */\n\tbase: THREE.Material;\n\thidden: ReadonlySet<number>;\n\thighlight: { index: number; material: THREE.Material } | null;\n}\n\nconst states = new WeakMap<THREE.Mesh, DrawState>();\nconst listeners = new WeakMap<THREE.Mesh, Set<() => void>>();\n\nconst NONE: ReadonlySet<number> = new Set();\n\nfunction windowsOf(mesh: THREE.Mesh): Required<MemberWindow>[] | null {\n\tconst members = mesh.userData?.members as MemberWindow[] | undefined;\n\tif (!Array.isArray(members) || members.length === 0) return null;\n\t// One member without a window means the ranges can't be rebuilt without dropping geometry.\n\tif (members.some((m) => m.indexStart == null || m.indexCount == null)) return null;\n\treturn members as Required<MemberWindow>[];\n}\n\nfunction stateOf(mesh: THREE.Mesh): DrawState {\n\tlet state = states.get(mesh);\n\tif (!state) {\n\t\tconst base = Array.isArray(mesh.material) ? mesh.material[0]! : mesh.material;\n\t\tstate = { base, hidden: NONE, highlight: null };\n\t\tstates.set(mesh, state);\n\t}\n\treturn state;\n}\n\n// Groups live on the geometry, and a cached geometry can back two meshes at once (two identical\n// branches), so a mesh gets its own geometry over the same attributes before writing any.\nfunction ownGeometry(mesh: THREE.Mesh): THREE.BufferGeometry {\n\tconst shared = mesh.geometry;\n\tif (!isCachedGeometry(shared)) return shared;\n\n\tconst own = new THREE.BufferGeometry();\n\town.setIndex(shared.index);\n\tfor (const [name, attribute] of Object.entries(shared.attributes))\n\t\town.setAttribute(name, attribute);\n\town.boundingBox = shared.boundingBox?.clone() ?? null;\n\town.boundingSphere = shared.boundingSphere?.clone() ?? null;\n\tborrowGeometry(own, shared);\n\tmesh.geometry = own;\n\treturn own;\n}\n\nfunction rebuild(mesh: THREE.Mesh, windows: Required<MemberWindow>[], state: DrawState): void {\n\tconst geometry = ownGeometry(mesh);\n\tgeometry.clearGroups();\n\n\tif (state.hidden.size === 0 && !state.highlight) {\n\t\tmesh.material = state.base;\n\t\tstates.delete(mesh);\n\t\treturn;\n\t}\n\n\t// Coalesce neighbours with the same material, so hiding one member costs two draws, not N.\n\tlet runStart = -1;\n\tlet runEnd = 0;\n\tlet runMaterial = 0;\n\tconst flush = () => {\n\t\tif (runStart >= 0) geometry.addGroup(runStart, runEnd - runStart, runMaterial);\n\t\trunStart = -1;\n\t};\n\tfor (let i = 0; i < windows.length; i++) {\n\t\tif (state.hidden.has(i)) {\n\t\t\tflush();\n\t\t\tcontinue;\n\t\t}\n\t\tconst { indexStart, indexCount } = windows[i]!;\n\t\tconst material = state.highlight?.index === i ? 1 : 0;\n\t\tif (runStart < 0 || material !== runMaterial || indexStart !== runEnd) {\n\t\t\tflush();\n\t\t\trunStart = indexStart;\n\t\t\trunMaterial = material;\n\t\t}\n\t\trunEnd = indexStart + indexCount;\n\t}\n\tflush();\n\n\tmesh.material = state.highlight ? [state.base, state.highlight.material] : [state.base];\n}\n\nfunction update(mesh: THREE.Mesh, change: (state: DrawState) => void): void {\n\tconst windows = windowsOf(mesh);\n\tif (!windows) return;\n\tconst state = stateOf(mesh);\n\tchange(state);\n\trebuild(mesh, windows, state);\n\tlisteners.get(mesh)?.forEach((listener) => listener());\n}\n\n/** Members of `mesh` not drawn, by index into `userData.members`. */\nexport function getHiddenMembers(mesh: THREE.Mesh): ReadonlySet<number> {\n\treturn states.get(mesh)?.hidden ?? NONE;\n}\n\nexport function setHiddenMembers(mesh: THREE.Mesh, hidden: ReadonlySet<number>): void {\n\tconst current = getHiddenMembers(mesh);\n\tif (current.size === hidden.size && [...hidden].every((i) => current.has(i))) return;\n\tupdate(mesh, (state) => {\n\t\tstate.hidden = new Set(hidden);\n\t});\n}\n\n/** The material `mesh` draws with when nothing is highlighted. */\nexport function getBaseMaterial(mesh: THREE.Mesh): THREE.Material {\n\treturn (\n\t\tstates.get(mesh)?.base ?? (Array.isArray(mesh.material) ? mesh.material[0]! : mesh.material)\n\t);\n}\n\n/** Draws member `index` with `material`. The caller owns `material` and disposes it. */\nexport function setMemberHighlight(\n\tmesh: THREE.Mesh,\n\tindex: number,\n\tmaterial: THREE.Material\n): void {\n\tupdate(mesh, (state) => {\n\t\tstate.highlight = { index, material };\n\t});\n}\n\nexport function clearMemberHighlight(mesh: THREE.Mesh): void {\n\tif (!states.get(mesh)?.highlight) return;\n\tupdate(mesh, (state) => {\n\t\tstate.highlight = null;\n\t});\n}\n\n/** Calls `listener` after the hidden set or highlight of `mesh` changes. Returns an unsubscribe. */\nexport function onMemberDrawChange(mesh: THREE.Mesh, listener: () => void): () => void {\n\tlet set = listeners.get(mesh);\n\tif (!set) listeners.set(mesh, (set = new Set()));\n\tset.add(listener);\n\treturn () => set.delete(listener);\n}\n"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- const e=require("./gpu-ownership-ilj3JEdn.cjs");let t=require("three");t=e.s(t,1);const n=/* @__PURE__ */ new WeakMap,r=/* @__PURE__ */ new WeakMap,i=/* @__PURE__ */ new Set;function a(e){let t=e.userData?.members;return!Array.isArray(t)||t.length===0||t.some(e=>e.indexStart==null||e.indexCount==null)?null:t}function o(e){let t=n.get(e);return t||(t={base:Array.isArray(e.material)?e.material[0]:e.material,hidden:i,highlight:null},n.set(e,t)),t}function s(n){let r=n.geometry;if(!e.i(r))return r;let i=new t.BufferGeometry;i.setIndex(r.index);for(let[e,t]of Object.entries(r.attributes))i.setAttribute(e,t);return i.boundingBox=r.boundingBox?.clone()??null,i.boundingSphere=r.boundingSphere?.clone()??null,e.t(i,r),n.geometry=i,i}function c(e,t,r){let i=s(e);if(i.clearGroups(),r.hidden.size===0&&!r.highlight){e.material=r.base,n.delete(e);return}let a=-1,o=0,c=0,l=()=>{a>=0&&i.addGroup(a,o-a,c),a=-1};for(let e=0;e<t.length;e++){if(r.hidden.has(e)){l();continue}let{indexStart:n,indexCount:i}=t[e],s=+(r.highlight?.index===e);(a<0||s!==c||n!==o)&&(l(),a=n,c=s),o=n+i}l(),e.material=r.highlight?[r.base,r.highlight.material]:[r.base]}function l(e,t){let n=a(e);if(!n)return;let i=o(e);t(i),c(e,n,i),r.get(e)?.forEach(e=>e())}function u(e){return n.get(e)?.hidden??i}function d(e,t){let n=u(e);n.size===t.size&&[...t].every(e=>n.has(e))||l(e,e=>{e.hidden=new Set(t)})}function f(e){return n.get(e)?.base??(Array.isArray(e.material)?e.material[0]:e.material)}function p(e,t,n){l(e,e=>{e.highlight={index:t,material:n}})}function m(e){n.get(e)?.highlight&&l(e,e=>{e.highlight=null})}function h(e,t){let n=r.get(e);return n||r.set(e,n=/* @__PURE__ */ new Set),n.add(t),()=>n.delete(t)}Object.defineProperty(exports,"a",{enumerable:!0,get:function(){return d}}),Object.defineProperty(exports,"i",{enumerable:!0,get:function(){return h}}),Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return f}}),Object.defineProperty(exports,"o",{enumerable:!0,get:function(){return p}}),Object.defineProperty(exports,"r",{enumerable:!0,get:function(){return u}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return m}});
2
- //# sourceMappingURL=merged-draw-SXYrxFt4.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"merged-draw-SXYrxFt4.cjs","names":["isCachedGeometry","THREE","require_gpu_ownership","three","states","listeners","NONE","windowsOf","members","mesh","m","stateOf","state","ownGeometry","shared","own","name","attribute","rebuild","geometry","runStart","runEnd","runMaterial","flush","i","windows","material","indexStart","indexCount","update","change","listener","getHiddenMembers","setHiddenMembers","current","hidden","getBaseMaterial","setMemberHighlight","clearMemberHighlight","onMemberDrawChange","set"],"sources":["../src/shared/merged-draw.ts"],"sourcesContent":["// ============================================================================\n// Which parts of a merged mesh draw, and with what material\n// ============================================================================\n//\n// A merged mesh draws many source members in one call. Two features draw only part of it: hiding\n// a member (`scene/`) and tinting the selected member (`render/`). Both need geometry groups, and\n// three honours groups only when `material` is an array: with a single material it draws the whole\n// index range and ignores them. So one owner builds the groups and the material array from both\n// states together. Two writers each replacing the groups would undo each other.\n//\n// Members are addressed by their index in `userData.members`, which carries each member's window\n// into the index buffer (`finalizeMergedMesh`).\n\nimport * as THREE from 'three';\n\nimport { borrowGeometry, isCachedGeometry } from './gpu-ownership.js';\n\ninterface MemberWindow {\n\tindexStart?: number;\n\tindexCount?: number;\n}\n\ninterface DrawState {\n\t/** The mesh's own material, restored once nothing is hidden or highlighted. */\n\tbase: THREE.Material;\n\thidden: ReadonlySet<number>;\n\thighlight: { index: number; material: THREE.Material } | null;\n}\n\nconst states = new WeakMap<THREE.Mesh, DrawState>();\nconst listeners = new WeakMap<THREE.Mesh, Set<() => void>>();\n\nconst NONE: ReadonlySet<number> = new Set();\n\nfunction windowsOf(mesh: THREE.Mesh): Required<MemberWindow>[] | null {\n\tconst members = mesh.userData?.members as MemberWindow[] | undefined;\n\tif (!Array.isArray(members) || members.length === 0) return null;\n\t// One member without a window means the ranges can't be rebuilt without dropping geometry.\n\tif (members.some((m) => m.indexStart == null || m.indexCount == null)) return null;\n\treturn members as Required<MemberWindow>[];\n}\n\nfunction stateOf(mesh: THREE.Mesh): DrawState {\n\tlet state = states.get(mesh);\n\tif (!state) {\n\t\tconst base = Array.isArray(mesh.material) ? mesh.material[0]! : mesh.material;\n\t\tstate = { base, hidden: NONE, highlight: null };\n\t\tstates.set(mesh, state);\n\t}\n\treturn state;\n}\n\n// Groups live on the geometry, and a cached geometry can back two meshes at once (two identical\n// branches), so a mesh gets its own geometry over the same attributes before writing any.\nfunction ownGeometry(mesh: THREE.Mesh): THREE.BufferGeometry {\n\tconst shared = mesh.geometry;\n\tif (!isCachedGeometry(shared)) return shared;\n\n\tconst own = new THREE.BufferGeometry();\n\town.setIndex(shared.index);\n\tfor (const [name, attribute] of Object.entries(shared.attributes))\n\t\town.setAttribute(name, attribute);\n\town.boundingBox = shared.boundingBox?.clone() ?? null;\n\town.boundingSphere = shared.boundingSphere?.clone() ?? null;\n\tborrowGeometry(own, shared);\n\tmesh.geometry = own;\n\treturn own;\n}\n\nfunction rebuild(mesh: THREE.Mesh, windows: Required<MemberWindow>[], state: DrawState): void {\n\tconst geometry = ownGeometry(mesh);\n\tgeometry.clearGroups();\n\n\tif (state.hidden.size === 0 && !state.highlight) {\n\t\tmesh.material = state.base;\n\t\tstates.delete(mesh);\n\t\treturn;\n\t}\n\n\t// Coalesce neighbours with the same material, so hiding one member costs two draws, not N.\n\tlet runStart = -1;\n\tlet runEnd = 0;\n\tlet runMaterial = 0;\n\tconst flush = () => {\n\t\tif (runStart >= 0) geometry.addGroup(runStart, runEnd - runStart, runMaterial);\n\t\trunStart = -1;\n\t};\n\tfor (let i = 0; i < windows.length; i++) {\n\t\tif (state.hidden.has(i)) {\n\t\t\tflush();\n\t\t\tcontinue;\n\t\t}\n\t\tconst { indexStart, indexCount } = windows[i]!;\n\t\tconst material = state.highlight?.index === i ? 1 : 0;\n\t\tif (runStart < 0 || material !== runMaterial || indexStart !== runEnd) {\n\t\t\tflush();\n\t\t\trunStart = indexStart;\n\t\t\trunMaterial = material;\n\t\t}\n\t\trunEnd = indexStart + indexCount;\n\t}\n\tflush();\n\n\tmesh.material = state.highlight ? [state.base, state.highlight.material] : [state.base];\n}\n\nfunction update(mesh: THREE.Mesh, change: (state: DrawState) => void): void {\n\tconst windows = windowsOf(mesh);\n\tif (!windows) return;\n\tconst state = stateOf(mesh);\n\tchange(state);\n\trebuild(mesh, windows, state);\n\tlisteners.get(mesh)?.forEach((listener) => listener());\n}\n\n/** Members of `mesh` not drawn, by index into `userData.members`. */\nexport function getHiddenMembers(mesh: THREE.Mesh): ReadonlySet<number> {\n\treturn states.get(mesh)?.hidden ?? NONE;\n}\n\nexport function setHiddenMembers(mesh: THREE.Mesh, hidden: ReadonlySet<number>): void {\n\tconst current = getHiddenMembers(mesh);\n\tif (current.size === hidden.size && [...hidden].every((i) => current.has(i))) return;\n\tupdate(mesh, (state) => {\n\t\tstate.hidden = new Set(hidden);\n\t});\n}\n\n/** The material `mesh` draws with when nothing is highlighted. */\nexport function getBaseMaterial(mesh: THREE.Mesh): THREE.Material {\n\treturn (\n\t\tstates.get(mesh)?.base ?? (Array.isArray(mesh.material) ? mesh.material[0]! : mesh.material)\n\t);\n}\n\n/** Draws member `index` with `material`. The caller owns `material` and disposes it. */\nexport function setMemberHighlight(\n\tmesh: THREE.Mesh,\n\tindex: number,\n\tmaterial: THREE.Material\n): void {\n\tupdate(mesh, (state) => {\n\t\tstate.highlight = { index, material };\n\t});\n}\n\nexport function clearMemberHighlight(mesh: THREE.Mesh): void {\n\tif (!states.get(mesh)?.highlight) return;\n\tupdate(mesh, (state) => {\n\t\tstate.highlight = null;\n\t});\n}\n\n/** Calls `listener` after the hidden set or highlight of `mesh` changes. Returns an unsubscribe. */\nexport function onMemberDrawChange(mesh: THREE.Mesh, listener: () => void): () => void {\n\tlet set = listeners.get(mesh);\n\tif (!set) listeners.set(mesh, (set = new Set()));\n\tset.add(listener);\n\treturn () => set.delete(listener);\n}\n"],"mappings":"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"}