Closed johnsonm closed 3 years ago
I changed to an array for:
function Union(objectsToJoin: oc.TopoDS_Shape[], keepObjects?: boolean, fuzzValue?: number, keepEdges?: boolean): oc.TopoDS_Shape
Also nudged the pegs into the board by 1 unit as co-planar faces can slow down boolean operations.
let clearance = 1; let baseLen = 25; let units = 8; let dWid = baseLen / 2.414; let bezelInset = 3; let boardWidth = units baseLen + 2 bezelInset;
let boardHeight = 5; let pegHeight = 6; let pegOffset = pegHeight / 2 + boardHeight;
function peg() { let pegLeg = dWid - clearance; return Rotate([0, 0, 1], 45, Box(pegLeg, pegLeg, pegHeight, true)); } var a=[] function baseBoard(){ let board = Translate([0, 0, boardHeight / 2], Box(boardWidth, boardWidth, boardHeight, true)); for (let x = 1; x < units; x++) { let xOffset = (x - units / 2) baseLen; for (let y = 1; y < units; y++) { let yOffset = (y - units / 2) baseLen; //board = Union(board, Translate([xOffset, yOffset, pegOffset], peg())); a.push( Translate([xOffset, yOffset, pegOffset-1], peg()) ) } } a.push(board); board=Union(a); return board; }
baseBoard();
Thank you! This was excerpted from a larger model. I feel silly about missing the list on the Union
invocation; every other Union
in my surrounding code not copied when I made this simplified model did that right.
All of my OpenSCAD models have explicit overlap to avoid co-planar surfaces; I just was noticing that you managed to avoid Z-fighting in some trivial examples, and I was playing with co-planar surfaces on purpose. ☺
Here's my version — which, since I sometimes have thin parts, makes me ask how much overlap is useful for avoiding co-planar surfaces. Do you have a heuristic similarity value which should be a minimum overlap for computational efficiency?
function peg() {
let pegLeg = dWid - clearance;
return Rotate([0, 0, 1], 45, Box(pegLeg, pegLeg, pegHeight+0.2, true));
}
function baseBoard() {
let board = [Translate([0, 0, boardHeight / 2], Box(boardWidth, boardWidth, boardHeight, true))];
for (let x = 1; x < units; x++) {
let xOffset = (x - units / 2) * baseLen;
for (let y = 1; y < units; y++) {
let yOffset = (y - units / 2) * baseLen;
board.push(Translate([xOffset, yOffset, pegOffset-0.1], peg()));
}
}
return Union(board);
}
Here's my completed test model just in case it's interesting as an example. It's a representation of the "Pathagon" game that I saw when I looked around for something geometric to try to model as a real-life example.
let clearance = 1;
let partClearance = 5;
let baseLen = 25;
let units = 8;
let dWid = baseLen / 2.414;
let bezelInset = 3;
let boardWidth = units * baseLen + 2 * bezelInset;
let bezelWidth = 14;
let bezelHeight = 12;
let bezelLength = boardWidth + 2 * bezelWidth - 2 * bezelInset;
let bezelInsetOffset = 2;
let boardHeight = 3;
let pegHeight = 6;
let pegOffset = pegHeight / 2 + boardHeight;
let pawnHeight = pegHeight + 4;
let pawnsPerSide = 14;
let assembled = Checkbox("Assembled", false);
let darkPieces = Checkbox("Dark pieces", false);
function pawn() {
let pawnLeg = baseLen - clearance;
let basePawn = Box(pawnLeg, pawnLeg, pawnHeight, true);
return Intersection([
basePawn,
Rotate([0, 0, 1], 45, basePawn)
]);
}
function peg() {
let pegLeg = dWid - clearance;
return Rotate([0, 0, 1], 45, Box(pegLeg, pegLeg, pegHeight+0.2, true));
}
function baseBoard() {
let board = [Translate([0, 0, boardHeight / 2], Box(boardWidth, boardWidth, boardHeight, true))];
for (let x = 1; x < units; x++) {
let xOffset = (x - units / 2) * baseLen;
for (let y = 1; y < units; y++) {
let yOffset = (y - units / 2) * baseLen;
board.push(Translate([xOffset, yOffset, pegOffset-0.1], peg()));
}
}
return Union(board);
}
function bezel() {
return Translate([0, 0, bezelWidth / 2],
FilletEdges(
Difference(
ChamferEdges(Box(bezelLength, bezelHeight, bezelWidth, true), bezelWidth - 0.01, [1, 5]),
[Translate([0, boardHeight-bezelHeight/2, bezelWidth / 2 - bezelInset / 2], Box(bezelLength, boardHeight, bezelInset, true))]
),
1.5, [15, 19]
)
);
}
function bezelSet() {
return Rotate([0, 0, 1], 90, Union([
Translate([0, -(bezelHeight / 2 + partClearance/2), 0], bezel()),
Translate([0, bezelHeight / 2 + partClearance/2, 0], bezel())
]));
}
function pawnSet() {
let pawns = [];
for (let y = 0; y < pawnsPerSide/2; y++) {
pawns.push(Translate([0, boardWidth/2 - baseLen/2 - y * (baseLen + partClearance), 0], pawn()));
pawns.push(Translate([baseLen + partClearance, boardWidth/2 - baseLen/2 -y * (baseLen + partClearance), 0], pawn()));
}
return Union(pawns);
}
if (assembled) {
Translate([0, 0, bezelInsetOffset], baseBoard());
let b = Translate([0, boardWidth/2 + bezelWidth - bezelInset, bezelHeight/2], Rotate([1, 0, 0], 90, bezel()));
for (let n=0; n < 4; n++) {
b = Rotate([0, 0, 1], 90, b, true);
}
for (let x=0; x < units; x++) {
for (let y=0; y < units; y++) {
// show that every position could be filled with one of the 28 actual pawns
Translate([-baseLen*units/2 + baseLen/2 + baseLen*x, -baseLen*units/2 + baseLen/2 + baseLen*y, bezelInsetOffset+boardHeight], pawn());
}
}
} else if (darkPieces) {
Translate([baseLen/2 + partClearance, 0, 0], pawnSet());
Translate([-(bezelWidth + partClearance), 0, 0], bezelSet());
} else {
baseBoard();
Translate([boardWidth/2 + baseLen/2 + partClearance, 0, 0], pawnSet());
Translate([-(boardWidth/2 + bezelWidth + partClearance), 0, 0], bezelSet());
}
Thanks Michael!
It's an interesting example.
I'm trying our CascadeStudio after years of OpenSCAD and there are a lot of things I really like about it! A well-known language, fillets and chamfers, and so far zero Z-fighting come to mind. Thanks for working on it, it's really an attractive idea. I looked around for something geometrical to model as an exercise and saw a game, so tried modeling it as an exercise to learn CascadeStudio.
The line numbers in the error messages not being linked back to the line numbers in the source has given me a little trouble finding the occasional misplace parenthesis. But this looks like even if the model has a bug, it might also be a bug in CascadeStudio. I'm getting lots of errors of this sort:
I narrowed my model down to something relatively simple:
https://zalo.github.io/CascadeStudio/?code=hVJNa4QwEL37K%2BaoNf3QuqVg97KnFhYKpaWHsgfrjq4gsWgEbdn%2F3kliPnZ7aBCTGTPvvXljiwLKFou%2B4CXCGpI8aCn1WQy4RU6JdKUzI2%2FEQPG9DvfvzZ4ic%2B8a0qssyZZi%2FMb2iQ90XMPtkuuKXtaIA%2BU01oWtjiGVkS3LA1fziE19kECLji%2BsberOpp6rStO5zySJgD0MQq1GXoqm4%2FJaGMFPALQWiC3WVK%2F6unSW5OpKj2LsObx0ohAYftwwoCfZMchWDDbdFOp6Bt6uSRmIfsQoyoOjRy8b30hlJyKUVtLwSsxD6zH5RlBbO83pLGXw53zOLjmqrodQEk1q0LQ96FHQMY6NEqNmsp6GEzmiZ0bskRtcbgss9KyhZwc9n0Ib%2BNnBz%2F%2FCy2XceePkoG6e%2BVYteplBZu6%2FIMP0xI0Tch0D917mq0DVpLwB5b8%3D&gui=Pc0xC8IwEAXgvyI3h3AmLmYR0VWHDC7icCanDTZp6bU4iP%2FdKNTxPd7He0Hoct8VLuORMoODQBIo8inxExQcWBrPAg61sf%2Foqdzr9owal8pcFOwoNLwBNw4TK%2FAU01SNtXo9p5kYVCusYivC%2BdpyBHejVqra0%2FBY9InD9%2B7XvT8%3D
Thanks!