Quantcast
Channel: Rhino Developer - McNeel Forum
Viewing all articles
Browse latest Browse all 8577

Closing a trimmed brep (similar to boolean split command)

$
0
0

@lungenstrudel wrote:

Hi, i wrote a method that trims a simple brep (grey) by another brep (cyan) that is open and contains several faces.

Similar to the Boolean Split command, i want to achieve a CLOSED brep from my trim:

As a first step, i am trimming the grey brep with the cyan one. This gives me an OPEN brep, from which i take the closed outer loop.

I now split each of the cyan (cutter) brep’s faces with this closed outer loop.

Here’s the result for one of the cutter’s faces. I should get two faces, however, i get three.

Anyway, i finally identify all split-faces that are inside the closed outer loop’s bounding box, add them to a list and re-append them to my trimmed brep.

However, i am unable to achieve a clean result.

I’ve tried compacting, repairing, joining naked edges, shrinking faces, etc. etc.

Here’s my test-geometry:

closingTrimmedBrep.3dm (294.5 KB)

And my code:

 protected override Result RunCommand(RhinoDoc doc, RunMode mode)
    {
        double myTolerance = 0.1;

        #region pick brep
        var getter = new GetObject();
        getter.SetCommandPrompt("Pick extrusion brep");
        getter.GeometryFilter = Rhino.DocObjects.ObjectType.Brep;
        getter.DisablePreSelect();
        getter.SubObjectSelect = false;
        getter.Get();

        if (getter.CommandResult() != Rhino.Commands.Result.Success)
            return getter.CommandResult();

        if (null == getter.Object(0).Brep())
            return Rhino.Commands.Result.Failure;
        #endregion

        Brep untrimmedBrep = getter.Object(0).Brep();

        #region pick another brep
        var getter2 = new GetObject();
        getter2.SetCommandPrompt("Pick cutter brep");
        getter2.GeometryFilter = Rhino.DocObjects.ObjectType.Brep;
        getter2.DisablePreSelect();
        getter2.SubObjectSelect = false;
        getter2.Get();

        if (getter2.CommandResult() != Rhino.Commands.Result.Success)
            return getter.CommandResult();

        if (null == getter2.Object(0).Brep())
            return Rhino.Commands.Result.Failure;
        #endregion

        Brep cutterBrep = getter2.Object(0).Brep();

       // trim untrimmed brep with cutter
        var trimResults = untrimmedBrep.Trim(cutterBrep, myTolerance);

        if (trimResults.Length != 1)
            return Rhino.Commands.Result.Failure;

        var trimmedOpenBrep = trimResults[0];

        //close trimmed brep
        var closedBrep = CloseTrimmedProfile(trimmedOpenBrep, cutterBrep, true, myTolerance, doc);

        doc.Objects.AddBrep(closedBrep);

        doc.Views.Redraw();

        return Result.Success;
    }

    private Brep CloseTrimmedProfile(Brep trimmedOpenBrep, Brep cuttingBrep, bool accurateButSlowerBoundingBoxes, double tolerance, RhinoDoc doc)
    {
        //extract naked edge curve from brep and join them

        var nakedEdgeCurveSegments = trimmedOpenBrep.DuplicateNakedEdgeCurves(true, false);

        var joinResults = Curve.JoinCurves(nakedEdgeCurveSegments);

        if (joinResults.Length != 1)
            throw new Exception("Trimmed Brep yields more than one closed naked edge curve.");

        var nakedEdgeCurveClosed = joinResults[0];

        if (!nakedEdgeCurveClosed.IsClosed)
            throw new Exception("Trimmed Brep yields invalid edge results. Curve not closed.");

        //bounding box of entire naked edge curve

        BoundingBox masterBox = nakedEdgeCurveClosed.GetBoundingBox(accurateButSlowerBoundingBoxes);
        masterBox.Inflate(tolerance * 10); //ENLARGE BOUNDING BOX SLIGHTLY

        List<Brep> allContainedSingleBreps = new List<Brep>();

        foreach (var f in cuttingBrep.Faces)
        {
            //take single surface (face/brep) of cuttingBrep

            Brep singleFace = f.DuplicateFace(false);
            singleFace.Compact();

            //split this surface with full naked edge curve

            Brep splitResultBrep = singleFace.Faces[0].Split(nakedEdgeCurveClosed.DuplicateSegments(), tolerance);

            splitResultBrep.Compact();

            //make list of surfaces (face/brep) resulting from split operation

            List<Brep> splitResultSingleBreps = new List<Brep>();

            foreach (var face in splitResultBrep.Faces)
            {
                Brep singleFc = face.DuplicateFace(false);
                singleFc.Compact();
                singleFc.Faces[0].ShrinkFace(BrepFace.ShrinkDisableSide.ShrinkAllSides);
                splitResultSingleBreps.Add(singleFc);
            }

            //see if face's bounding box is contained in master bbox. if yes - add to list

            foreach (var brep in splitResultSingleBreps)
            {
                BoundingBox currBrepBBox = brep.Faces[0].OuterLoop.To3dCurve().GetBoundingBox(accurateButSlowerBoundingBoxes);

                bool strictOnCoincidentSurfaces = false;
                bool isContained = masterBox.Contains(currBrepBBox, strictOnCoincidentSurfaces);

                if (isContained)
                    allContainedSingleBreps.Add(brep);
            }
        }

        //join faces back together
        foreach (var item in allContainedSingleBreps)
            trimmedOpenBrep.Join(item, tolerance, true);

        return trimmedOpenBrep;
    }

Posts: 5

Participants: 4

Read full topic


Viewing all articles
Browse latest Browse all 8577

Trending Articles