add sketch item dialogs and editing, sketch extrusion dialog and options
This commit is contained in:
parent
d86d71fef8
commit
47e47df0a5
6 changed files with 279 additions and 53 deletions
|
|
@ -850,6 +850,18 @@ class Polygon {
|
|||
return this;
|
||||
}
|
||||
|
||||
rotate(degrees) {
|
||||
let rad = degrees * DEG2RAD;
|
||||
if (rad)
|
||||
this.points = this.points.map(p => {
|
||||
let [ x, y ] = base.util.rotate(p.x, p.y, rad);
|
||||
p.x = x;
|
||||
p.y = y;
|
||||
return p;
|
||||
});
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* hint fill angle hinting from longest segment
|
||||
*/
|
||||
|
|
@ -2232,10 +2244,11 @@ class Polygon {
|
|||
}
|
||||
|
||||
// outside wall
|
||||
obj.appendAll(this.ribbonZ(z_side_top, z_side_bottom));
|
||||
let rib = z - chamfer_top - chamfer_bottom;
|
||||
obj.appendAll(this.ribbonZ(rib, z_side_bottom));
|
||||
for (let inner of this.inner || []) {
|
||||
// inside wall(s)
|
||||
obj.appendAll(inner.ribbonZ(z_side_top, z_side_bottom, true));
|
||||
obj.appendAll(inner.ribbonZ(rib, z_side_bottom, true));
|
||||
}
|
||||
|
||||
return obj;
|
||||
|
|
|
|||
|
|
@ -235,6 +235,7 @@ function space_init(data) {
|
|||
return shiftKey ? api.tool.rebuild() : api.tool.repair();
|
||||
case 'KeyE':
|
||||
if (api.mode.is([ api.modes.sketch ])) {
|
||||
estop(evt);
|
||||
return api.sketch.extrude();
|
||||
}
|
||||
return api.tool.clean();
|
||||
|
|
|
|||
|
|
@ -442,10 +442,35 @@ let sketch = {
|
|||
return sketches;
|
||||
},
|
||||
|
||||
extrude() {
|
||||
selection.sketches(true).forEach(sketch => {
|
||||
sketch.extrude(...arguments);
|
||||
extrude(opt = {}) {
|
||||
if (!selection.sketch()) {
|
||||
return log('select a sketch to extrude');
|
||||
}
|
||||
api.modal.dialog({
|
||||
title: "gear generator",
|
||||
body: [ h.div({ class: "addgear" }, [
|
||||
h.label('height'),
|
||||
h.input({ value: opt.height || 10, size: 5, id: "_height" }),
|
||||
h.hr(),
|
||||
h.code("optional"),
|
||||
h.hr(),
|
||||
h.label('chamfer top'),
|
||||
h.input({ value: opt.chamfer_top || 0, size: 5, id: "_chamtop" }),
|
||||
h.label('chamfer bottom'),
|
||||
h.input({ value: opt.chamfer_bottom || 0, size: 5, id: "_chambot" }),
|
||||
h.button({ _: "create", onclick() {
|
||||
const { _height, _chamtop, _chambot } = api.modal.bound;
|
||||
selection.sketch()?.extrude({
|
||||
...opt,
|
||||
height: parseFloat(_height.value),
|
||||
chamfer_top: parseFloat(_chamtop.value),
|
||||
chamfer_bottom: parseFloat(_chambot.value),
|
||||
});
|
||||
api.modal.hide();
|
||||
} })
|
||||
]) ]
|
||||
});
|
||||
api.modal.bound._height.focus();
|
||||
},
|
||||
|
||||
selection: {
|
||||
|
|
@ -508,12 +533,35 @@ let add = {
|
|||
|
||||
/** add sketch components */
|
||||
|
||||
circle() {
|
||||
let sel = selection.sketches();
|
||||
if (!sel.length) {
|
||||
circle(opt = {}) {
|
||||
let sketch = selection.sketch();
|
||||
if (!sketch) {
|
||||
return log('select a sketch');
|
||||
}
|
||||
return sel[0].add_circle(...arguments);
|
||||
api.modal.dialog({
|
||||
title: "gear generator",
|
||||
body: [ h.div({ class: "addgear" }, [
|
||||
h.label('radius in mm'),
|
||||
h.input({ value: opt.radius || 10, size: 5, id: "_radius" }),
|
||||
h.hr(),
|
||||
h.code("optional"),
|
||||
h.hr(),
|
||||
h.label('point spacing'),
|
||||
h.input({ value: opt.spacing || 0, size: 5, id: "_spacing" }),
|
||||
h.label('point count'),
|
||||
h.input({ value: opt.points || 0, size: 5, id: "_points" }),
|
||||
h.button({ _: "create", onclick() {
|
||||
const { _radius, _points, _spacing } = api.modal.bound;
|
||||
sketch.add_circle({
|
||||
radius: parseFloat(_radius.value),
|
||||
points: parseInt(_points.value),
|
||||
spacing: parseFloat(_spacing.value),
|
||||
});
|
||||
api.modal.hide();
|
||||
} })
|
||||
]) ]
|
||||
});
|
||||
api.modal.bound._radius.focus();
|
||||
},
|
||||
|
||||
rectangle() {
|
||||
|
|
|
|||
|
|
@ -445,14 +445,14 @@ function ui_build() {
|
|||
h.button({ _: 'grid', onclick() { api.pattern.grid() } }),
|
||||
])
|
||||
]),
|
||||
h.div({ class: "sketch-on" }, [
|
||||
h.div({ _: "pattern", class: "head" }),
|
||||
h.div({ class: "back"}),
|
||||
h.div({ class: "pop"}, [
|
||||
h.button({ _: 'circular', onclick() { sketch.pattern.circle() } }),
|
||||
h.button({ _: 'grid', onclick() { sketch.pattern.grid() } }),
|
||||
])
|
||||
]),
|
||||
// h.div({ class: "sketch-on" }, [
|
||||
// h.div({ _: "pattern", class: "head" }),
|
||||
// h.div({ class: "back"}),
|
||||
// h.div({ class: "pop"}, [
|
||||
// h.button({ _: 'circular', onclick() { sketch.pattern.circle() } }),
|
||||
// h.button({ _: 'grid', onclick() { sketch.pattern.grid() } }),
|
||||
// ])
|
||||
// ]),
|
||||
h.div({ class: "sketch-on" }, [
|
||||
h.div({ _: "extrude", class: "head" }),
|
||||
h.div({ class: "back"}),
|
||||
|
|
@ -518,6 +518,38 @@ function ui_build() {
|
|||
]);
|
||||
}
|
||||
|
||||
// for dashboard sketch grids
|
||||
function grid2(v1, v2, side = [ "pos", "rot"], top = [ "X", "Y" ], root) {
|
||||
let v = 'val', l = 'lbl';
|
||||
let [ X, Y ] = top;
|
||||
let [ pos, rot ] = side;
|
||||
return h.div({ class: "grid grid2"}, [
|
||||
h.div({ _: "" }),
|
||||
h.div({ _: X, class: "top noselect", id: root ? [ root, l, X ] : und }),
|
||||
h.div({ _: Y, class: "top noselect", id: root ? [ root, l, Y ] : und }),
|
||||
h.div({ _: side[0], class: "side noselect" }),
|
||||
h.label({ _: v1[0], id: root ? [ root, v, X, pos ] : und }),
|
||||
h.label({ _: v1[1], id: root ? [ root, v, Y, pos ] : und }),
|
||||
h.div({ _: side[1], class: "side noselect" }),
|
||||
h.label({ _: v2[0], id: root ? [ root, v, X, rot ] : und }),
|
||||
h.label({ _: v2[1], id: root ? [ root, v, Y, rot ] : und }),
|
||||
]);
|
||||
}
|
||||
|
||||
// for other dashboard grids
|
||||
function grid1(vals, side = [ "X", "Y"], top = "center", root, post) {
|
||||
let v = 'val', l = 'lbl';
|
||||
let [ X, Y ] = side;
|
||||
return h.div({ class: "grid grid1"}, [
|
||||
h.div({ _: "" }),
|
||||
h.div({ _: top, class: "top noselect", id: root ? [ root, l ] : und }),
|
||||
h.div({ _: side[0], class: "side noselect" }),
|
||||
h.label({ _: vals[0], id: root ? [ root, v, X, post ] : und }),
|
||||
h.div({ _: side[1], class: "side noselect" }),
|
||||
h.label({ _: vals[1], id: root ? [ root, v, Y, post ] : und }),
|
||||
]);
|
||||
}
|
||||
|
||||
function update_all() {
|
||||
update_selector();
|
||||
update_selection();
|
||||
|
|
@ -619,13 +651,17 @@ function ui_build() {
|
|||
if (modal.info.cancelled) {
|
||||
return;
|
||||
}
|
||||
if (opt.sketch) {
|
||||
defer_selection();
|
||||
return set(tempval, value);
|
||||
}
|
||||
for (let g of api.selection.groups()) {
|
||||
set(g, tempval, value);
|
||||
if (floor && opt.floor !== false) {
|
||||
g.floor(mesh.group);
|
||||
}
|
||||
defer_selection(); // update ui
|
||||
}
|
||||
defer_selection();
|
||||
};
|
||||
let onkeydown = (ev) => {
|
||||
if (ev.key === 'Enter') {
|
||||
|
|
@ -642,14 +678,9 @@ function ui_build() {
|
|||
}
|
||||
}
|
||||
|
||||
// update model information dashboard (bottom)
|
||||
// editable model/sketch information dashboard
|
||||
function update_selection() {
|
||||
let map = { fixed: 2 };
|
||||
let s_grp = selection.groups(true);
|
||||
let s_mdl = selection.models(true);
|
||||
if (s_mdl.length === 0) {
|
||||
return h.bind(selectlist, []);
|
||||
}
|
||||
|
||||
// toggle-able stat block generator
|
||||
let sdata = {};
|
||||
|
|
@ -668,6 +699,108 @@ function ui_build() {
|
|||
];
|
||||
}
|
||||
|
||||
// possible selections
|
||||
let sketch = selection.sketch();
|
||||
let s_grp = selection.groups(true);
|
||||
let s_mdl = selection.models(true);
|
||||
|
||||
if (!(sketch || s_grp.length)) {
|
||||
return h.bind(selectlist, []);
|
||||
}
|
||||
|
||||
// render sketch options
|
||||
if (sketch) {
|
||||
let bounds = {
|
||||
size: sketch.scale,
|
||||
center: sketch.center
|
||||
};
|
||||
let sel = sketch.selection.mesh_items();
|
||||
let sk_vars = sblock('sketch', sketch.file || sketch.id, grid(
|
||||
util.extract(bounds.center, map),
|
||||
util.extract(bounds.size, map),
|
||||
[ "center", "size" ], und, 'sketch'
|
||||
));
|
||||
let sel_item;
|
||||
let si_vars = sel.slice(0,1).map(item => item.sketch_item.item).map(item => {
|
||||
sel_item = item;
|
||||
if (item.type === 'rectangle') {
|
||||
return sblock('rectangle', '', grid2(
|
||||
util.extract(item.center, map),
|
||||
[ item.width.toFixed(2), item.height.toFixed(2) ],
|
||||
[ "center", "size" ], und, 'item'
|
||||
));
|
||||
} else if (item.type === 'circle') {
|
||||
return [
|
||||
sblock('circle', '', grid1(
|
||||
[ item.points, item.rotation || 0 ],
|
||||
[ "points", "rotation" ], "value", 'circle', 'other'
|
||||
)),
|
||||
sblock('circle', '', grid2(
|
||||
util.extract(item.center, map),
|
||||
[ (item.radius*2).toFixed(2), (item.radius*2).toFixed(2) ],
|
||||
[ "center", "size" ], und, 'item'
|
||||
)),
|
||||
];
|
||||
} else if (item.type === 'polygon') {
|
||||
return sblock('poly', '', grid1(
|
||||
util.extract(item.center, map),
|
||||
und, und, 'item', 'center'
|
||||
));
|
||||
}
|
||||
});
|
||||
let bound = h.bind(selectlist, [
|
||||
...si_vars,
|
||||
...sk_vars
|
||||
]);
|
||||
for (let axis of [ 'x', 'y', 'z' ]) {
|
||||
let el = bound[`sketch_val_${axis.toUpperCase()}_center`];
|
||||
el.classList.add('editable');
|
||||
el.onclick = field_edit(`${axis} center`, (nval, oval) => {
|
||||
sketch.center[axis] = nval;
|
||||
sketch.render();
|
||||
}, { sketch: true });
|
||||
let el2 = bound[`sketch_val_${axis.toUpperCase()}_size`];
|
||||
el2.classList.add('editable');
|
||||
el2.onclick = field_edit(`${axis} size`, (nval, oval) => {
|
||||
sketch.scale[axis] = nval;
|
||||
sketch.render();
|
||||
}, { sketch: true });
|
||||
}
|
||||
if (sel_item)
|
||||
for (let axis of [ 'x', 'y' ]) {
|
||||
let el = bound[`item_val_${axis.toUpperCase()}_center`];
|
||||
if (!el) continue;
|
||||
el.classList.add('editable');
|
||||
el.onclick = field_edit(`${axis} center`, (nval, oval) => {
|
||||
sel_item.center[axis] = nval;
|
||||
sketch.render();
|
||||
}, { sketch: true });
|
||||
|
||||
let el2 = bound[`item_val_${axis.toUpperCase()}_size`];
|
||||
if (!el2) continue;
|
||||
el2.classList.add('editable');
|
||||
el2.onclick = field_edit(`${axis} size`, (nval, oval) => {
|
||||
if (sel_item.type === 'rectangle') {
|
||||
sel_item[{ x:'width', y:'height' }[axis]] = nval;
|
||||
} else if (sel_item.type === 'circle') {
|
||||
sel_item.radius = nval / 2;
|
||||
}
|
||||
sketch.render();
|
||||
}, { sketch: true });
|
||||
|
||||
let lab = { x: 'points', y: 'rotation' }[axis];
|
||||
let el3 = bound[`circle_val_${lab}_other`];
|
||||
if (!el3) continue;
|
||||
el3.classList.add('editable');
|
||||
el3.onclick = field_edit(`${axis} size`, (nval, oval) => {
|
||||
sel_item[lab] = nval;
|
||||
sketch.render();
|
||||
}, { sketch: true });
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// map selection to divs
|
||||
let g_pos = util.average(s_grp.map(g => g.object.position));
|
||||
let g_rot = util.average(s_grp.map(g => g.object.rotation));
|
||||
|
|
@ -678,8 +811,8 @@ function ui_build() {
|
|||
und, und, 'group'
|
||||
));
|
||||
|
||||
let m_pos = util.average(s_mdl.map(m => m.object.position));
|
||||
let m_rot = util.average(s_mdl.map(m => m.object.rotation));
|
||||
// let m_pos = util.average(s_mdl.map(m => m.object.position));
|
||||
// let m_rot = util.average(s_mdl.map(m => m.object.rotation));
|
||||
let m_id = s_mdl.map(m => m.id).join(' ');
|
||||
|
||||
let bounds = util.bounds(s_mdl);
|
||||
|
|
@ -693,7 +826,7 @@ function ui_build() {
|
|||
let t_face = s_mdl.map(m => m.faces).reduce((a,v) => a+v);
|
||||
let h_msh = [h.div([
|
||||
h.button({ _: `mesh` }),
|
||||
h.div({ class: ["grid","grid2"]}, [
|
||||
h.div({ class: ["grid","grid1"]}, [
|
||||
h.div({ _: "" }),
|
||||
h.div({ _: "count", class: "top" }),
|
||||
h.div({ _: "vertex", class: "side" }),
|
||||
|
|
@ -706,7 +839,7 @@ function ui_build() {
|
|||
let m_viz = !s_mdl.map(m => !m.visible()).reduce((v,b) => v || b);
|
||||
let h_ops = [h.div([
|
||||
h.button({ _: `ops` }),
|
||||
h.div({ class: ["grid","grid1"]}, [
|
||||
h.div({ class: ["grid","grid0"]}, [
|
||||
h.div({ class: [ 'square' ],
|
||||
onclick(e) {
|
||||
api.selection.visible(!m_viz);
|
||||
|
|
@ -852,6 +985,7 @@ function ui_build() {
|
|||
selection_scale: defer_selection,
|
||||
selection_rotate: defer_selection,
|
||||
selection_qrotate: defer_selection,
|
||||
sketch_selections: defer_selection
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ const { BufferGeometry, BufferAttribute } = THREE;
|
|||
const { MeshBasicMaterial, LineBasicMaterial, LineSegments, DoubleSide } = THREE;
|
||||
const { PlaneGeometry, EdgesGeometry, SphereGeometry, Vector3, Mesh, Group } = THREE;
|
||||
const { base, mesh, moto } = root;
|
||||
const { space } = moto;
|
||||
const { space, broker } = moto;
|
||||
const { api, util } = mesh;
|
||||
const { newPolygon } = base;
|
||||
|
||||
|
|
@ -144,6 +144,7 @@ mesh.sketch = class MeshSketch extends mesh.object {
|
|||
all() {
|
||||
sketch.items.forEach(i => i.selected = true);
|
||||
sketch.render();
|
||||
broker.publish('sketch_selections');
|
||||
return sketch.items.length;
|
||||
},
|
||||
|
||||
|
|
@ -153,6 +154,7 @@ mesh.sketch = class MeshSketch extends mesh.object {
|
|||
if (sel.length) {
|
||||
sel.forEach(s => s.selected = false);
|
||||
sketch.render();
|
||||
broker.publish('sketch_selections');
|
||||
}
|
||||
return sel.length;
|
||||
},
|
||||
|
|
@ -163,6 +165,7 @@ mesh.sketch = class MeshSketch extends mesh.object {
|
|||
if (sel.length) {
|
||||
sketch.items = sketch.items.filter(i => !i.selected);
|
||||
sketch.render();
|
||||
broker.publish('sketch_selections');
|
||||
}
|
||||
return sel.length;
|
||||
}
|
||||
|
|
@ -174,6 +177,7 @@ mesh.sketch = class MeshSketch extends mesh.object {
|
|||
return {
|
||||
union() {
|
||||
let items = sketch.selection.mesh_items();
|
||||
if (items.length < 2) return log('operation requires at least 2 items');
|
||||
let polys = items.map(i => i.sketch_item.poly);
|
||||
let union = POLYS.union(polys, 0, true);
|
||||
sketch.selection.delete();
|
||||
|
|
@ -184,6 +188,7 @@ mesh.sketch = class MeshSketch extends mesh.object {
|
|||
|
||||
intersect() {
|
||||
let items = sketch.selection.mesh_items();
|
||||
if (items.length !== 2) return log('operation requires 2 items');
|
||||
let polys = items.map(i => i.sketch_item.poly);
|
||||
let trim = POLYS.trimTo([polys[0]], [polys[1]]);
|
||||
sketch.selection.delete();
|
||||
|
|
@ -194,6 +199,7 @@ mesh.sketch = class MeshSketch extends mesh.object {
|
|||
|
||||
difference() {
|
||||
let items = sketch.selection.mesh_items();
|
||||
if (items.length !== 2) return log('operation requires 2 items');
|
||||
let polys = items.map(i => i.sketch_item.poly);
|
||||
let diff1 = POLYS.diff([polys[0]], [polys[1]]);
|
||||
let diff2 = POLYS.diff([polys[1]], [polys[0]]);
|
||||
|
|
@ -205,6 +211,7 @@ mesh.sketch = class MeshSketch extends mesh.object {
|
|||
|
||||
group() {
|
||||
let items = sketch.selection.mesh_items();
|
||||
if (items.length < 2) return log('operation requires at least 2 items');
|
||||
let polys = items.map(i => i.sketch_item.poly).clone(true);
|
||||
let union = POLYS.nest(POLYS.flatten(polys, [], true));
|
||||
sketch.selection.delete();
|
||||
|
|
@ -320,22 +327,31 @@ mesh.sketch = class MeshSketch extends mesh.object {
|
|||
|
||||
add_circle(opt = {}) {
|
||||
log(this.file || this.id, '| add circle');
|
||||
Object.assign(opt, { center: {x:0, y:0, z:0}, radius:5 }, opt);
|
||||
this.items.push({ type: "circle", ...opt });
|
||||
this.items.push({
|
||||
type: "circle",
|
||||
...Object.assign({}, { center: {x:0, y:0, z:0}, radius:5 }, opt)
|
||||
});
|
||||
this.render();
|
||||
}
|
||||
|
||||
add_rectangle(opt = {}) {
|
||||
log(this.file || this.id, '| add rectangle');
|
||||
Object.assign(opt, { center: {x:0, y:0, z:0}, width:15, height:10 }, opt);
|
||||
this.items.push({ type: "rectangle", ...opt });
|
||||
this.items.push({
|
||||
type: "rectangle",
|
||||
...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');
|
||||
Object.assign(opt, { center: {x:0, y:0, z:0} }, opt);
|
||||
this.items.push({ type: "polygon", ...opt, ...opt.poly.toObject() });
|
||||
let poly = opt.poly;
|
||||
delete opt.poly;
|
||||
this.items.push({
|
||||
type: "polygon",
|
||||
...Object.assign({}, { center: {x:0, y:0, z:0} }, opt),
|
||||
...poly.toObject()
|
||||
});
|
||||
this.render();
|
||||
}
|
||||
|
||||
|
|
@ -347,19 +363,24 @@ mesh.sketch = class MeshSketch extends mesh.object {
|
|||
// mapy items into polys into meshes to add to group
|
||||
for (let si of this.items.map((i,o) => new SketchItem(this, i, o))) {
|
||||
group.add(si.mesh);
|
||||
group.add(si.outs);
|
||||
group.add(...si.outs);
|
||||
}
|
||||
this.update();
|
||||
}
|
||||
|
||||
extrude(opt = {}) {
|
||||
let { z, selection } = opt;
|
||||
console.log({ opt });
|
||||
let { selection, height, chamfer, chamfer_top, chamfer_bottom } = opt;
|
||||
let models = [];
|
||||
let items = this.group.children
|
||||
.filter(c => c.sketch_item)
|
||||
.filter(c => !selection || c.sketch_item.selected);
|
||||
for (let item of items) {
|
||||
let vert = item.sketch_item.extrude(z || 10);
|
||||
let vert = item.sketch_item.extrude(height, {
|
||||
chamfer,
|
||||
chamfer_top,
|
||||
chamfer_bottom
|
||||
});
|
||||
let nmdl = new mesh.model({ file: "item", mesh: vert.toFloat32() });
|
||||
models.push(nmdl);
|
||||
}
|
||||
|
|
@ -393,21 +414,22 @@ class SketchItem {
|
|||
this.item.selected = !this.item.selected;
|
||||
this.update();
|
||||
this.sketch.render();
|
||||
broker.publish('sketch_selections');
|
||||
}
|
||||
|
||||
extrude(opt = {}) {
|
||||
return this.poly.extrude(opt);
|
||||
extrude(z, opt = {}) {
|
||||
return this.poly.extrude(z, opt);
|
||||
}
|
||||
|
||||
update() {
|
||||
let bump = 0.0025;
|
||||
let { item, sketch, order } = this;
|
||||
let { material } = mesh;
|
||||
let { type, center, width, height, radius, spacing, poly, selected } = item;
|
||||
let { type, center, width, height, radius, points, spacing, poly, selected } = item;
|
||||
if (type === 'circle') {
|
||||
let circumference = 2 * Math.PI * radius;
|
||||
let points = Math.floor(circumference / (spacing || 1));
|
||||
poly = newPolygon().centerCircle(center, radius, points).annotate({ item } );
|
||||
points = points || Math.floor(circumference / (spacing || 1));
|
||||
poly = newPolygon().centerCircle(center, radius, points).annotate({ item } ).rotate(item.rotation || 0);
|
||||
} else if (type === 'rectangle') {
|
||||
poly = newPolygon().centerRectangle(center, width, height).annotate({ item });
|
||||
} else if (type === 'polygon') {
|
||||
|
|
@ -430,14 +452,18 @@ class SketchItem {
|
|||
meh.sketch_item = this;
|
||||
// bump z to avoid z order conflict and ensure item ray intersect priority
|
||||
meh.position.z += bump + (order * bump);
|
||||
// create poly outline
|
||||
let lpt = poly.points.map(p => new Vector3(p.x, p.y, p.z));
|
||||
lpt.push(lpt[0]);
|
||||
let lge = new BufferGeometry().setFromPoints(lpt);
|
||||
let out = this.outs = new THREE.Line(lge, material.wireline);
|
||||
out.renderOrder = -1;
|
||||
out.sketch_line = this;
|
||||
out.position.z += bump + (order * bump);
|
||||
// create poly outline(s)
|
||||
let outs = this.outs = [];
|
||||
for (let p of [poly, ...(poly.inner || [])]) {
|
||||
let lpt = p.points.map(p => new Vector3(p.x, p.y, p.z));
|
||||
lpt.push(lpt[0]);
|
||||
let lge = new BufferGeometry().setFromPoints(lpt);
|
||||
let out = new THREE.Line(lge, material.wireline);
|
||||
out.renderOrder = -1;
|
||||
out.sketch_line = this;
|
||||
out.position.z += bump + (order * bump);
|
||||
outs.push(out);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -756,7 +756,7 @@ button.selected:hover {
|
|||
grid: min-content 1fr 1fr / min-content 1fr 1fr 1fr;
|
||||
}
|
||||
|
||||
#selectlist .grid1 {
|
||||
#selectlist .grid0 {
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
flex-direction: column;
|
||||
|
|
@ -765,10 +765,14 @@ button.selected:hover {
|
|||
gap: 5px;
|
||||
}
|
||||
|
||||
#selectlist .grid2 {
|
||||
#selectlist .grid1 {
|
||||
grid: min-content 1fr / min-content 1fr;
|
||||
}
|
||||
|
||||
#selectlist .grid2 {
|
||||
grid: min-content 1fr 1fr / min-content 1fr 1fr;
|
||||
}
|
||||
|
||||
.grid .ungrouped {
|
||||
background-color: rgba(128,128,128,0.5) !important;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue