2

I'm trying to subtract a polyhedron from a cube, but it is not working (the cube remains solid). However, I can see the cut-out poly in preview mode (but not after a full render).

Preview -- poly cutout shows on the top (and bottom).

Rendered -- poly cutout not visible.

Poly Exploded -- pulled the poly to the right to show its shape.

Code

size = 30;
wall = 3;
wall_x2 = wall * 2;
nubGap = .125;
nubHeight = 8;
nubOffset = wall + nubGap;
xCutoutSize = size - wall_x2;
yCutoutSize = size - wall_x2;
cutoutLowerY = nubHeight + nubGap;
cutoutUpperOffset = nubOffset + wall;

difference() {
cube([size, size, size]);

translate([wall, wall, 0]) {
polyhedron(
points = [
[0, 0, -10],
[xCutoutSize, 0, -10],
[xCutoutSize, yCutoutSize, -10],
[0, yCutoutSize, -10],

[0, 0, cutoutLowerY],
[xCutoutSize, 0, cutoutLowerY],
[xCutoutSize, yCutoutSize, cutoutLowerY],
[0, yCutoutSize, cutoutLowerY],

[cutoutUpperOffset, cutoutUpperOffset, size],
[xCutoutSize - cutoutUpperOffset, cutoutUpperOffset, size],
[xCutoutSize - cutoutUpperOffset, yCutoutSize - cutoutUpperOffset, size],
[cutoutUpperOffset, yCutoutSize - cutoutUpperOffset, size]
],
faces = [
[0, 1, 2], [2, 3, 0],     // bottom

[0, 1, 4], [1, 4, 5],     // side A
[1, 2, 5], [2, 5, 6],     // side B
[2, 3, 6], [3, 6, 7],     // side C
[3, 0, 7], [0, 7, 4],     // side D

[4, 5,  8], [5,   8,  9], // slope A
[5, 6,  9], [6,   9, 10], // slope B
[6, 7, 10], [7,  10, 11], // slope C
[7, 4, 11], [4,  11,  8], // slope D

[8, 9, 10], [10, 11,  8]  // top
]
);
};
};


4

Usually when there's an overlap in two objects during a difference action, F6 render will resolve the problem. There's something more than that involved here, as reducing the height of the cube creates a non-manifold object from the difference. user R..'s answer has merit but is not going to solve the problem.

Isolating the cube from the code and exporting the result as an STL allows me to determine that the faces are generated in a manner preventing a proper difference action:

This image from meshmixer shows the faces have inverted normals. The order of the points are critical when describing a polyhedron. From the wiki page for OpenSCAD:

It is arbitrary which point you start with, but all faces must have points ordered in the same direction . OpenSCAD prefers clockwise when looking at each face from outside inward. The back is viewed from the back, the bottom from the bottom, etc. Another way to remember this ordering requirement is to use the right-hand rule. Using your right-hand, stick your thumb up and curl your fingers as if giving the thumbs-up sign, point your thumb into the face, and order the points in the direction your fingers curl.

EDIT: I reversed some of the points, haphazardly and luckily picked the correct ones:

        faces = [
[0, 1, 2], [2, 3, 0],     // bottom

[4, 1, 0], [1, 4, 5],     // side A
[5, 2, 1], [2, 5, 6],     // side B
[6, 3, 2], [3, 6, 7],     // side C
[7, 0, 3], [0, 7, 4],     // side D

[8, 5, 4], [5,   8,  9], // slope A
[9, 6, 5], [6,   9, 10], // slope B
[10, 7, 6], [7,  10, 11], // slope C
[11, 4, 7], [4,  11,  8], // slope D

[10, 9, 8], [8, 11, 10]  // top


Ah, that makes sense, I'll give it a try. Thanks! – Josh M. – 2020-11-28T12:19:45.283

1Yes, OpenSCAD requires consistent normals, and from my experience actually requires (not just prefers) them pointing inwards if you want CSG functionality to all work right. – R.. GitHub STOP HELPING ICE – 2020-11-28T14:33:43.327

1I wasn't sure about the "requires versus prefers... pointing inwards" reference, but it's "prefers clockwise" according to the wiki. – fred_dot_u – 2020-11-28T15:59:55.777

Thanks. I had just reordered the points so they were clockwise but had a similar but different issue. I guess I don't understand why (for Side A) [4, 1, 0] works but [0, 4, 1] does not (as applied to all other faces) -- they are both clockwise looking at the face, but starting from the "top" is perhaps the difference? – Josh M. – 2020-11-28T16:16:31.163

2

If the polyhedron surface and top surface of the cube are exactly coplanar, which they seem to be, it won't work; OpenSCAD operates numerically rather than analytically and which is "inside" or "outside" the other is subject to numerical instability. Whenever using differences you need to make the object being subtracted extend by at least some small epsilon outside the surfact of the object you're subtracting from.

I did extend the bottom of the poly down through the bottom of the cube and got the same results. I'll try that again, though. – Josh M. – 2020-11-28T12:17:17.853