add .dispose() for removed three geometry, update wiredge on geometry mutation
This commit is contained in:
parent
33603d9236
commit
a478f4b34b
4 changed files with 44 additions and 10 deletions
|
|
@ -373,7 +373,7 @@ function space_init(data) {
|
||||||
let obj = int?.object;
|
let obj = int?.object;
|
||||||
if (obj) api.selection.drag({ start: int.object });
|
if (obj) api.selection.drag({ start: int.object });
|
||||||
if (obj) obj.sketch_item?.sketch.drag({ start: int.object });
|
if (obj) obj.sketch_item?.sketch.drag({ start: int.object });
|
||||||
return event?.altKey ? undefined : api.objects(selection.count() ? true : false);
|
return selection.count() ? api.objects(true) : undefined;
|
||||||
});
|
});
|
||||||
|
|
||||||
// called two ways:
|
// called two ways:
|
||||||
|
|
|
||||||
|
|
@ -442,6 +442,7 @@ function ui_build() {
|
||||||
div({ class: "menu-items" }, [
|
div({ class: "menu-items" }, [
|
||||||
menu_item('Bounds', () => { selection.boundsBox({ toggle: true }) }, 'B'),
|
menu_item('Bounds', () => { selection.boundsBox({ toggle: true }) }, 'B'),
|
||||||
menu_item('Normals', () => { api.normals() }, 'N'),
|
menu_item('Normals', () => { api.normals() }, 'N'),
|
||||||
|
hr(),
|
||||||
menu_item('WireEdges', () => { api.wireedges() }, 'W'),
|
menu_item('WireEdges', () => { api.wireedges() }, 'W'),
|
||||||
menu_item('WireFaces', () => { api.wireframe() }, [ 'bi-shift', 'W' ]),
|
menu_item('WireFaces', () => { api.wireframe() }, [ 'bi-shift', 'W' ]),
|
||||||
hr(),
|
hr(),
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,7 @@ class History {
|
||||||
}
|
}
|
||||||
|
|
||||||
do(type, data) {
|
do(type, data) {
|
||||||
|
console.log({ type, data });
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'move': {
|
case 'move': {
|
||||||
let { set, dx, dy, dz } = data;
|
let { set, dx, dy, dz } = data;
|
||||||
|
|
|
||||||
|
|
@ -169,7 +169,6 @@ class MeshModel extends meshObject {
|
||||||
qrotate(quaternion) {
|
qrotate(quaternion) {
|
||||||
this.log('model-rotate', quaternion.toArray());
|
this.log('model-rotate', quaternion.toArray());
|
||||||
this.geometry.applyQuaternion(quaternion);
|
this.geometry.applyQuaternion(quaternion);
|
||||||
this.geometry._model_invalid = true;
|
|
||||||
this.updateBounds();
|
this.updateBounds();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -177,7 +176,6 @@ class MeshModel extends meshObject {
|
||||||
if (x === 1 && y === 1 && z === 1) return;
|
if (x === 1 && y === 1 && z === 1) return;
|
||||||
this.log('model-scale', ...arguments, this.bounds);
|
this.log('model-scale', ...arguments, this.bounds);
|
||||||
this.geometry.scale(x, y, z);
|
this.geometry.scale(x, y, z);
|
||||||
this.geometry._model_invalid = true;
|
|
||||||
this.updateBounds();
|
this.updateBounds();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -185,7 +183,6 @@ class MeshModel extends meshObject {
|
||||||
if (!(x || y || z)) return;
|
if (!(x || y || z)) return;
|
||||||
this.log('model-translate', ...arguments);
|
this.log('model-translate', ...arguments);
|
||||||
this.geometry.translate(x, y, z);
|
this.geometry.translate(x, y, z);
|
||||||
this.geometry._model_invalid = true;
|
|
||||||
this.updateBounds();
|
this.updateBounds();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -237,8 +234,10 @@ class MeshModel extends meshObject {
|
||||||
// when geometry updates, recompute bounds for ray intersections
|
// when geometry updates, recompute bounds for ray intersections
|
||||||
// and sync data to worker and indexed db
|
// and sync data to worker and indexed db
|
||||||
updateBounds() {
|
updateBounds() {
|
||||||
if (this._wire)
|
if (this._wire) {
|
||||||
this._wire.geometry.attributes.position.needsUpdate = true;
|
this._wire.geometry.attributes.position.needsUpdate = true;
|
||||||
|
this.updateWireEdges();
|
||||||
|
}
|
||||||
this.attributes.position.needsUpdate = true;
|
this.attributes.position.needsUpdate = true;
|
||||||
this.geometry.computeBoundingBox();
|
this.geometry.computeBoundingBox();
|
||||||
this.geometry.computeBoundingSphere();
|
this.geometry.computeBoundingSphere();
|
||||||
|
|
@ -307,10 +306,12 @@ class MeshModel extends meshObject {
|
||||||
this.log('reload');
|
this.log('reload');
|
||||||
let was = this.wireframe(false);
|
let was = this.wireframe(false);
|
||||||
let geo = this.mesh.geometry;
|
let geo = this.mesh.geometry;
|
||||||
|
const oldGeo = geo;
|
||||||
|
geo = new BufferGeometry();
|
||||||
geo.setAttribute('position', new BufferAttribute(vertices, 3));
|
geo.setAttribute('position', new BufferAttribute(vertices, 3));
|
||||||
// signal util.box3expand that geometry changed
|
|
||||||
geo._model_invalid = true;
|
|
||||||
geo.computeVertexNormals();
|
geo.computeVertexNormals();
|
||||||
|
this.mesh.geometry = geo;
|
||||||
|
oldGeo.dispose();
|
||||||
// restore wireframe state
|
// restore wireframe state
|
||||||
this.wireframe(was);
|
this.wireframe(was);
|
||||||
// fixup normals
|
// fixup normals
|
||||||
|
|
@ -443,19 +444,22 @@ class MeshModel extends meshObject {
|
||||||
if (bool.toggle) {
|
if (bool.toggle) {
|
||||||
bool = !was;
|
bool = !was;
|
||||||
}
|
}
|
||||||
// no change
|
|
||||||
if (was === bool) {
|
if (was === bool) {
|
||||||
return was;
|
return was;
|
||||||
}
|
}
|
||||||
if (was) {
|
if (was) {
|
||||||
this.mesh.remove(this._wire);
|
this.mesh.remove(this._wire);
|
||||||
this._wire?.geometry.dispose();
|
if (this._wire) {
|
||||||
|
this._wire.geometry.dispose();
|
||||||
|
this._wire.material.dispose();
|
||||||
|
}
|
||||||
this._wire = undefined;
|
this._wire = undefined;
|
||||||
this.opacity({restore: true});
|
this.opacity({restore: true});
|
||||||
}
|
}
|
||||||
if (bool && opt.edges) {
|
if (bool && opt.edges) {
|
||||||
let edges = new THREE.EdgesGeometry(this.mesh.geometry, opt.edges);
|
let edges = new THREE.EdgesGeometry(this.mesh.geometry, opt.edges);
|
||||||
this._wire = new THREE.LineSegments(edges, materials.wireline);
|
this._wire = new THREE.LineSegments(edges, materials.wireline);
|
||||||
|
this._wire._edges = opt.edges;
|
||||||
this.mesh.add(this._wire);
|
this.mesh.add(this._wire);
|
||||||
this.opacity({temp: opt.opacity || 0.15});
|
this.opacity({temp: opt.opacity || 0.15});
|
||||||
} else if (bool) {
|
} else if (bool) {
|
||||||
|
|
@ -467,6 +471,15 @@ class MeshModel extends meshObject {
|
||||||
return was;
|
return was;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateWireEdges() {
|
||||||
|
if (this._wire?.isLineSegments) {
|
||||||
|
const newEdges = new THREE.EdgesGeometry(this.mesh.geometry, this._wire._edges);
|
||||||
|
this._wire.geometry.dispose();
|
||||||
|
this._wire.material.dispose();
|
||||||
|
this._wire.geometry = newEdges;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
normals(bool) {
|
normals(bool) {
|
||||||
let was = this._norm ? true : false;
|
let was = this._norm ? true : false;
|
||||||
if (bool === undefined) {
|
if (bool === undefined) {
|
||||||
|
|
@ -574,6 +587,25 @@ class MeshModel extends meshObject {
|
||||||
this.group = undefined;
|
this.group = undefined;
|
||||||
this.removed = 'pending';
|
this.removed = 'pending';
|
||||||
} else {
|
} else {
|
||||||
|
// Clean up geometries and materials
|
||||||
|
if (this._wire) {
|
||||||
|
this._wire.geometry.dispose();
|
||||||
|
this._wire.material.dispose();
|
||||||
|
this._wire = undefined;
|
||||||
|
}
|
||||||
|
if (this._norm) {
|
||||||
|
this._norm.geometry.dispose();
|
||||||
|
this._norm.material.dispose();
|
||||||
|
this._norm = undefined;
|
||||||
|
}
|
||||||
|
if (this.mesh) {
|
||||||
|
this.mesh.geometry.dispose();
|
||||||
|
if (Array.isArray(this.mesh.material)) {
|
||||||
|
this.mesh.material.forEach(m => m.dispose());
|
||||||
|
} else {
|
||||||
|
this.mesh.material.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
// manage lifecycle with worker, mesh app caches, etc
|
// manage lifecycle with worker, mesh app caches, etc
|
||||||
this.destroy();
|
this.destroy();
|
||||||
// tag removed for debugging
|
// tag removed for debugging
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue