joostn / OpenJsCad

3D solid CAD using only Javascript
313 stars 127 forks source link

issue in fixTJunctions #61

Open bebbi opened 9 years ago

bebbi commented 9 years ago

See also #60 . This issue here is about fixing fixTJunctions.. While I think #60 is more important, here is another example that trigger either assertionFailed or sidemapIsEmpty depending on very minor changes in numbers. Possibly helps narrow down the issue.

    function main() {
        // this r produces assertion failed (unless H triggers sidemapisempty)
        var r = 2.306667;
        // this r produces sidemapisempty
        // var r = 2.30667;

        // this H produces sidemapisempty
        var H = 0.69333;
        // this H produces assertion failed
        // var H = 0.693333;

        var rotPath = CSG.Path2D.arc({
            center: [8.8, H],
            radius: r,
            startangle: 0,
            endangle: 90,
            resolution: 15 * r
        });
        rotPath = rotPath.appendPoints([[0, 3], [0, 0]]);
        var cag = CAG.fromPoints(rotPath.points);
        var csg_fail = cag.rotateExtrude({
            angle: 360,
            resolution: 50
        });
        var polys = csg_fail.polygons.filter(function(p){return p.getArea() > 1e-10});
        var csg_pass = CSG.fromPolygons(polys);
        return csg_fail; // vs csg_pass that works
    }
joostn commented 9 years ago

I haven't been able to get to the bottom of this but it looks like it's caused by nasty rounding errors. I guess these might leave small holes in the CSG so it's no longer watertight. At least that's what !sidemapisempty means: some sides have not been matched with a companion side in opposite direction.

I'd suggest (for now) just to comment out the 'throw new Error("!sidemapisempty");' line. The resulting solid is not watertight but many slicers will be able to handle this.

bebbi commented 9 years ago

For completeness, here's another one. It's a very different path to csg, so it may help (or distract..)

function main() {
    var res = CSG.sphere({
        radius: 1,
        resolution: 50
    });
    var stretchradius = [10, 4];
    var roundradius = [2, 3.5, 0.001];
    res = res.scale(roundradius);
    res = res.stretchAtPlane([1, 0, 0], [0, 0, 0], stretchradius[0]);
    res = res.stretchAtPlane([0, 1, 0], [0, 0, 0], stretchradius[1]);
    return res;
}

Meshmixer shows holes (blue pin) and non-manifold areas (red pin): holes

ghost commented 8 years ago

FYI, I've found that fixTJunctions() after a simple CSG operation leaves one T-junction untouched:

function main() {
   return CSG.cube({radius: 1.0, center: [0, 0, 0]})
         .subtract(CSG.cube({radius: 0.6, center: [0, 0, 0.5]}))
         .scale(10)
         .fixTJunctions();
}

Here is a screenshot of the output geometry opened in MeshLab:

t_junction_issue

z3dev commented 8 years ago

@sergerusso has an open pull request at @spiritdude OpenJSCAD.org, which addresses this issue as well. Please review.