stub in ungrouping, add analysis step
This commit is contained in:
parent
cd7e3dde5a
commit
9f73e6e3c3
5 changed files with 83 additions and 30 deletions
|
|
@ -79,7 +79,7 @@ function restore_space() {
|
|||
let count = 0;
|
||||
let space = moto.Space;
|
||||
let parray = [];
|
||||
let mcache;
|
||||
let mcache = {};
|
||||
mesh.db.admin.get("camera")
|
||||
.then(saved => {
|
||||
if (saved) {
|
||||
|
|
@ -158,7 +158,7 @@ function space_init(data) {
|
|||
case 'KeyD':
|
||||
if (shiftKey) {
|
||||
for (let m of selection.models()) {
|
||||
m.debug();
|
||||
m.duplicate();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -182,6 +182,8 @@ function space_init(data) {
|
|||
return selection.boundsBox({toggle:true});
|
||||
case 'KeyH':
|
||||
return space.view.home();
|
||||
case 'KeyA':
|
||||
return api.tool.analyze();
|
||||
case 'KeyR':
|
||||
return api.tool.repair();
|
||||
case 'KeyT':
|
||||
|
|
|
|||
|
|
@ -258,7 +258,13 @@ let file = {
|
|||
|
||||
let tool = {
|
||||
analyze() {
|
||||
console.log('...analyze todo');
|
||||
api.log.emit('analyzing mesh(es)...').pin();
|
||||
for (let m of selection.models()) {
|
||||
worker.model_analyze(m.id).then(data => {
|
||||
console.log({data});
|
||||
api.log.emit('analysis complete').unpin();
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
repair() {
|
||||
|
|
|
|||
|
|
@ -79,14 +79,14 @@ mesh.model = class MeshModel extends mesh.object {
|
|||
return this.mesh.matrixWorld.elements;
|
||||
}
|
||||
|
||||
debug() {
|
||||
worker.model_debug({
|
||||
// return new group containing just this model in world coordinates
|
||||
duplicate() {
|
||||
worker.model_duplicate({
|
||||
matrix: this.matrix,
|
||||
id: this.id
|
||||
}).then(data => {
|
||||
// for debugging matrix ops
|
||||
return mesh.api.group.new([new mesh.model({
|
||||
file: `synth-${this.name}`,
|
||||
file: `${this.file}-dup`,
|
||||
mesh: data
|
||||
})]);
|
||||
});
|
||||
|
|
@ -101,12 +101,6 @@ mesh.model = class MeshModel extends mesh.object {
|
|||
meh.receiveShadow = true;
|
||||
meh.castShadow = true;
|
||||
meh.renderOrder = 1;
|
||||
// center vertices then restore mesh object position
|
||||
// still this doesn't work. scale broken for bounding boxes
|
||||
let { mid } = meh.getBoundingBox();
|
||||
geo.moveMesh(-mid.x, -mid.y, -mid.z);
|
||||
geo.computeBoundingBox();
|
||||
this.move(mid.x, mid.y, mid.z);
|
||||
// sets fallback opacity for wireframe toggle
|
||||
this.opacity(1);
|
||||
// this ref allows clicks to be traced to models and groups
|
||||
|
|
@ -116,7 +110,7 @@ mesh.model = class MeshModel extends mesh.object {
|
|||
}
|
||||
|
||||
reload(vertices, indices, normals) {
|
||||
this.wireframe(false);
|
||||
let was = this.wireframe(false);
|
||||
let geo = this.mesh.geometry;
|
||||
geo.setAttribute('position', new THREE.BufferAttribute(vertices, 3));
|
||||
geo.setAttribute('normal', undefined);
|
||||
|
|
@ -125,6 +119,8 @@ mesh.model = class MeshModel extends mesh.object {
|
|||
if (!normals) geo.computeVertexNormals();
|
||||
// sync data to worker
|
||||
worker.model_load({id: this.id, name: this.name, vertices, indices});
|
||||
// restore wireframe state
|
||||
this.wireframe(was);
|
||||
}
|
||||
|
||||
get group() {
|
||||
|
|
@ -150,6 +146,19 @@ mesh.model = class MeshModel extends mesh.object {
|
|||
return this.vertices / 3;
|
||||
}
|
||||
|
||||
// todo -- put model into its own group
|
||||
ungroup() {
|
||||
// get current world coordinates
|
||||
let { mid } = meh.getBoundingBox();
|
||||
// transform mesh into world coordinates
|
||||
// move mesh to origin
|
||||
// create and add to group
|
||||
// move group center back to original center
|
||||
geo.moveMesh(-mid.x, -mid.y, -mid.z);
|
||||
geo.computeBoundingBox();
|
||||
this.move(mid.x, mid.y, mid.z);
|
||||
}
|
||||
|
||||
visible(bool) {
|
||||
if (bool === undefined) {
|
||||
return this.mesh.visible;
|
||||
|
|
@ -204,6 +213,7 @@ mesh.model = class MeshModel extends mesh.object {
|
|||
if (bool.toggle) {
|
||||
return this.wireframe(this._wire ? false : true, opt);
|
||||
}
|
||||
let was = this._wire ? true : false;
|
||||
if (this._wire) {
|
||||
this.mesh.remove(this._wire);
|
||||
this._wire = undefined;
|
||||
|
|
@ -215,6 +225,7 @@ mesh.model = class MeshModel extends mesh.object {
|
|||
this.opacity({temp: opt.opacity || 0});
|
||||
}
|
||||
space.update();
|
||||
return was;
|
||||
}
|
||||
|
||||
remove() {
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ mesh.tool = class MeshTool {
|
|||
* construct ordered line maps with array of connected edges.
|
||||
* connect lines into polys. earcut polys into new faces.
|
||||
*/
|
||||
heal() {
|
||||
heal(opt = { merge: true }) {
|
||||
let vertices = this.vertices;
|
||||
let faces = this.faces;
|
||||
let hash = {}; // key to line map
|
||||
|
|
@ -314,6 +314,7 @@ mesh.tool = class MeshTool {
|
|||
// rotate/flatten to Z plane and use earcut to generate faces
|
||||
// because earcut emits point indexes, no need to un-rotate
|
||||
function emitLoop(loop) {
|
||||
let faces = [];
|
||||
let lastPoint;
|
||||
let pindex = [];
|
||||
let points = [];
|
||||
|
|
@ -371,17 +372,33 @@ mesh.tool = class MeshTool {
|
|||
for (let point of ec) {
|
||||
faces.push(pindex[point]);
|
||||
}
|
||||
|
||||
// newly generated faces
|
||||
return faces;
|
||||
}
|
||||
|
||||
// emit loops
|
||||
let faceCount = this.faces.length;
|
||||
// create area faces covering loops
|
||||
let areas = this.areas = [];
|
||||
for (let loop of loops) {
|
||||
emitLoop(loop);
|
||||
this.areas.push(emitLoop(loop));
|
||||
}
|
||||
|
||||
// track newly created faces when loop areas are merged
|
||||
let faceCount = this.faces.length;
|
||||
if (opt.merge) {
|
||||
this.merge();
|
||||
}
|
||||
this.newFaces = this.faces.length - faceCount;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
// merge poly areas into faces
|
||||
merge() {
|
||||
for (let area of this.areas || []) {
|
||||
this.faces.appendAll(area);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -38,6 +38,20 @@ function translate_encode(id, matrix) {
|
|||
return geo.attributes.position.array;
|
||||
}
|
||||
|
||||
function analyze(id) {
|
||||
log(`${id} | indexing...`);
|
||||
let geo = cache[id].geo;
|
||||
let tool = new mesh.tool({
|
||||
vertices: geo.attributes.position.array,
|
||||
faces: geo.index ? geo.index.array : undefined,
|
||||
debug: false
|
||||
});
|
||||
log(`${id} | analyzing...`);
|
||||
tool.heal();
|
||||
dbug.log(tool);
|
||||
return tool;
|
||||
}
|
||||
|
||||
let model = {
|
||||
load(data) {
|
||||
let { vertices, indices, name, id } = data;
|
||||
|
|
@ -47,7 +61,8 @@ let model = {
|
|||
cacheUpdate(id, { name, geo, matrix: core_matrix.clone() });
|
||||
},
|
||||
|
||||
debug(data) {
|
||||
// return new vertices in world coordinates
|
||||
duplicate(data) {
|
||||
let { id, matrix } = data;
|
||||
return translate_encode(id, matrix);
|
||||
throw "should not here";
|
||||
|
|
@ -55,21 +70,23 @@ let model = {
|
|||
let geo = rec.geo.clone();
|
||||
let m4 = core_matrix.clone().multiply( new THREE.Matrix4().fromArray(matrix) );
|
||||
geo.applyMatrix4(m4);
|
||||
// for debugging state / matrix ops
|
||||
return geo.attributes.position.array;
|
||||
},
|
||||
|
||||
analyze(id) {
|
||||
let tool = analyze(id);
|
||||
let { stats, newFaces } = tool;
|
||||
let { cull, dups, faces } = stats;
|
||||
log(`${id} | face count=${faces} bad=${cull} dup=${dups}`);
|
||||
log(`${id} | open loops=${tool.loops.length} edges=${tool.edges.length}`);
|
||||
return {
|
||||
new: newFaces
|
||||
};
|
||||
},
|
||||
|
||||
heal(id) {
|
||||
log(`${id} | indexing...`);
|
||||
let geo = cache[id].geo;
|
||||
let tool = new mesh.tool({
|
||||
vertices: geo.attributes.position.array,
|
||||
faces: geo.index ? geo.index.array : undefined,
|
||||
debug: false
|
||||
});
|
||||
log(`${id} | healing...`);
|
||||
tool.heal();
|
||||
dbug.log(tool);
|
||||
let tool = analyze(id);
|
||||
log(`${id} | unrolling...`);
|
||||
return true || tool.newFaces ? {
|
||||
vertices: tool.unrolled().toFloat32(),
|
||||
} : 0;
|
||||
|
|
|
|||
Loading…
Reference in a new issue