Temporary Split with CutPlane

Hello All,

I m trying to create an enchanced split command by using temporary cutplanes

import rhinoscriptsyntax as rs

objs = rs.GetObjects("Select objects for cut plane")
if objs:
    point0 = rs.GetPoint("Start of cut plane")
    if point0:
        point1 = rs.GetPoint("End of cut plane", point0)
        if point1: cutplane = rs.AddCutPlane( objs, point0, point1 )


rs.Command("_Split")

rs.DeleteObjects(cutplane)

Can you please tell me how i can pass the obj and cutplane arguments to the split command so that i dont have to reselect them?

Try this on for size:

import rhinoscriptsyntax as rs

objs = rs.GetObjects("Select objects for cut plane",preselect=True,select=True)
if objs:
    point0 = rs.GetPoint("Start of cut plane")
    if point0:
        point1 = rs.GetPoint("End of cut plane", point0)
        if point1: cutplane = rs.AddCutPlane( objs, point0, point1 )

rs.EnableRedraw(False)
rs.Command("_Split _SelID {} _Enter".format(cutplane))
rs.DeleteObjects(cutplane)

The trick is to have the objects to be split already selected when the rs.Command("Split...") is called. If there is only one cut plane then you can use SelID to select it as the second prompt in Split.

If there are several cut planes, you can group them before calling the Split command, get the group name, and then use SelGroup GroupName instead of SelID. You can delete the group name afterward.

1 Like

I just managed to solve by giving names to the cutplanes.
Also added a while loop to add multiple sections.

import rhinoscriptsyntax as rs

objs = rs.GetObjects("Select objects for cut plane")
tmp_cutplane = []
if objs:
    while True:
        point0 = rs.GetPoint("Start of cut plane")
        if point0:
            point1 = rs.GetPoint("End of cut plane", point0)
            if point1: 
                cutplane = rs.AddCutPlane( objs, point0, point1 )
                tmp_cutplane.append(cutplane)
                rs.ObjectName( cutplane, "tmp_cutplane" )
                del(point0)
                del(point1)
        else:
            break

rs.SelectObjects(objs)
rs.Command('_Split _-SelName tmp_cutplane _Enter')
rs.DeleteObjects(tmp_cutplane)

Lovely Thanks!!!

I script that with SelID by adding a for a loop at the end.
Any idea which method performs faster?

import rhinoscriptsyntax as rs
cutplanes=[]
objs = rs.GetObjects("Select objects for cut plane",preselect=True,select=True)
if objs:
    while True:
        point0 = rs.GetPoint("Start of cut plane")
        if point0:
            point1 = rs.GetPoint("End of cut plane", point0)
            if point1: 
                cutplanes.append(rs.AddCutPlane( objs, point0, point1 ))
                del(point0)
                del(point1)
        else:
            break
            
rs.EnableRedraw(False)
for cutplane in cutplanes:
    rs.Command("_Split _SelID {} _Enter".format(cutplane))
    rs.DeleteObjects(cutplane)

The above might not work reliably because once you split the original objects the first time, they have new IDs. Every time you re-split them they have new IDs again. If they always remain selected, I guess it’s OK though, but to me it feels a bit shaky.

The selname or selgroup methods should work fine for selecting multiple cutting planes at once. As far as speed goes, it might be faster to do all this in RhinoCommon, but I haven’t tested that.

Does anyone understand why this script doesn’t always work when selecting just one object?

import rhinoscriptsyntax as rs
group_name = "TempCutPlane"
cutplanes = []
objs = rs.GetObjects("Select objects for cut plane",preselect=True,select=True)
if objs:
    while True:
        point0 = rs.GetPoint("Start of cut plane")
        if point0:
            point1 = rs.GetPoint("End of cut plane", point0)
            if point1: 
                cutplane = rs.AddCutPlane( objs, point0, point1 )
                cutplanes.append(cutplane)
                rs.ObjectName(cutplane, group_name)
                del(point0)
                del(point1)
        else:
            break

rs.EnableRedraw(False)
rs.Command("_Split _-SelName {} _Enter".format(group_name))
rs.DeleteObjects(cutplanes)

Lets say that i want to split the horizontal srf


If the points are not belonging on the surface (i.e if i select points using the transverse srf) the split fails.

If the points are taken on the horizontal srf the split is successful.

I have noticed that this doesn’t happen when 2 or more surfaces are selected

Not sure, but like the native Rhino command, rs.AddCutPlane takes the CPlane of the active viewport as a reference, so maybe the wrong viewport is active at the time the script is launched (depending on where/how you pick your points) ?

The Help is a bit confusing though, looking at it again, I can’t figure out if it is using the active CPlane or World…

image

Edit -

OK, I did a little investigation and it looks like the rs.AddCutPlane() method may be unreliable if the objects to be cut are all coplanar and on the same plane. It uses the bounding box of the objects to determine the depth of the plane and since the box is flat, in Z it may be getting confused - it adds a plane but the plane does not cut through the selected objects (check this by not deleting the cut planes at the end of the script). I don’t have the time to investigate this further today though.

One other thing briefly, you do not need to delete the points 0 and 1 as they are not point objects in the document anyway.

Edit 2:

I have tracked down a bug in the rs.AddCutPlane() method which looks like it is causing your problem.

I put together a different way of doing this to avoid the bug with creating cutplanes. It does rely on drilling down into RhinoCommon though as well as dealing with an esoteric python/RhinoCommon problem with certain overloaded functions (notably Brep.Split).

I created a custom method SplitBrepWLines which takes a single surface or polysurface plus a set of lines (in the form of two points) and a normal direction vector. It turns the lines into infinite planes using the normal vector (in this case the active view’s CPlane normal direction), intersects the surface/polysurface with the planes to make curves and then splits the surface with the curves.

I then made a wrapper function that deals with the user interface, allows the user to pick multiple surfaces/polysurfaces and multiple 2-point lines, then it calls the above function once for each surface/polysurface and reports the results.

SplitBrepsWLines.py (2.3 KB)

1 Like