post split add healing faces
This commit is contained in:
parent
e608840757
commit
b549aad3fe
4 changed files with 25 additions and 32 deletions
|
|
@ -927,11 +927,11 @@ const tool = {
|
||||||
return { id: m.id, matrix: m.matrix }
|
return { id: m.id, matrix: m.matrix }
|
||||||
}))
|
}))
|
||||||
.then(data => {
|
.then(data => {
|
||||||
api.selection.visible(false);
|
|
||||||
let group = api.group.new([new mesh.model({
|
let group = api.group.new([new mesh.model({
|
||||||
file: `merged`,
|
file: `merged`,
|
||||||
mesh: data
|
mesh: data
|
||||||
})]).promote();
|
})]).promote();
|
||||||
|
api.selection.visible(false);
|
||||||
api.selection.set([group]);
|
api.selection.set([group]);
|
||||||
log('merge complete').unpin();
|
log('merge complete').unpin();
|
||||||
});
|
});
|
||||||
|
|
@ -946,11 +946,11 @@ const tool = {
|
||||||
worker
|
worker
|
||||||
.model_union(models.map(m => m.id))
|
.model_union(models.map(m => m.id))
|
||||||
.then(data => {
|
.then(data => {
|
||||||
api.selection.visible(false);
|
|
||||||
let group = api.group.new([new mesh.model({
|
let group = api.group.new([new mesh.model({
|
||||||
file: `union`,
|
file: `union`,
|
||||||
mesh: data
|
mesh: data
|
||||||
})]).promote();
|
})]).promote();
|
||||||
|
api.selection.visible(false);
|
||||||
api.selection.set([ group ]);
|
api.selection.set([ group ]);
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
|
|
@ -969,11 +969,11 @@ const tool = {
|
||||||
log(`diff ${models.length} models`).pin();
|
log(`diff ${models.length} models`).pin();
|
||||||
worker.model_difference(models.map(m => m.id))
|
worker.model_difference(models.map(m => m.id))
|
||||||
.then(data => {
|
.then(data => {
|
||||||
api.selection.visible(false);
|
|
||||||
let group = api.group.new([new mesh.model({
|
let group = api.group.new([new mesh.model({
|
||||||
file: `diff`,
|
file: `diff`,
|
||||||
mesh: data
|
mesh: data
|
||||||
})]).promote();
|
})]).promote();
|
||||||
|
api.selection.visible(false);
|
||||||
api.selection.set([group]);
|
api.selection.set([group]);
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
|
|
|
||||||
|
|
@ -262,6 +262,7 @@ mesh.model = class MeshModel extends mesh.object {
|
||||||
this.geometry.computeBoundingBox();
|
this.geometry.computeBoundingBox();
|
||||||
this.geometry.computeBoundingSphere();
|
this.geometry.computeBoundingSphere();
|
||||||
this.log('update-bounds', this.geometry.boundingBox);
|
this.log('update-bounds', this.geometry.boundingBox);
|
||||||
|
this.normals({ refresh: true });
|
||||||
this.updateBoundsBox();
|
this.updateBoundsBox();
|
||||||
moto.space.update();
|
moto.space.update();
|
||||||
this.sync();
|
this.sync();
|
||||||
|
|
@ -552,14 +553,13 @@ mesh.model = class MeshModel extends mesh.object {
|
||||||
return new Promise((resolve,reject) => {
|
return new Promise((resolve,reject) => {
|
||||||
worker.model_split({ id: this.id, z }).then(data => {
|
worker.model_split({ id: this.id, z }).then(data => {
|
||||||
let { o1, o2 } = data;
|
let { o1, o2 } = data;
|
||||||
let model;
|
if (o1?.length)
|
||||||
if (o1.length)
|
|
||||||
this.group.add(new mesh.model({
|
this.group.add(new mesh.model({
|
||||||
file: `${this.file}-top`,
|
file: `${this.file}-top`,
|
||||||
mesh: o1
|
mesh: o1
|
||||||
}).reCenter());
|
}).reCenter());
|
||||||
if (o2.length)
|
if (o2?.length)
|
||||||
this.group.add(model = new mesh.model({
|
this.group.add(new mesh.model({
|
||||||
file: `${this.file}-bot`,
|
file: `${this.file}-bot`,
|
||||||
mesh: o2
|
mesh: o2
|
||||||
}).reCenter());
|
}).reCenter());
|
||||||
|
|
|
||||||
|
|
@ -27,14 +27,14 @@ mesh.object = class MeshObject {
|
||||||
|
|
||||||
constructor(id) {
|
constructor(id) {
|
||||||
this.id = id || mesh.util.uuid();
|
this.id = id || mesh.util.uuid();
|
||||||
worker.object_create({ id: this.id, type: this.type });
|
|
||||||
// storage location for meta data like position, scale, rotation
|
|
||||||
this.meta = { pos: [0,0,0] };
|
this.meta = { pos: [0,0,0] };
|
||||||
|
worker.object_create({ id: this.id, type: this.type });
|
||||||
|
worker.object_meta({ id: this.id, meta: this.meta });
|
||||||
this.log('NEW');
|
this.log('NEW');
|
||||||
}
|
}
|
||||||
|
|
||||||
log() {
|
log() {
|
||||||
mesh.api.log.emit(this.id, this.type, ...arguments);
|
// mesh.api.log.emit(this.id, this.type, ...arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
get type() {
|
get type() {
|
||||||
|
|
|
||||||
|
|
@ -21,19 +21,14 @@
|
||||||
gapp.main("mesh.work", [], (root) => {
|
gapp.main("mesh.work", [], (root) => {
|
||||||
|
|
||||||
const { Matrix4, Vector3, BufferGeometry, BufferAttribute, computeFaceNormal } = THREE;
|
const { Matrix4, Vector3, BufferGeometry, BufferAttribute, computeFaceNormal } = THREE;
|
||||||
const { Quaternion, } = THREE;
|
|
||||||
const { base, mesh, moto } = root;
|
const { base, mesh, moto } = root;
|
||||||
const { client, worker } = moto;
|
const { client, worker } = moto;
|
||||||
const { util } = mesh;
|
|
||||||
const { CSG, newPoint, newPolygon, sliceConnect } = base;
|
const { CSG, newPoint, newPolygon, sliceConnect } = base;
|
||||||
const cache = {};
|
const cache = {};
|
||||||
|
|
||||||
// add scoped access to cache
|
// add scoped access to cache
|
||||||
mesh.work = { cache };
|
mesh.work = { cache };
|
||||||
|
|
||||||
// compensation for space/world/platform rotation
|
|
||||||
const core_matrix = new Matrix4().makeRotationX(Math.PI / 2);
|
|
||||||
|
|
||||||
// start worker pool (disabled for now with *0)
|
// start worker pool (disabled for now with *0)
|
||||||
client.start(`/code/mesh_pool?${gapp.version}`, client.max() * 0);
|
client.start(`/code/mesh_pool?${gapp.version}`, client.max() * 0);
|
||||||
|
|
||||||
|
|
@ -52,7 +47,7 @@ function translate_encode(id) {
|
||||||
let rec = cache[id];
|
let rec = cache[id];
|
||||||
let { pos } = rec;
|
let { pos } = rec;
|
||||||
let mkey = pos.map(v => v.round(6)).join('-');
|
let mkey = pos.map(v => v.round(6)).join('-');
|
||||||
// re-translate on missing cache or changed matrix
|
// re-translate on missing cache or changed position
|
||||||
if (!rec || !rec.trans || rec.mkey !== mkey) {
|
if (!rec || !rec.trans || rec.mkey !== mkey) {
|
||||||
let geo = rec.geo.clone().translate(new Vector3().fromArray(pos));
|
let geo = rec.geo.clone().translate(new Vector3().fromArray(pos));
|
||||||
rec.mkey = mkey;
|
rec.mkey = mkey;
|
||||||
|
|
@ -102,12 +97,7 @@ let model = {
|
||||||
let { vertices, name, id } = data;
|
let { vertices, name, id } = data;
|
||||||
let geo = new BufferGeometry();
|
let geo = new BufferGeometry();
|
||||||
geo.setAttribute('position', new BufferAttribute(vertices, 3));
|
geo.setAttribute('position', new BufferAttribute(vertices, 3));
|
||||||
cacheUpdate(id, {
|
cacheUpdate(id, { name, geo, mkey: '' });
|
||||||
name,
|
|
||||||
geo,
|
|
||||||
trans: undefined,
|
|
||||||
tool: undefined
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// merge several model vertices into a single array
|
// merge several model vertices into a single array
|
||||||
|
|
@ -247,12 +237,15 @@ let model = {
|
||||||
}
|
}
|
||||||
on.length = over.length = under.length = 0;
|
on.length = over.length = under.length = 0;
|
||||||
}
|
}
|
||||||
// let mi4 = core_matrix.clone().multiply(new Matrix4().fromArray(matrix)).invert();
|
if (edges.length) {
|
||||||
// let b1 = new BufferAttribute(o1.toFloat32(), 3);
|
// heal open spaces created by split
|
||||||
// let b2 = new BufferAttribute(o2.toFloat32(), 3);
|
let heal = sliceConnect(edges, z).map(poly => poly.earcut()).flat();
|
||||||
// o1 = b1.applyMatrix4(mi4).array;
|
let o1p = heal.map(poly => poly.points.map(p => [ p.x, p.y, p.z ]));
|
||||||
// o2 = b2.applyMatrix4(mi4).array;
|
let o2p = heal.map(poly => poly.points.reverse().map(p => [ p.x, p.y, p.z ]));
|
||||||
console.log({ edges, split_face: sliceConnect(edges, z), o1, o2 });
|
o1.appendAll(o1p.flat().flat());
|
||||||
|
o2.appendAll(o2p.flat().flat());
|
||||||
|
// console.log({ edges, heal, o1, o2 });
|
||||||
|
}
|
||||||
return { o1: o1.toFloat32(), o2: o2.toFloat32() };
|
return { o1: o1.toFloat32(), o2: o2.toFloat32() };
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -394,8 +387,8 @@ let file = {
|
||||||
let { format, recs } = data;
|
let { format, recs } = data;
|
||||||
let vtot = 0;
|
let vtot = 0;
|
||||||
for (let rec of recs) {
|
for (let rec of recs) {
|
||||||
let { id, matrix, file } = rec;
|
let { id } = rec;
|
||||||
let vs = rec.varr = Array.from(translate_encode(id, matrix)).map(v => v.round(5));
|
let vs = rec.varr = Array.from(translate_encode(id)).map(v => v.round(5));
|
||||||
vtot += (vs.length / 3);
|
vtot += (vs.length / 3);
|
||||||
}
|
}
|
||||||
switch (format) {
|
switch (format) {
|
||||||
|
|
@ -403,7 +396,7 @@ let file = {
|
||||||
let p = 1;
|
let p = 1;
|
||||||
let obj = [header];
|
let obj = [header];
|
||||||
for (let rec of recs) {
|
for (let rec of recs) {
|
||||||
let { id, matrix, file, varr } = rec;
|
let { file, varr } = rec;
|
||||||
obj.push(`g ${file}`);
|
obj.push(`g ${file}`);
|
||||||
for (let i=0; i<varr.length; p += 3) {
|
for (let i=0; i<varr.length; p += 3) {
|
||||||
obj.push(`v ${varr[i++]} ${varr[i++]} ${varr[i++]}`);
|
obj.push(`v ${varr[i++]} ${varr[i++]} ${varr[i++]}`);
|
||||||
|
|
@ -420,7 +413,7 @@ let file = {
|
||||||
header.split('').forEach((c,i) => {
|
header.split('').forEach((c,i) => {
|
||||||
dat.setUint8(i, c.charCodeAt(0));
|
dat.setUint8(i, c.charCodeAt(0));
|
||||||
});
|
});
|
||||||
// todo put Kiri:Moto info in header
|
// todo put Mesh:Tool info in header
|
||||||
dat.setInt32(80, vtot/3, true);
|
dat.setInt32(80, vtot/3, true);
|
||||||
for (let rec of recs) {
|
for (let rec of recs) {
|
||||||
let { id, matrix, file, varr } = rec;
|
let { id, matrix, file, varr } = rec;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue