add precision/factor for CSG ops to eliminate sharps. add difference op to CSG
This commit is contained in:
parent
8aae9885e8
commit
41479e200b
5 changed files with 66 additions and 18 deletions
|
|
@ -235,10 +235,10 @@ const pattern = {
|
|||
* @param {float[]} center [x,y,z]
|
||||
*/
|
||||
circle(count, center) {
|
||||
async function doit(count, center = [0,0,0]) {
|
||||
async function doit(count, center = [0,0]) {
|
||||
api.modal.hide();
|
||||
let models = selection.models();
|
||||
let [ cx, cy, cz ] = center;
|
||||
let [ cx, cy ] = center;
|
||||
for (let model of models) {
|
||||
await api.tool.regroup([ model ]);
|
||||
let pos = model.group.position().clone();
|
||||
|
|
@ -260,8 +260,8 @@ const pattern = {
|
|||
body: [ h.div({ class: "addgear" }, [
|
||||
h.label('total count'),
|
||||
h.input({ value: 3, size: 5, id: "_count" }),
|
||||
h.label('center x,y,z'),
|
||||
h.input({ value: "0,0,0", size: 5, id: "_center" }),
|
||||
h.label('center x,y'),
|
||||
h.input({ value: "0,0", size: 5, id: "_center" }),
|
||||
h.button({ _: "create", onclick() {
|
||||
doit(
|
||||
parseInt(api.modal.bound._count.value) || 3,
|
||||
|
|
@ -489,6 +489,7 @@ const tool = {
|
|||
file: `merged`,
|
||||
mesh: data
|
||||
})]).promote();
|
||||
api.selection.visible(false);
|
||||
api.selection.set([group]);
|
||||
api.log.emit('merge complete').unpin();
|
||||
});
|
||||
|
|
@ -508,6 +509,7 @@ const tool = {
|
|||
file: `union`,
|
||||
mesh: data
|
||||
})]).promote();
|
||||
api.selection.visible(false);
|
||||
api.selection.set([group]);
|
||||
})
|
||||
.catch(error => {
|
||||
|
|
@ -518,6 +520,31 @@ const tool = {
|
|||
});
|
||||
},
|
||||
|
||||
difference(models) {
|
||||
models = fallback(models);
|
||||
if (models.length < 2) {
|
||||
return api.log.emit('nothing to diff');
|
||||
}
|
||||
api.log.emit(`diff ${models.length} models`).pin();
|
||||
worker.model_difference(models.map(m => {
|
||||
return { id: m.id, matrix: m.matrix }
|
||||
}))
|
||||
.then(data => {
|
||||
let group = api.group.new([new mesh.model({
|
||||
file: `diff`,
|
||||
mesh: data
|
||||
})]).promote();
|
||||
api.selection.visible(false);
|
||||
api.selection.set([group]);
|
||||
})
|
||||
.catch(error => {
|
||||
api.log.emit(`diff error: ${error}`);
|
||||
})
|
||||
.finally(() => {
|
||||
api.log.emit('diff complete').unpin();
|
||||
});
|
||||
},
|
||||
|
||||
intersect(models) {
|
||||
models = fallback(models);
|
||||
if (models.length < 2) {
|
||||
|
|
@ -532,6 +559,7 @@ const tool = {
|
|||
file: `intersect`,
|
||||
mesh: data
|
||||
})]).promote();
|
||||
api.selection.visible(false);
|
||||
api.selection.set([group]);
|
||||
})
|
||||
.catch(error => {
|
||||
|
|
@ -556,6 +584,7 @@ const tool = {
|
|||
file: `subtract`,
|
||||
mesh: data
|
||||
})]).promote();
|
||||
api.selection.visible(false);
|
||||
api.selection.set([group]);
|
||||
})
|
||||
.catch(error => {
|
||||
|
|
|
|||
|
|
@ -396,6 +396,7 @@ function ui_build() {
|
|||
h.button({ _: 'union', onclick: tool.union }),
|
||||
h.button({ _: 'subtract', onclick: tool.subtract }),
|
||||
h.button({ _: 'intersect', onclick: tool.intersect }),
|
||||
h.button({ _: 'difference', onclick: tool.difference }),
|
||||
])
|
||||
]),
|
||||
h.div([
|
||||
|
|
|
|||
|
|
@ -153,13 +153,17 @@ mesh.model = class MeshModel extends mesh.object {
|
|||
return this.duplicate({ mirror: true });
|
||||
}
|
||||
|
||||
// return new group containing just this model in world coordinates
|
||||
// return a model containing just this model
|
||||
// translated into world coordinates (rebuilt from rotation matrix)
|
||||
// defaults to returning a new model in a new group
|
||||
// options to mirror, re-use a group, or update model in-place
|
||||
duplicate(opt = {}) {
|
||||
return worker.model_duplicate({
|
||||
matrix: this.matrix,
|
||||
id: this.id,
|
||||
opt: { mirror: opt.mirror}
|
||||
}).then(data => {
|
||||
if (opt.reload) return this.reload(data);
|
||||
let model = new mesh.model({ file: `${this.file}`, mesh: data });
|
||||
let group = opt.group || mesh.api.group.new();
|
||||
group.add(model);
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ const { Matrix4, Vector3, BufferGeometry, BufferAttribute, computeFaceNormal } =
|
|||
const { base, mesh, moto } = root;
|
||||
const { client, worker } = moto;
|
||||
const { util } = mesh;
|
||||
const { newPolygon } = base;
|
||||
const { CSG, newPolygon } = base;
|
||||
const cache = {};
|
||||
|
||||
// add scoped access to cache
|
||||
|
|
@ -146,29 +146,36 @@ let model = {
|
|||
|
||||
union(recs) {
|
||||
let arrays = recs.map(rec => translate_encode(rec.id, rec.matrix));
|
||||
let solids = arrays.map(a => base.CSG.fromPositionArray(a));
|
||||
let union = base.CSG.union(...solids);
|
||||
return base.CSG.toPositionArray(union);
|
||||
let solids = arrays.map(a => CSG.fromPositionArray(a));
|
||||
let union = CSG.union(...solids);
|
||||
return CSG.toPositionArray(union);
|
||||
},
|
||||
|
||||
difference(recs) {
|
||||
let arrays = recs.map(rec => translate_encode(rec.id, rec.matrix));
|
||||
let solids = arrays.map(a => CSG.fromPositionArray(a));
|
||||
let diff = CSG.difference(...solids);
|
||||
return CSG.toPositionArray(diff);
|
||||
},
|
||||
|
||||
intersect(recs) {
|
||||
let arrays = recs.map(rec => translate_encode(rec.id, rec.matrix));
|
||||
let solids = arrays.map(a => base.CSG.fromPositionArray(a));
|
||||
let union = base.CSG.intersect(...solids);
|
||||
return base.CSG.toPositionArray(union);
|
||||
let solids = arrays.map(a => CSG.fromPositionArray(a));
|
||||
let union = CSG.intersect(...solids);
|
||||
return CSG.toPositionArray(union);
|
||||
},
|
||||
|
||||
subtract(recs) {
|
||||
let bases = recs.filter(rec => !rec.tool)
|
||||
.map(rec => translate_encode(rec.id, rec.matrix))
|
||||
.map(a => base.CSG.fromPositionArray(a));
|
||||
.map(a => CSG.fromPositionArray(a));
|
||||
let tools = recs.filter(rec => rec.tool)
|
||||
.map(rec => translate_encode(rec.id, rec.matrix))
|
||||
.map(a => base.CSG.fromPositionArray(a));
|
||||
.map(a => CSG.fromPositionArray(a));
|
||||
let subs = [];
|
||||
for (let obj of bases) {
|
||||
let sub = base.CSG.subtract(obj, ...tools);
|
||||
subs.appendAll(base.CSG.toPositionArray(sub));
|
||||
let sub = CSG.subtract(obj, ...tools);
|
||||
subs.appendAll(CSG.toPositionArray(sub));
|
||||
}
|
||||
return subs.toFloat32();
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in a new issue