flat color work

This commit is contained in:
Stewart Allen 2020-11-13 13:52:35 -05:00
commit ec90480f84
6 changed files with 54 additions and 31 deletions

View file

@ -1,6 +1,6 @@
{ {
"name": "grid-apps", "name": "grid-apps",
"version": "2.3.D7", "version": "2.3.D8",
"description": "grid.space 3d slice & modeling tools", "description": "grid.space 3d slice & modeling tools",
"author": "Stewart Allen <sa@grid.space>", "author": "Stewart Allen <sa@grid.space>",
"license": "MIT", "license": "MIT",

View file

@ -113,6 +113,7 @@
polys: encode(layer.polys, state), polys: encode(layer.polys, state),
lines: encodePointArray(layer.lines, state), lines: encodePointArray(layer.lines, state),
faces: codec.allocFloat32Array(layer.faces), faces: codec.allocFloat32Array(layer.faces),
cface: layer.cface,
color: layer.color, color: layer.color,
paths: layer.paths, paths: layer.paths,
cpath: layer.cpath, cpath: layer.cpath,
@ -130,6 +131,7 @@
cpoly: v.data[i].cpoly, cpoly: v.data[i].cpoly,
lines: decodePointArray(v.data[i].lines), lines: decodePointArray(v.data[i].lines),
faces: v.data[i].faces, faces: v.data[i].faces,
cface: v.data[i].cface,
color: v.data[i].color, color: v.data[i].color,
paths: v.data[i].paths, paths: v.data[i].paths,
cpath: v.data[i].cpath, cpath: v.data[i].cpath,

View file

@ -30,9 +30,11 @@
this.current = layers[layer] = layers[layer] || { this.current = layers[layer] = layers[layer] || {
off: off === true, off: off === true,
lines: [], lines: [],
polys: [], polys: [], // colors are an attribute on polygons
faces: [], faces: [],
cface: undefined, // face color indices
paths: [], paths: [],
cpath: undefined, // path colors indices
color: colors || { color: colors || {
line: 0, line: 0,
face: 0, face: 0,
@ -80,10 +82,14 @@
polys = flat(polys); polys = flat(polys);
if (options) { if (options) {
polys.forEach(p => { polys.forEach(p => {
if (options.z !== undefined) p.setZ(options.z); if (options.z !== undefined) {
if (options.color) p.color = options.color; p.setZ(options.z);
}
switch (typeof(options.color)) {
case 'number': p.color = options.color; break;
case 'object': p.color = options.color.line; break;
}
}); });
// if (options.color) console.log({polys, options})
} }
this.current.polys.appendAll(polys); this.current.polys.appendAll(polys);
this.stats.line_poly += polys.length; this.stats.line_poly += polys.length;
@ -113,15 +119,10 @@
return; return;
} }
const z = polys[0].getZ(), faces = this.current.faces; const z = polys[0].getZ(), faces = this.current.faces;
const open = opts.open || false; const off_opt = { z, flat: true };
const off_opt = {
z,
flat: true,
type: open ? ClipperLib.EndType.etOpenSquare : undefined,
};
polys.forEach(poly => { polys.forEach(poly => {
let exp = off_opt.outs = []; let exp = off_opt.outs = [];
if (open) { if (poly.isOpen()) {
exp.appendAll(POLY.expand_lines(poly, offset * 0.9, z)); exp.appendAll(POLY.expand_lines(poly, offset * 0.9, z));
this.stats.flat_line = 0; this.stats.flat_line = 0;
} else if (offset) { } else if (offset) {
@ -132,11 +133,26 @@
if (opts.outline) { if (opts.outline) {
this.addPolys(exp.clone()); this.addPolys(exp.clone());
} }
const faceidx = faces.length / 3;
POLY.nest(exp).forEach((poly,i) => { POLY.nest(exp).forEach((poly,i) => {
poly.earcut().forEach(ep => { poly.earcut().forEach(ep => {
ep.forEachPoint(p => { faces.push(p.x, p.y, p.z) }); ep.forEachPoint(p => { faces.push(p.x, p.y, p.z) });
}); });
}); });
const cur = this.current;
const color = opts.color ?
(typeof(opts.color === 'number') ? { line: opts.color, face: opts.color } : opts.color) :
cur.color;
if (!cur.cface) {
cur.cface = [ Object.assign({ start: faceidx, count: Infinity }, color) ];
} else {
// rewrite last color count if color or opacity have changed
const pc = cur.cface[cur.cface.length - 1];
if (pc.face !== color.face || pc.opacity !== color.opacity) {
pc.count = faceidx;
cur.cface.push(Object.assign({ start: faceidx, count: Infinity }, color));
}
}
}); });
return this; return this;
} }
@ -167,15 +183,6 @@
poly = poly.debur(0.05); poly = poly.debur(0.05);
if (!poly) return; if (!poly) return;
poly = poly.miter(); poly = poly.miter();
// cleaning converts open to closed which is problematic
// poly = poly.clean().miter();
// if (poly.debug) {
// const save = this.current;
// this.setLayer('debug.acute', 0xff0000).addPoly(poly, {thin:true});
// this.setLayer('debug.start', 0x00ff00).addPoly(newPolygon().centerRectangle(poly.first(),1,1), {thin:true});
// this.setLayer('debug.end', 0x0000ff).addPoly(newPolygon().centerRectangle(poly.last(),0.8,0.8), {thin:true});
// this.current = save;
// }
poly.points.forEach(p => { poly.points.forEach(p => {
contour.push(new THREE.Vector2(p.x, p.y)); contour.push(new THREE.Vector2(p.x, p.y));
}); });
@ -202,7 +209,7 @@
// rewrite last color count if color or opacity have changed // rewrite last color count if color or opacity have changed
const pc = cur.cpath[cur.cpath.length - 1]; const pc = cur.cpath[cur.cpath.length - 1];
if (pc.face !== opts.color.face || pc.opacity !== opts.color.opacity) { if (pc.face !== opts.color.face || pc.opacity !== opts.color.opacity) {
pc.count = indln - 1; pc.count = indln;
cur.cpath.push(Object.assign({ start: indln, count: Infinity }, opts.color)); cur.cpath.push(Object.assign({ start: indln, count: Infinity }, opts.color));
} }
} }

View file

@ -109,7 +109,7 @@
ctrl.toggle.checked = defstate; ctrl.toggle.checked = defstate;
const { polys, cpoly, lines, faces, paths, cpath } = data; const { polys, cpoly, lines, faces, cface, paths, cpath } = data;
if (polys.length || lines.length) { if (polys.length || lines.length) {
const vert = []; // vertexes const vert = []; // vertexes
const mat = []; // materials const mat = []; // materials
@ -123,16 +123,16 @@
const vl = vert.length; const vl = vert.length;
const poly = polys[i]; const poly = polys[i];
addPoly(vert, poly); addPoly(vert, poly);
const pc = poly.color ? { line: poly.color, opacity: data.color.opacity } : data.color; const pc = poly.color !== undefined ? { line: poly.color, opacity: data.color.opacity } : data.color;
const pk = pc.line; const pk = pc.line;
cmap[pk] = cmap[pk] || { idx: cidx++, mat: createLineMaterial(pc, mat) }; const cc = cmap[pk] = cmap[pk] || { idx: cidx++, mat: createLineMaterial(pc, mat) };
if (last !== pk) { if (last !== pk) {
if (grp.length) { if (grp.length) {
// rewrite counts for last group // rewrite counts for last group
const prev = grp[grp.length - 1] const prev = grp[grp.length - 1]
prev[1] = prev[1] - vl; prev[1] = prev[1] - vl;
} }
grp.push([vl, Infinity, cidx - 1]); grp.push([vl, Infinity, cc.idx]);
last = pk; last = pk;
} }
} }
@ -156,17 +156,31 @@
ctrl.group.appendAll(mat); ctrl.group.appendAll(mat);
} }
if (faces.length) { if (faces.length) {
const mat = newMat(data.color); const mat = [];
if (cface) {
cface.forEach(c => { mat.push(newMat(c)) });
} else {
mat.push(newMat(data.color));
}
mat.forEach(m => m.visible = defstate);
const geo = new THREE.BufferGeometry(); const geo = new THREE.BufferGeometry();
geo.setAttribute('position', new THREE.BufferAttribute(faces, 3)); if (faces.toFloat32) {
geo.setAttribute('position', new THREE.BufferAttribute(faces.toFloat32(), 3));
} else {
geo.setAttribute('position', new THREE.BufferAttribute(faces, 3));
}
geo.computeFaceNormals(); geo.computeFaceNormals();
geo.computeVertexNormals(); geo.computeVertexNormals();
if (cface) {
cface.forEach((c, i) => geo.addGroup(c.start, c.count, i));
} else {
geo.addGroup(0, Infinity, 0);
}
const mesh = new THREE.Mesh(geo, mat); const mesh = new THREE.Mesh(geo, mat);
mesh.castShadow = true; mesh.castShadow = true;
mesh.receiveShadow = true; mesh.receiveShadow = true;
group.add(mesh); group.add(mesh);
ctrl.group.push(mat); ctrl.group.push(mat);
mat.visible = defstate;
} }
if (paths.length) { if (paths.length) {
const mat = []; const mat = [];

View file

@ -3,7 +3,7 @@
let terms = { let terms = {
COPYRIGHT: "Copyright (C) Stewart Allen <sa@grid.space> - All Rights Reserved", COPYRIGHT: "Copyright (C) Stewart Allen <sa@grid.space> - All Rights Reserved",
LICENSE: "See the license.md file included with the source distribution", LICENSE: "See the license.md file included with the source distribution",
VERSION: "2.3.D7" VERSION: "2.3.D8"
}; };
if (typeof(module) === 'object') { if (typeof(module) === 'object') {

View file

@ -294,7 +294,7 @@
if (top.fill_sparse) output if (top.fill_sparse) output
.setLayer("infill", COLOR.infill) .setLayer("infill", COLOR.infill)
.addPolys(top.fill_sparse, vopt({ offset, height, open: true, outline: true })) .addPolys(top.fill_sparse, vopt({ offset, height, outline: true }))
if (top.thin_fill) output if (top.thin_fill) output
.setLayer("fill", COLOR.fill) .setLayer("fill", COLOR.fill)