[BUG] -_Rebuild not macro'able


I can’t get -_Rebuild to work in a script where I use multiple closed Crv’s
A single curve works though.

Is this a bug?


Hi Jordy,

If you can do it “by hand” in Rhino it’s also possible to script it with rs.Command()
Generally if you try to select several objects in the rs.Command() , you will have to loop through “-_selid”

If you post your code it might be possible to find your bug.


Martin, maybe I am misunderstanding your words, but … do you know a way to script commands like FilletSrf and Trim ?

well it is not like it bugs in a script.

!_selnone -_selcrv -_Rebuild p=100 _enter

and it wont rebuild.

Also If I try with the curves by “hand” with the -_rebuild nothing happens :wink:

here is an example file:
Crvs.3dm (245.2 KB)

Copy pase the “script” in your command bar and it should run… nothing…

This is some old code of mine with a function to split Breps along a plane. It was from the Rhino Python Beta Phase.

However the idea is to write everything you want to execute into one string and the execute it.

def TrimObjectsAlongPlane(lstObjectIDs,CuttingPlane,blnDeleteAbovePlane):
#Split Objects
#Use Rhino Command Until Split Brep is Implemented

#Get Boundingbox
BBox = rs.BoundingBox(lstObjectIDs)    
#Analyse Boundingbox
tupAnalysedBBox = AnalyseBox(BBox)
#Create copy of the Plane
CuttingPlaneCopy = copy.copy(CuttingPlane)
#Move Plane to Center of the Boundingbox
CuttingPlaneCopy = rs.MovePlane(CuttingPlaneCopy,rs.PlaneClosestPoint(CuttingPlaneCopy,tupAnalysedBBox[3]))
#Create The Cutting Srf from the Plane
BBoxDimensionMax = tupAnalysedBBox[4] * 1.5
CuttingSrf = GetSurfaceFromPlane(CuttingPlaneCopy, BBoxDimensionMax, BBoxDimensionMax)
#Start Splitting
strCommand = "_split "
for Object in lstObjectIDs:
    strCommand = strCommand + " _selID " + Object.ToString()
strCommand = strCommand + " _Enter "    
strCommand = strCommand + "_selID " + CuttingSrf.ToString() + " _Enter "
#Get the Created Objcects
lstSplitSrfs = rs.LastCreatedObjects()
#Check if Objects were split
if (lstSplitSrfs == None):
#Delete the Cutting Srfs
#Create List Objects
lstReturnObjs = []
#Filter the Objects
for SplitSrf in lstSplitSrfs:
    #Get the Boundingbox
    SplitSrfBBox = rs.BoundingBox(SplitSrf)         
    testPt = AnalyseBox (SplitSrfBBox)[3]
    #Get Distance to Plane
    PlaneDistance = rs.DistanceToPlane(CuttingPlane, testPt)
    if (blnDeleteAbovePlane):
        if (PlaneDistance > 0):
        if (PlaneDistance < 0):
return lstReturnObjs

even though I probably wouldn’t use Object.ToString() but str(Object) … One is the .Net way, the other the Python way.

The important part is:

strCommand = "_split "

for Object in lstObjectIDs:
strCommand = strCommand + " _selID " + Object.ToString()

strCommand = strCommand + " _Enter "
strCommand = strCommand + "_selID " + CuttingSrf.ToString() + " _Enter "



this actually works for me… (i added another _selnone at the end but i don’t think that’s anything to do with it… i also changed p to 10 just so the example is obvious that it’s working)



it also works if i just copy/paste it into my command search (on mac)

hmm… ok… it doesn’t work if i use your original file with p=100…
if i rebuild the curves with 10 points, then run your macro again with p=100, it does work then ??

Yeah FilletSrf should work - Don’t have time to write it down right now - but copying a simpler example with the -> _sweep2 command, I already have

def Sweep2(rail1, rail2, profile, blnCap=True):

#Initialize command
strCommand = ""
strCommand += "-_Sweep2"
strCommand += " _selID " + rail1.ToString()    
strCommand += " _selID " + rail2.ToString()
strCommand += " _selID " + profile.ToString()
strCommand += " _Enter"
strCommand += " _Enter"
strCommand += " _Enter"
rs.Command(strCommand, False)
lstSurface = rs.LastCreatedObjects()
surface = lstSurface[0]
if blnCap:
return surface


