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;
}