106 lines
3.5 KiB
JavaScript
106 lines
3.5 KiB
JavaScript
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
|
|
|
import { CamOp } from './op.js';
|
|
import { Tool } from './tool.js';
|
|
import { generate as Topo } from './topo3.js';
|
|
import { newSlice } from '../../core/slice.js';
|
|
import { newPolygon } from '../../../geo/polygon.js';
|
|
import { polygons as POLY } from '../../../geo/polygons.js';
|
|
import { util as base_util } from '../../../geo/base.js';
|
|
import { calc_normal, calc_vertex } from '../../../geo/paths.js';
|
|
import { CAM } from './driver-be.js';
|
|
|
|
const DEG2RAG = Math.PI / 180;
|
|
|
|
class OpArea extends CamOp {
|
|
constructor(state, op) {
|
|
super(state, op);
|
|
}
|
|
|
|
async slice(progress) {
|
|
const pocket = this;
|
|
let { op, state } = this;
|
|
let { tool, mode, down, over, follow, expand, plunge, smooth, tolerance } = op;
|
|
let { ov_topz, ov_botz, ov_conv } = op;
|
|
let { settings, widget, zBottom, tabs, color } = state;
|
|
let { addSlices, setToolDiam, cutTabs, healPolys, shadowAt, workarea } = state;
|
|
|
|
let areaTool = new Tool(settings, tool);
|
|
let toolDiam = areaTool.fluteDiameter();
|
|
|
|
zBottom = ov_botz ? workarea.bottom_stock + ov_botz : zBottom;
|
|
|
|
setToolDiam(toolDiam);
|
|
|
|
// selected area polygons: surfaces and edges
|
|
let { devel, edgeangle } = settings.controller;
|
|
let groups = [];
|
|
let polys = [];
|
|
|
|
function newGroup() {
|
|
groups.push(newSlice());
|
|
return groups.peek();
|
|
}
|
|
|
|
// gather area selections
|
|
for (let arr of (op.areas[widget.id] ?? [])) {
|
|
polys.push(newPolygon().fromArray(arr));
|
|
}
|
|
|
|
// gather surface selections
|
|
let vert = widget.getGeoVertices({ unroll: true, translate: true }).map(v => v.round(4));
|
|
let faces = CAM.surface_find(widget, (op.surfaces[widget.id] ?? []), (follow ?? edgeangle ?? 5) * DEG2RAG);
|
|
let fpoly = [];
|
|
for (let face of faces) {
|
|
let i = face * 9;
|
|
fpoly.push(newPolygon()
|
|
.add(vert[i++], vert[i++], vert[i++])
|
|
.add(vert[i++], vert[i++], vert[i++])
|
|
.add(vert[i++], vert[i++], vert[i++])
|
|
);
|
|
}
|
|
|
|
// connect open poly edge segments into closed loops (when possible)
|
|
// surface and edge selections produce open polygons by default
|
|
polys = POLY.nest(healPolys(polys));
|
|
|
|
// add in surface areas
|
|
polys.push(...POLY.union(fpoly, 0.0001, true));
|
|
|
|
// expand selections (flattens z variable polys)
|
|
if (Math.abs(expand) > 0) {
|
|
let nupolys = polys.filter(p => p.open); // set aside open
|
|
for (let p of polys.filter(p => !p.open)) {
|
|
let expanded = POLY.expand([ p ], expand);
|
|
if (expanded) {
|
|
POLY.setZ(expanded, p.minZ());
|
|
nupolys.push(...expanded.flat());
|
|
}
|
|
}
|
|
polys = nupolys;
|
|
}
|
|
|
|
// process each area separately
|
|
for (let area of polys) {
|
|
let bounds = area.getBound3D();
|
|
console.log({ area, bounds });
|
|
|
|
if (devel) newGroup().output()
|
|
.setLayer("areas", { line: 0xff8800 }, false)
|
|
.addPolys(polys);
|
|
}
|
|
|
|
addSlices(groups);
|
|
}
|
|
|
|
prepare(ops, progress) {
|
|
let { op, state, pockets } = this;
|
|
let { getPrintPoint , pocket, setTool, setSpindle, setTolerance } = ops;
|
|
let { process } = state.settings;
|
|
|
|
setTool(op.tool, op.rate);
|
|
setSpindle(op.spindle);
|
|
}
|
|
}
|
|
|
|
export { OpArea };
|