Splitting of Brep

Hi guys,

At the moment I see that Brep.Split method is still supporting only splitting with one brep.
Any development in the direction of splitting with multiple breps?

I guess @stevebaer was looking into this some time ago, or?

Thanks,
Dmitriy

Each BrepFace can be split with multiple curves using BrepFace.Split(IEnumerable<Curve>)
Maybe that can be of use in the meantime.

Hi @menno,

Thanks.

I used it also before.
However the question is how to maintain a multifaceted brep after split - to have similar behavior as Split command in Rhino.
Please see sketch enclosed (rather simple example but gives an idea).

Thanks,
Dmitriy

This seems to be what you are after.

  1. split each brep face with the curves provided
  2. join all pieces into one brep
public override Result RunCommand(RhinoDoc doc, RunMode mode)
{
    ObjRef bRef;
    Result res = RhinoGet.GetOneObject("Select a BREP to split", false, ObjectType.Brep, out bRef);
    if (res != Result.Success)
        return res;

    ObjRef[] crvRefs;
    res = RhinoGet.GetMultipleObjects("Select splitting curves", false, ObjectType.Curve, out crvRefs);
    if (res != Result.Success)
        return res;

    Brep b = bRef.Brep();
    Curve[] splitCurves = crvRefs.Select(r => r.Curve()).ToArray();

    List<Brep> splitted = new List<Brep>();
    foreach (BrepFace bf in b.Faces)
    {
        Brep split = bf.Split(splitCurves, doc.ModelAbsoluteTolerance);
        if (null != split)
            splitted.Add(split);
    }

    Brep [] joined = Brep.JoinBreps(splitted, doc.ModelAbsoluteTolerance);
    foreach (var join in joined)
    {
        doc.Objects.AddBrep(join);
    }

    return Result.Success;
}

Thanks @menno,

However this is not the final target.
As I mentioned - the problem is to identify how to connect relevant parts of the final brep to obtain 3 breps as shown on the target picture - I means one brep with two faces of green, one brep with two faces of blue and one brep with two faces of dark blue. That means there should be step 3 in the pipeline.

Thanks,
Dmitriy

You have to figure out which brep is which. So you have to sort them on X or Y. And only join the 2 you want to join…
If you Sort them on Y then 0 and 1 will be the teal ones, 2 and 3 the purple and 4 and 5 the green one.

Some function like:

  Private Function SortList(ByVal List As List(Of Geometry.brep)) As Geometry.brep()
            Dim Breps As New List(Of Double)
            Dim BrepIn As New List(Of Geometry.brep)
            For Each pt As Geometry.brep In List
                Breps.Add(pt.GetBoundingBox(True).Max.Y)
                BrepIn.Add(pt)
            Next
            Dim LocationYOut As Double() = Breps.ToArray()
            Dim BrepsOut() As Geometry.brep= BrepIn.ToArray()
            Array.Sort(LocationYOut, BrepsOut)
            Return BrepsOut
        End Function

Throw the spllited brep list in this. and it returns the breps sorted on Y. This way you can join 0 and 1 and you know it are the top 2.

Thanks Jordy,

Proposed sorting will work in this simple particular case - however I don’t see how it can work in more complicated 3D case. Sorting will be much more difficult then.
I am looking for the equivalent Split command in Rhino where you can specify split of Brep with multiple breps.

Algorithm I was thinking about can be shortly described as following (starting as a step 3 - first 2 are given by Menno already):

  • try to connect adjacent faces - if they share an edge that is a part of the split curve then deny connection
  • as a result you would have a group of the Breps - each of them would consist of few faces, however adjucent faces would not contain split curves

This should work. What do you think?
However I not sure how to do it in the most efficiently, because you can have hundreds of faces you need to check.

Maybe @stevebaer or @dale can propose a solution similar to one used for Split command in Rhino.

Thanks,
Dmitriy

As I did now I sorted the breps…

Maybe you can split your splitcurves?

Vertical and horizontal ones split.
If you first split all horizontal.
Then loop through the new faces and split them with the vertical ones and join them again?

Or are the breps that should join not always horizontal or vertical?

Sorry, your drawing was not clear enough for me.

Yes, breps can be of very complicated 3D shape - so sorting like this will not work.
Intersection curves also can be represented by closed loops, not intersecting at all.

So, it should be more general approach, I guess
If implementation of Brep split with multiple objects will not happen in the nearest future in RC - at least it would be nice to know which direction to explore to repeat a similar behaviour of Split command. :smile:

As an example enclosed is the shape - multifaceted brep split with number of curves - result of the command Split.
Please note that basic brep can consist of freely connected faces.

Hope, now it is clear what I am looking for.

Dmitriy split_example.3dm (1.1 MB)

@GregArden is there anything you can add to this conversation?

Doing the splitting is not trivial and I’m not sure all the required functions are in the RhinoCommon SDK. The method I would use (and in fact do use in the Rhino Split command) involves digging around in the ON_Brep structure looking at the underlying surfaces of ON_BrepFace’s and looking at ON_BrepLoop’s, ON_Brep_Edges and ON_BrepTrims. If you are comforatble with these concept and how they are related to each other you could probably implement this function from the hints I give below.

Starting with a Brep B, the basic idea is to split each face of B with the collection of splitting curves. This makes a new Brep S with a large number of faces but the underlying surfaces of S are just the underlying surfaces of B. Now a final piece from the split operation S0 is a connected subset of the faces of S. Once you have this subset you can construct S0 with the method S.DuplicateFaces( ). Two faces are connected in the final split piece Si if they share a common edge E in S and they are on different underlying surfaces. That is E is an edge that was already part of the original brep. It is not an edge that was introduced by splitting a face.

I’m not sure if this helps?!
Greg Arden

Thanks @GregArden,

Your explanation is rather clear. I was looking for the similar way but was thinking to compare with splitting curves. But your approach is actually much more cleaner.

I am just curious that so vital function has not been added to RhinoCommon yet. :smile:

Will try to compile a general function for this, but check by McNeel experts will be appreciated.

Thanks,
Dmitriy

Hi,

Has meantime Greg’s method been implemented into an API?

Thank you!
Cristina

Splitting of a Brep with multiple Brep cutters is much easier than I previously indicated.

Create a combined cutter from multiple Breps by using Brep.Append(). This combined Brep should not be added to the document as it will likely cause unexpected problems with many Rhino commands.
However, it can be used as an argument for Brep.Split().

1 Like

Hi @menno,
Is there a way to split a brep with a line?

Hi @Devang_Chauhan,

No there is not. The way you do this is to extrude the line into a surface that completely intersects the Brep. Then you an split the Brep using Brep.Split.

– Dale

Or, use BrepFace.Split for each face in the brep. This function accepts curves. You need to sort out the resulting pieces though…

Thank you @dale and @menno,
I realized that there is no way to use lines to split a brep. I ended up doing something else.Thank you for your suggestions both of you!