add sketch item(s) duplication

This commit is contained in:
Stewart Allen 2024-07-27 20:01:13 -04:00
commit a6c4f8aff1
3 changed files with 81 additions and 50 deletions

View file

@ -378,7 +378,7 @@ function space_init(data) {
const normal = shiftKey ? int.face.normal.applyQuaternion(q) : undefined;
// y,z swap due to world rotation for orbit controls
api.focus({center: { x, y:-z, z:y }, normal});
let one = api.sketch.selection.one;
let one = api.sketch.selected.one;
if (one && confirm('attach sketch to face?')) {
one.center = {
x, y: -z, z: y
@ -471,7 +471,7 @@ function load_files(files) {
let has_image = false;
let has_svg = false;
let has_gbr = false;
let sketch = api.sketch.selection.one;
let sketch = api.sketch.selected.one;
for (let file of files) {
has_image = has_image || file.type === 'image/png';
has_svg = has_svg || file.name.toLowerCase().endsWith(".svg") > 0;

View file

@ -134,7 +134,7 @@ const selection = {
// remove all
delete() {
if (sketch.selection.delete()) {
if (sketch.selected.delete()) {
return;
}
for (let s of selection.list()) {
@ -163,7 +163,7 @@ const selection = {
},
clear() {
if (sketch.selection.clear()) {
if (sketch.selected.clear()) {
return;
}
for (let s of selection.list()) {
@ -466,7 +466,7 @@ let sketch = {
h.button({ _: "create", onclick() {
const { _height, _chamtop, _chambot } = api.modal.bound;
sketch.extrude({
selection: sketch.selection.count() > 0,
selection: sketch.selected.count() > 0,
...opt,
height: parseFloat(_height.value),
chamfer_top: parseFloat(_chamtop.value),
@ -480,32 +480,23 @@ let sketch = {
},
arrange: {
ifcan(fn, count = 1) {
let one = sketch.selection.one;
let items = one?.items.filter(i => i.selected);
(items.length >= count) && fn(one, items);
},
group() {
let one = sketch.selection.one;
let items = one?.items.filter(i => i.selected);
if (items.length > 1) {
sketch.selection.ifcan((sketch, items) => {
let group = Date.now().toString(36);
items.forEach(i => i.group = group);
log('grouped', items.length, 'sketch items');
}
}, 2);
},
ungroup() {
sketch.selection.ifcan((sketch, items) => {
items.forEach(i => delete i.group);
log('ungrouped', items.length, 'sketch items');
});
},
center() {
sketch.arrange.ifcan((sketch, items) => {
let bounds;
let recs = [];
items.filter(i => i.type === 'polygon').forEach(item => {
let poly = newPolygon().fromObject(item);
let bnds = poly.bounds;
bounds = (bounds ? bounds.merge(bnds) : bnds);
recs.push({ item, poly });
});
sketch.selection.bounded_op((sketch, bounds, recs) => {
let center = bounds.center(0);
for (let rec of recs) {
rec.poly.move({ x: -center.x, y: -center.y, z:0 });
@ -515,17 +506,8 @@ let sketch = {
});
},
ungroup() {
let one = sketch.selection.one;
let items = one?.items.filter(i => i.selected)
if (items.length > 1) {
items.forEach(i => delete i.group);
log('ungrouped', items.length, 'sketch items');
}
},
fliph() {
sketch.arrange.ifcan((sketch, items) => {
sketch.selection.ifcan((sketch, items) => {
items.filter(i => i.type === 'polygon').forEach(item => {
Object.assign(item, newPolygon().fromObject(item).flip('x').toObject());
});
@ -534,7 +516,7 @@ let sketch = {
},
flipv() {
sketch.arrange.ifcan((sketch, items) => {
sketch.selection.ifcan((sketch, items) => {
items.filter(i => i.type === 'polygon').forEach(item => {
Object.assign(item, newPolygon().fromObject(item).flip('y').toObject());
});
@ -543,7 +525,8 @@ let sketch = {
}
},
selection: {
// related to a selected sketch
selected: {
get one() {
return selection.sketch();
},
@ -560,42 +543,84 @@ let sketch = {
delete() {
let list = selection.list(true);
return list[0]?.type === 'sketch' && list[0].selection.delete();
}
},
},
// related to items selections in a selected sketch
selection: {
ifcan(fn, count = 1) {
let one = sketch.selected.one;
let items = one?.items.filter(i => i.selected);
if (items?.length >= count) {
return fn(one, items) || true;
} else {
return false;
}
},
bounded_op(fn) {
return sketch.selection.ifcan((sketch, items) => {
let bounds;
let recs = [];
items.filter(i => i.type === 'polygon').forEach(item => {
let poly = newPolygon().fromObject(item);
let bnds = poly.bounds;
bounds = (bounds ? bounds.merge(bnds) : bnds);
recs.push({ item, poly });
});
return (bounds && (fn(sketch, bounds, recs) || true)) || false;
}) || false;
},
duplicate(opt = {}) {
return sketch.selection.bounded_op((sketch, bounds, recs) => {
let { shift, select } = opt;
let x = bounds.width(), y = 0, z = 0;
for (let rec of recs) {
let { item, poly } = rec;
let item2 = structuredClone(item);
item.selected = !select;
item2.group += 'D';
shift && Object.assign(item2, poly.move({ x, y, z }).toObject());
sketch.add_item(item2, { select });
}
});
},
},
boolean: {
nest() {
sketch.selection.one?.boolean.nest();
sketch.selected.one?.boolean.nest();
},
flatten() {
sketch.selection.one?.boolean.flatten();
sketch.selected.one?.boolean.flatten();
},
evenodd() {
sketch.selection.one?.boolean.evenodd();
sketch.selected.one?.boolean.evenodd();
},
union() {
sketch.selection.one?.boolean.union();
sketch.selected.one?.boolean.union();
},
intersect() {
sketch.selection.one?.boolean.intersect();
sketch.selected.one?.boolean.intersect();
},
difference() {
sketch.selection.one?.boolean.difference();
sketch.selected.one?.boolean.difference();
}
},
pattern: {
circle() {
sketch.selection.one?.pattern.circle();
sketch.selected.one?.pattern.circle();
},
grid() {
sketch.selection.one?.pattern.grid();
sketch.selected.one?.pattern.grid();
}
}
};
@ -952,6 +977,9 @@ const tool = {
duplicate() {
let { dup_shift, dup_sel } = api.prefs.map.space;
if (sketch.selection.duplicate({ select: dup_sel, shift: dup_shift })) {
return;
}
let models = selection.models();
if (dup_sel) {
selection.clear();

View file

@ -405,34 +405,37 @@ mesh.sketch = class MeshSketch extends mesh.object {
add_circle(opt = {}) {
log(this.file || this.id, '| add circle');
this.items.push({
this.add_item({
type: "circle",
selected: true,
...Object.assign({}, { center: {x:0, y:0, z:0}, radius:5 }, opt)
});
this.render();
}
add_rectangle(opt = {}) {
log(this.file || this.id, '| add rectangle');
this.items.push({
this.add_item({
type: "rectangle",
selected: true,
...Object.assign({}, { center: {x:0, y:0, z:0}, width:15, height:10 }, opt)
});
this.render();
}
add_polygon(opt = {}) {
// log(this.file || this.id, '| add polygon');
let poly = opt.poly;
delete opt.poly;
this.items.push({
this.add_item({
type: "polygon",
selected: true,
...Object.assign({}, { center: {x:0, y:0, z:0} }, opt),
...poly.toObject()
});
}
add_item(item, opt = {}) {
item.selected = opt.select || false;
this.items.push(item);
this.render();
}