P.S.: I’m a little confused here - I was talking about script - but what you posted was actually a makro.

@MartinIC Sorry for the confusion. I meant macro ^^

@jeff_hammond isnt working here either…
!selnone -selcrv -_Rebuild p=10 _enter

this are only 11 - 12 curves. In the real thing I use 160 - 170 in 1 go.
so I think there is something wrong in -_rebuild for curves

maybe do it with python?

i tried this on 800 of your curves and it does the trick

import rhinoscriptsyntax as rs

crvs= rs.ObjectsByType(4)
rb= [rs.RebuildCurve(crv, degree=3, point_count=100) for crv in crvs]

oke I had that too work in rhinoScript aswell but how do I get all directions of the curves in the same direction? Rebuild will do this.

but it still should also work with just -_rebuild ^^

there’s a rs.CurveDirectionsMatch but i’m not sure of the best way to get it to work on hundreds of curves at once.
maybe @emilio knows?

agree- seems like it should work with the macro

Oke just checked my thing with

Option Explicit
Call Main()
Sub Main()
    Dim objArr, obj
    rhino.command "_selcrv", True
    objArr = rhino.getobjects("Crv's", 4, False, True, False)
    For Each obj In objArr
        Rhino.RebuildCurve obj, 3, 100
    rhino.command "_selcrv", True
    rhino.command "-_loft _enter e 100 _enter _delete _sellast -_matchproperties -_selname Leisten* _enter _invert _delete", True
End Sub

and somehow… its working. The directions do not matter for the lofting part. It gets right when I rebuild it so directions wont change with rebuild.

its a good workaround :wink:
but takes a while till it has rebuild 200 curves though :wink:

are you sure it’s the rebuilding which is slowing it down? that python thing i posted earlier works instantly (or less than 1 second ) on 1000 curves.

Oke I know why it was so slow… It redrew for every curve… now its under a second too!

Option Explicit
Call Main()
Sub Main()
    rhino.enableredraw False
    Dim objArr, obj, tot, i
    rhino.command "_selcrv", True
    objArr = rhino.getobjects("Crv's", 4, False, True, False)
    tot = UBound(objArr) + 1
    For i=0 To UBound(objArr)
        Rhino.prompt CStr(i + 1) & " / " & CStr(tot)
        Rhino.RebuildCurve objArr(i), 3, 100
   rhino.enableredraw True
End Sub

Too see the progress in the rebuild crv´s

mac rhino doesnt speak that language :wink:
(I’m on a Mac btw)

but I tested earlier with 100 points. not 10

I am pretty sure it has to do with the total number of points in the Rebuild - this is a bug, I would say- the macro works if the total number of points is below some threshold and not if it is above. This behavior started, as I recall, when previewing and max deviation were added and it slowed things down too much if the point count got too large . I know we raised the threshold but it should not matter at all in a macro, especially with Preview off. I’ll dig more but I think that is what’s happening here.


Oke @pascal thanks for looking into this.
It shouldnt matter if Rebuild is used in a macro or with a form. The form works great a macro’s actions arn’t really that different right? Only the settings are given an other way.


Sorry for not being clear.
I was talking about Rhino commands executed in a script by rs.Command()


I’m a a little late … sorry Jeff :wink:

Do you mean something like this ?

curves = rs.GetObjects( 'Curves ?' )
for ix in range( len( curves ) - 1 ):
    if not rs.CurveDirectionsMatch( curves[ ix ], curves[ ix + 1 ] ):
        rs.ReverseCurve( curves[ ix + 1 ] )

… not sure I understand the problem correctly, I have not read the whole thread …

in the end, i don’t think there was a problem but still, this is helpful for future reference.

my main confusion was if it would be better to take one curve (say curve[0]) then compare to all the rest or to do what you’ve shown-- 1 to 2… then 2 to 3 etc.

mainly i don’t know exactly what CurveDirectionsMatch is doing so i was thinking it might be more likely to flip itself somewhere along the way when doing the second type of comparison and you’d end up with half the curves going one way and the other half going the other way.