fixes #206 empty surfaces with multi-part and pocket
This commit is contained in:
parent
421d8636bc
commit
0e7d01c8fa
6 changed files with 98 additions and 48 deletions
2
notes.md
2
notes.md
|
|
@ -74,6 +74,8 @@
|
|||
* `B` need to force cut line at synthetic z bottom (midlines, etc)
|
||||
* `B` contour does not honor clip to stock
|
||||
|
||||
* `F` add pause operation with optional gcode
|
||||
* `F` add option for op-major ordering (instead of part major)
|
||||
* `F` animate only selected range (as an option)
|
||||
* `F` add `plunge max` to contouring that can override z feed limit
|
||||
* `F` roughing flats should be constrained to flat region, not create a layer
|
||||
|
|
|
|||
|
|
@ -1005,10 +1005,10 @@ class OpPocket extends CamOp {
|
|||
}
|
||||
}
|
||||
}
|
||||
let surfaces = op.surfaces[widget.id];
|
||||
let surfaces = op.surfaces[widget.id] || [];
|
||||
let vert = widget.getVertices().array.map(v => v.round(4));
|
||||
let prog = 0, pinc= 1 / surfaces.length;
|
||||
for (let surface of surfaces || []) {
|
||||
for (let surface of surfaces) {
|
||||
let outline = [];
|
||||
let faces = CAM.surface_find(widget, [surface]);
|
||||
let zmin = Infinity;
|
||||
|
|
@ -1030,7 +1030,7 @@ class OpPocket extends CamOp {
|
|||
if (false) newSliceOut(zmin).output()
|
||||
.setLayer("pocket area", {line: 0x1188ff}, false)
|
||||
.addPolys(outline)
|
||||
clearZ(outline, zmin, down);
|
||||
clearZ(outline, zmin + 0.0001, down);
|
||||
progress(prog += pinc, "pocket");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,19 +15,54 @@ load.TMF = {
|
|||
parseAsync
|
||||
};
|
||||
|
||||
load.XML = {
|
||||
query
|
||||
};
|
||||
|
||||
let { BufferAttribute, Matrix4 } = THREE;
|
||||
|
||||
function query(node, path, fn) {
|
||||
let collect = false;
|
||||
let match = path[0];
|
||||
if (match[0] === '+') {
|
||||
match = match.slice(1);
|
||||
collect = true;
|
||||
// simple query api for map structures
|
||||
function query_map(node, path, fn) {
|
||||
let collect = {};
|
||||
let match = path[0].split('|').map(key => {
|
||||
if (key[0] === '+') {
|
||||
key = key.slice(1);
|
||||
collect[key] = true;
|
||||
}
|
||||
return key;
|
||||
});
|
||||
for (let [tag, value] of Object.entries(node)) {
|
||||
if (!Array.isArray(value)) {
|
||||
value = [ value ];
|
||||
}
|
||||
if (match.indexOf(tag) >= 0) {
|
||||
for (let node of value) {
|
||||
if (collect[tag]) {
|
||||
fn(tag, node);
|
||||
}
|
||||
if (path.length > 1) {
|
||||
query(node, path.slice(1), fn);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// simple query api for xml structures
|
||||
function query(node, path, fn) {
|
||||
let collect = {};
|
||||
let match = path[0].split('|').map(key => {
|
||||
if (key[0] === '+') {
|
||||
key = key.slice(1);
|
||||
collect[key] = true;
|
||||
}
|
||||
return key;
|
||||
});
|
||||
for (let child of [...node.childNodes]) {
|
||||
if (child.tagName === match) {
|
||||
if (collect) {
|
||||
fn(match, child);
|
||||
let { tagName } = child;
|
||||
if (match.indexOf(tagName) >= 0) {
|
||||
if (collect[tagName]) {
|
||||
fn(tagName, child);
|
||||
}
|
||||
if (path.length > 1) {
|
||||
query(child, path.slice(1), fn);
|
||||
|
|
|
|||
|
|
@ -15,7 +15,47 @@ if (load.File) return;
|
|||
// dep: load.png
|
||||
gapp.register('load.file', []);
|
||||
|
||||
const types = {
|
||||
stl(data, file, resolve, reject) {
|
||||
resolve([{
|
||||
mesh: new load.STL().parse(data), file
|
||||
}]);
|
||||
},
|
||||
|
||||
obj(data, file, resolve, reject) {
|
||||
resolve(load.OBJ.parse(data).map(m => {
|
||||
return { mesh: m.toFloat32(), file: nameOf(file, m.name, 1) }
|
||||
}));
|
||||
},
|
||||
|
||||
"3mf"(data, file, resolve, reject) {
|
||||
let i = 1;
|
||||
load.TMF.parseAsync(data).then((meshes) => {
|
||||
resolve(meshes.map(m => {
|
||||
return { mesh: m.faces.toFloat32(), file: nameOf(file, m.name, i++) }
|
||||
}));
|
||||
});
|
||||
},
|
||||
|
||||
svg(data, file, resolve, reject) {
|
||||
resolve(load.SVG.parse(data).map(m => { return {mesh: m.toFloat32(), file} }));
|
||||
},
|
||||
|
||||
png(data, file, resolve, reject) {
|
||||
load.PNG.parse(data, {
|
||||
...opt,
|
||||
done(data) {
|
||||
resolve({ mesh: data, file });
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const as_buffer = [ "stl", "png", "3mf" ];
|
||||
|
||||
load.File = {
|
||||
types,
|
||||
as_buffer,
|
||||
load_data,
|
||||
load: load_file
|
||||
};
|
||||
|
|
@ -31,39 +71,11 @@ function nameOf(file, part, i) {
|
|||
function load_data(data, file, ext, opt = {}) {
|
||||
ext = ext || name.toLowerCase().split('.').pop();
|
||||
return new Promise((resolve, reject) => {
|
||||
let i = 1;
|
||||
switch (ext) {
|
||||
case "stl":
|
||||
resolve([{
|
||||
mesh: new load.STL().parse(data), file
|
||||
}]);
|
||||
break;
|
||||
case "obj":
|
||||
resolve(load.OBJ.parse(data).map(m => {
|
||||
return { mesh: m.toFloat32(), file: nameOf(file, m.name, i++) }
|
||||
}));
|
||||
break;
|
||||
case "3mf":
|
||||
load.TMF.parseAsync(data).then((meshes) => {
|
||||
resolve(meshes.map(m => {
|
||||
return { mesh: m.faces.toFloat32(), file: nameOf(file, m.name, i++) }
|
||||
}));
|
||||
});
|
||||
break;
|
||||
case "svg":
|
||||
resolve(load.SVG.parse(data).map(m => { return {mesh: m.toFloat32(), file} }));
|
||||
break;
|
||||
case "png":
|
||||
load.PNG.parse(data, {
|
||||
...opt,
|
||||
done(data) {
|
||||
resolve({ mesh: data, file });
|
||||
}
|
||||
});
|
||||
break;
|
||||
default:
|
||||
reject(`unknown file type: "${ext}" from ${file}`);
|
||||
break;
|
||||
let fn = types[ext];
|
||||
if (fn) {
|
||||
fn(data, file, resolve, reject);
|
||||
} else {
|
||||
reject(`unknown file type: "${ext}" from ${file}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -85,7 +97,7 @@ function load_file(file, opt) {
|
|||
.then(data => resolve(data))
|
||||
.catch(e => reject(e));
|
||||
};
|
||||
if (["stl","png","3mf"].indexOf(ext) >= 0) {
|
||||
if (as_buffer.indexOf(ext) >= 0) {
|
||||
reader.readAsArrayBuffer(reader.file);
|
||||
} else {
|
||||
reader.readAsBinaryString(reader.file);
|
||||
|
|
|
|||
|
|
@ -522,7 +522,8 @@ function load_files_opt(files, opt) {
|
|||
|
||||
// add object loader
|
||||
function space_load(data) {
|
||||
mesh.api.group.new(data.flat().map(el => new mesh.model(el)))
|
||||
if (data && data.length && (data = data.flat()).length)
|
||||
mesh.api.group.new(data.map(el => new mesh.model(el)))
|
||||
.promote()
|
||||
.focus();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@
|
|||
</script>
|
||||
</head>
|
||||
<body onload="onload()">
|
||||
<h2 id="title">Kiri:Moto Javascript Engine API</h2>
|
||||
<h2 id="title">Kiri:Moto Javascript Engine <a href="https://docs.grid.space/projects/kiri-moto/apis">API</a></h2>
|
||||
<div id="demo">
|
||||
<div id="jcode">
|
||||
<div id="jhead">javascript</div>
|
||||
|
|
|
|||
Loading…
Reference in a new issue