sgenoud / replicad

The library to build browser based 3D models with code.
https://replicad.xyz
MIT License
323 stars 38 forks source link

Cutting a fused shape shows only edges #93

Open bramvandooren opened 11 months ago

bramvandooren commented 11 months ago

When trying the code below to cutout a fused circle with text it only show the edges of the fused shape instead of it being cut.

const main = (r) => {
       function center(drawing) {
            const boundingBox = drawing.boundingBox;
            drawing = drawing.translate(-boundingBox.center[0], -boundingBox.center[1]);

            return drawing;
        }

        let plate = drawRectangle(5, 5).cut(
            drawCircle(0.5)
                .fuse(center(drawText('test', { fontSize: 2 })).translate(0, 0.8).rotate(90))
        );

        return plate.sketchOnPlane('XY').extrude(0.2);
};
Screenshot 2023-07-31 165913

This also happens when only using a to be cutout when using this code:

const main = (r) => {
       function center(drawing) {
            const boundingBox = drawing.boundingBox;
            drawing = drawing.translate(-boundingBox.center[0], -boundingBox.center[1]);

            return drawing;
        }

        let text = drawText( 'text');
        text = text
            .stretch(1 / (text.boundingBox.width / 7.5), [0, 1], text.boundingBox.center)
            .stretch(1 / (text.boundingBox.height / 2), [1, 0], text.boundingBox.center);

        let plate = drawRectangle(10, 20).cut(
          center(text)
        );

        return plate.sketchOnPlane('XY').extrude(0.2);
};
Screenshot 2023-08-01 094442
raydeleu commented 8 months ago

I suspected that the character "e" could be the culprit, but this seems not the case. A simple workaround is to extrude the shapes first before performing the cut.

const {draw, drawRectangle, drawCircle, drawText} = replicad

const main = (r) => {
       function center(drawing) {
            const boundingBox = drawing.boundingBox;
            drawing = drawing.translate(-boundingBox.center[0], -boundingBox.center[1]);

            return drawing;
        }

        let plate = drawRectangle(5, 5).sketchOnPlane("XY").extrude(0.2)
        let cutter = drawCircle(0.5).fuse(center(drawText('test', { fontSize: 2 })).translate(0, 0.8).rotate(90))
        cutter = cutter.sketchOnPlane("XY").extrude(1.0);
        plate = plate.cut(cutter)

        return plate;
};

image

raydeleu commented 8 months ago

Just doodling ... single characters work fine, but multiple characters fail. Perhaps a relation with an earlier issue https://github.com/sgenoud/replicad/issues/50 ?

image

const {draw, drawRectangle, drawCircle, drawText} = replicad

const main = (r) => {
       function center(drawing) {
            const boundingBox = drawing.boundingBox;
            drawing = drawing.translate(-boundingBox.center[0], -boundingBox.center[1]);

            return drawing;
        }
        let text = drawText( '0',{fontSize : 8}).translate([0,4]);
        let text2 = drawText( 'experiment',{fontSize : 8}).translate([-17,-4])    
        let plate = drawRectangle(60, 40).cut(text).cut(text2);

        return plate.sketchOnPlane('XY').extrude(0.2);
};
paulftw commented 8 months ago

Cutting 3d shapes is performed by calling OCCT methods, 2d boolean ops are implemented in JS (based on my limited experience with replicad codebase and bug reports). So cutting after extrusion will have different results (often better, because that code is used in many other projects).

bramvandooren commented 6 months ago

Thank you for your response. I've explored the option of cutting after extrusion for this particular scenario, and while it may not be the optimal solution for my project, it serves as a viable workaround for the time being. Your assistance is greatly appreciated.

sgenoud commented 6 months ago

I confirm the whole issue - and I have been working on a better solution for 2D booleans (which can be faster) - but nothing that I would recommend yet unfortunately.