Skip to content

Commit

Permalink
Merge pull request #1259 from jsxcad/headless-2
Browse files Browse the repository at this point in the history
Redesign sort() and add desk design.
  • Loading branch information
pentacular authored Dec 3, 2024
2 parents d7bf56e + 4bde3e6 commit a156683
Show file tree
Hide file tree
Showing 28 changed files with 605 additions and 223 deletions.
3 changes: 1 addition & 2 deletions algorithm/cgal/Pack.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,7 @@ static int Pack(Geometry* geometry, size_t count,

auto display_pwhs =
[&](const std::vector<CGAL::Polygon_with_holes_2<EK>>& pwhs,
const std::string& tag) {
};
const std::string& tag) {};

auto cut_part_from_sheet =
[&](Sheet& sheet, const Part& part,
Expand Down
43 changes: 30 additions & 13 deletions api/shape/size.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,17 @@ export const size = Shape.registerMethod3(
[
'inputGeometry',
'function',
'strings:empty,max,min,right,left,front,back,top,bottom,length,width,height,center',
'strings:empty,max,min,maxX,maxY,maxZ,minX,minY,minZ,right,left,front,back,top,bottom,length,width,height,center',
'options',
],
async (geometry, _op, modes) => {
async (geometry, _op, modes, { resolution = 0.01 } = {}) => {
const round = (value) => {
if (resolution === 0) {
return value;
} else {
return Math.round(value / resolution) * resolution;
}
};
const bounds = measureBoundingBox(geometry);
const args = [];
if (bounds === undefined) {
Expand All @@ -43,39 +51,48 @@ export const size = Shape.registerMethod3(
args.push(false);
break;
case 'max':
args.push(max);
// CHECK: This is return a vector rather than a scalar.
args.push(round(max));
break;
case 'min':
args.push(min);
// CHECK: This is return a vector rather than a scalar.
args.push(round(min));
break;
case 'maxX':
case 'right':
args.push(max[X]);
args.push(round(max[X]));
break;
case 'minX':
case 'left':
args.push(min[X]);
args.push(round(min[X]));
break;
case 'minY':
case 'front':
args.push(min[Y]);
args.push(round(min[Y]));
break;
case 'maxY':
case 'back':
args.push(max[Y]);
args.push(round(max[Y]));
break;
case 'maxZ':
case 'top':
args.push(max[Z]);
args.push(round(max[Z]));
break;
case 'minZ':
case 'bottom':
args.push(min[Z]);
args.push(round(min[Z]));
break;
case 'length':
args.push(max[X] - min[X]);
args.push(round(max[X] - min[X]));
break;
case 'width':
args.push(max[Y] - min[Y]);
args.push(round(max[Y] - min[Y]));
break;
case 'height':
args.push(max[Z] - min[Z]);
args.push(round(max[Z] - min[Z]));
break;
case 'center':
// CHECK: This is return a vector rather than a scalar.
args.push(scale(0.5, add(min, max)));
break;
}
Expand Down
87 changes: 26 additions & 61 deletions api/shape/sort.js
Original file line number Diff line number Diff line change
@@ -1,78 +1,43 @@
import { Group, getLeafs, measureBoundingBox } from '@jsxcad/geometry';
import { Group, getLeafs } from '@jsxcad/geometry';

import Shape from './Shape.js';

const X = 0;
const Y = 1;
const Z = 2;

const round = (values, resolution) =>
values.map((value) => Math.round(value / resolution) * resolution);

export const sort = Shape.registerMethod3(
'sort',
['inputGeometry', 'string', 'number'],
(geometry, spec = 'z<y<x<', resolution = 0.01) => {
let leafs = [];
['inputGeometry', 'function', 'modes:min,max', 'numbers'],
async (geometry, rankOp = () => 0, mode, tiersToKeep = []) => {
let predicate = (a, b) => a - b;
if (mode.max) {
// Start from the max tier.
predicate = (a, b) => b - a;
}
const leafs = [];
for (const leaf of getLeafs(geometry)) {
console.log(JSON.stringify(leaf));
const bounds = measureBoundingBox(leaf);
if (bounds === undefined) {
continue;
}
const [min, max] = bounds;
const rank = await rankOp(Shape.fromGeometry(leaf));
leafs.push({
min: round(min, resolution),
max: round(max, resolution),
rank,
leaf,
});
}
const ops = [];
while (spec) {
const found = spec.match(/([xyz])([<>])([0-9.])?(.*)/);
if (found === null) {
throw Error(`Bad sort spec ${spec}`);
leafs.sort((a, b) => predicate(a.rank, b.rank));
let lastLeaf;
let tier;
const tiers = [];
for (const thisLeaf of leafs) {
if (!lastLeaf || lastLeaf.rank !== thisLeaf.rank) {
tier = [];
tiers.push(tier);
}
const [, dimension, order, limit, rest] = found;
// We apply the sorting ops in reverse.
ops.unshift({ dimension, order, limit });
spec = rest;
tier.push(thisLeaf);
}
for (const { dimension, order, limit } of ops) {
let axis;
switch (dimension) {
case 'x':
axis = X;
break;
case 'y':
axis = Y;
break;
case 'z':
axis = Z;
break;
}
if (limit !== undefined) {
switch (order) {
case '>':
leafs = leafs.filter(({ min }) => min[axis] > limit);
break;
case '<':
leafs = leafs.filter(({ max }) => max[axis] < limit);
break;
}
}
let compare;
switch (order) {
case '>':
compare = (a, b) => b.min[axis] - a.min[axis];
break;
case '<':
compare = (a, b) => a.max[axis] - b.max[axis];
break;
// Structure the results by rank tiers.
const keptTiers = [];
for (let nth = 0; nth < tiers.length; nth++) {
if (tiersToKeep.length === 0 || tiersToKeep.includes(nth + 1)) {
keptTiers.push(tiers[nth]);
}
leafs.sort(compare);
}
return Group(leafs.map(({ leaf }) => leaf));
return Group(keptTiers.map((tier) => Group(tier.map(({ leaf }) => leaf))));
}
);

Expand Down
8 changes: 8 additions & 0 deletions api/shape/view.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ const topViewOp = (
op = (_x) => (s) => s,
{
download,
downloadOp,
size = 256,
skin = true,
outline = true,
Expand All @@ -127,6 +128,7 @@ const topViewOp = (
) => {
const options = {
download,
downloadOp,
size,
skin,
outline,
Expand All @@ -150,6 +152,7 @@ const gridViewOp = (
op = (_x) => (s) => s,
{
download,
downloadOp,
size = 256,
skin = true,
outline = true,
Expand All @@ -162,6 +165,7 @@ const gridViewOp = (
) => {
const options = {
download,
downloadOp,
size,
skin,
outline,
Expand All @@ -185,6 +189,7 @@ const frontViewOp = (
op = (_x) => (s) => s,
{
download,
downloadOp,
size = 256,
skin = true,
outline = true,
Expand All @@ -197,6 +202,7 @@ const frontViewOp = (
) => {
const options = {
download,
downloadOp,
size,
skin,
outline,
Expand All @@ -220,6 +226,7 @@ const sideViewOp = (
op = (_x) => (s) => s,
{
download,
downloadOp,
size = 256,
skin = true,
outline = true,
Expand All @@ -232,6 +239,7 @@ const sideViewOp = (
) => {
const options = {
download,
downloadOp,
size,
skin,
outline,
Expand Down
6 changes: 5 additions & 1 deletion doc/updateNotebook.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,11 @@ const writeMarkdown = async (
}
const observedPath = `${modulePath}.observed.${filename}`;
const expectedPath = `${modulePath}.${filename}`;
if (!filename.endsWith('stl') && !filename.endsWith('pdf') && !filename.endsWith('png')) {
if (
!filename.endsWith('stl') &&
!filename.endsWith('pdf') &&
!filename.endsWith('png')
) {
// STL output has become unstable; skip for now.
try {
const observed = new TextDecoder('utf8').decode(data);
Expand Down
Loading

0 comments on commit a156683

Please sign in to comment.