2
$\begingroup$

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).

preview

Rendered -- poly cutout not visible.

rendered

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

poly exploded

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
            ]
        );
    };
};
$\endgroup$
4
$\begingroup$

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:

meshmixer image

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

rendered code

$\endgroup$
4
  • $\begingroup$ Ah, that makes sense, I'll give it a try. Thanks! $\endgroup$
    – Josh M.
    Nov 28 '20 at 12:19
  • 1
    $\begingroup$ Yes, 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. $\endgroup$ Nov 28 '20 at 14:33
  • 1
    $\begingroup$ I wasn't sure about the "requires versus prefers... pointing inwards" reference, but it's "prefers clockwise" according to the wiki. $\endgroup$
    – fred_dot_u
    Nov 28 '20 at 15:59
  • $\begingroup$ 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? $\endgroup$
    – Josh M.
    Nov 28 '20 at 16:16
2
$\begingroup$

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.

$\endgroup$
1
  • $\begingroup$ 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. $\endgroup$
    – Josh M.
    Nov 28 '20 at 12:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.