Python code - loft

Hi,

I’m trying to create a simple code that creates a loft between 2 selected curves but I keep getting the following error:

"Message: expected float, got Guid

Traceback:
line 2492, in EvaluateCurve, “C:\Users\rneto\AppData\Roaming\McNeel\Rhinoceros\7.0\Plug-ins\IronPython (814d908a-e25c-493d-97e9-ee3861957f49)\settings\lib\rhinoscript\curve.py”

Can someone tell me what’s wrong with my code? For the life of me I just can’t figure it out:

import rhinoscriptsyntax as rs
import scriptcontext as sc
import Rhino
from Rhino.Geometry import *

curve01 = rs.GetObject("Select a closed curve", rs.filter.curve, True, False)
curve02 = rs.GetObject("Select a closed curve", rs.filter.curve, True, False)

closestPoints = rs.CurveClosestObject(curve01, curve02)
start = rs.EvaluateCurve(curve01, closestPoints[0])
end = rs.EvaluateCurve(curve02, closestPoints[1])

loft = Rhino.Geometry.Brep.CreateFromLoft([curve01, curve02], start, end, 3, True, 0)
if loft:
    for brep in loft:
        sc.doc.Objects.AddBrep(brep)
    sc.doc.Views.Redraw()

Thank you

Many things going on here…

First, you are mixing rhinoscriptsyntax and RhinoCommon. To do so you need to know a fair amount about how each one works. Rhinoscriptsyntax works (mostly) with GUID’s (object ID’s) of objects in the document. RhinoCommon works with ‘virtual’ geometry and the objects do not have ID’s because they have not yet been added to the document. This will cause a problem with the following:

loft = Rhino.Geometry.Brep.CreateFromLoft([curve01, curve02], start, end, 3, True, 0)

where curve01 and curve02 are GUID’s and the RhinoCommon method is looking for the curves’ geometry, not their ID’s. That’s where the error message comes from. I would suggest you stay in rhinoscriptsyntax instead and use rs.AddLoftSrf() instead of Rhino.Geometry.Brep.CreateFromLoft()

Also, ‘start’ and ‘end’ in the loft do not refer to points on the curves to be lofted, they refer to points that might be used additionally if the loft should go to a point on either end - like the Rhino Loft command has. This does not appear to be the case, so you can leave that part out (there are some errors in there as well but…).

So you can actually simply run this:

import rhinoscriptsyntax as rs

curve01 = rs.GetObject("Select a closed curve", rs.filter.curve, True, False)
curve02 = rs.GetObject("Select a closed curve", rs.filter.curve, True, False)
if (curve01 and curve02):
    loft_id=rs.AddLoftSrf([curve01,curve02])

However, that does not address the issues of curve direction and seam. So it’s most likely to result in a twisted mess unless you have already created the closed curves in the same direction and matching seams. Matching the direction and seams is actually a bit complicated. Will post some code in a few minutes.

Voilà…

import rhinoscriptsyntax as rs

curve01=rs.GetObject("Select a closed curve", rs.filter.curve, True, False)
curve02=rs.GetObject("Select a closed curve", rs.filter.curve, True, False)
if curve01 and curve02:
    if rs.IsCurveClosed(curve01) and rs.IsCurveClosed(curve02):
        
        #check curve directions (CW/CCW)
        if not rs.CurveDirectionsMatch(curve01,curve02):
            #flip (reverse) second curve if directions don't match
            rs.ReverseCurve(curve02)
            
        #match seam on curve02 to curve01
        start01=rs.CurveStartPoint(curve01)
        #get the *parameter* on curve02 of the closest point to start01
        param=rs.CurveClosestPoint(curve02,start01)
        #change the seam of curve02
        rs.CurveSeam(curve02,param)
        
        #create and add the loft to the document
        loft_id=rs.AddLoftSrf([curve01,curve02])

There is lots more that can be done, for example limiting the choice while picking to only closed curves, etc. but this is just to get you started.

2 Likes

Thank you so much! The code I shared was just my last attempt to make a loft work in code, but as you said I always ended up with a twisted mess. So basically you solved 2 problems in just one comment. Legend!