Loft multiple curves

Hi I am trying to loft multiple lines once.for example, I want to loft each sets of circles like picture below.


I have a script that is similar to what I want but this one can only select 4 curves. I want to select more than that.how can I change this??

Option Explicit
Rhino.ClearCommandHistory()

    Dim loft1, loft2, loft3, loft4
    Dim srf1, srf2

            
    loft1=Rhino.Getcurveobject("select first curve")

loft2=Rhino.Getcurveobject(“select second curve”)

loft3=Rhino.Getcurveobject(“select third curve”)

loft4=Rhino.Getcurveobject(“select fourth curve”)

Rhino.AddLoftSrf (Array(loft1(0),loft2(0)))
srf1=Rhino.FirstObject()

Rhino.AddLoftSrf (Array(loft3(0),loft4(0)))
srf2=Rhino.FirstObject()

Rhino.SelectObjects (Array (srf1,srf2))

Rhino.Command("_Boolean2Objects enter ")

The problem is that Loft just takes a bunch of curves and tries to run a surface through them, so if you select a set of curves “en masse” (via window or something similar) it won’t know which sets of two to loft together.

There’s no good workaround for this except picking all the curves manually in pairs - one, two, one two, one two… If the pick order is correct, this can be made to work, but if you make a mistake, it will all go wrong.

Or, if you know that the pair of curves will always have some distinguishing criteria (same color, closest together, etc.) then something could be set up to handle that particular situation automatically.

–Mitch

Below is a quick Python script to loft picked pairs of curves together. You can select each pair of curves by individual mouse click or together with a window. As soon as exactly two curves are picked, it will make the surface between. You can continue to pick curve pairs as long as you want, when you hit Enter the sequence will terminate.

–Mitch

import rhinoscriptsyntax as rs

def LoftCurvePairs():
    msg="Pick a pair of curves to loft, or press Enter to exit"
    while True:
        crvs=rs.GetObjects(msg,4,preselect=True,minimum_count=2,maximum_count=2)
        if not crvs: break
        rs.AddLoftSrf(crvs,loft_type=0,simplify_method=0)
LoftCurvePairs()

Hi Mitch

that is brilliant!! that’s what I wanted. Rhino5 should have this tool.
by the way would it be possible to add the history?? also, can you add the option to adjust the seam like normal loft processing??

Well, that takes out some of the automaticity, and it turned out to be a bit more difficult to implement than I thought, but below is a script hack using rs.Command that seems to work OK…

import rhinoscriptsyntax as rs

def LoftCurvePairsWSeamHistory():
    msg="Pick a pair of curves to loft, or press Enter to exit"
    commOpts=" _Type=_Normal _Simplify=_None _Closed=_No _Enter"
    while True:
        rs.UnselectAllObjects()
        crvs=rs.GetObjects(msg,4,preselect=True,minimum_count=2,maximum_count=2)
        if not crvs: break
        if rs.IsCurveClosed(crvs[0]) and rs.IsCurveClosed(crvs[1]):
            rs.SelectObjects(crvs)
            rs.Command("_CrvSeam")
            rs.Command("-Loft _Enter"+commOpts,False)
        elif not rs.IsCurveClosed(crvs[0]) and not rs.IsCurveClosed(crvs[1]):
            rs.SelectObjects(crvs)
            rs.Command("-Loft"+commOpts,False)
        else:
            print "Cannot loft an open curve with a closed curve"
            continue
LoftCurvePairsWSeamHistory()
1 Like

thank you Mitch. I also want to have the history option on and off but the history is not working.I put rs.Command("_history _record=yes") but it is not working. for example,

import rhinoscriptsyntax as rs

def LoftCurvePairsWSeamHistory():
    msg="Pick a pair of curves to loft, or press Enter to exit"
    commOpts=" _Type=_Normal _Simplify=_None _Closed=_No _Enter"
    while True:
        rs.UnselectAllObjects()
        crvs=rs.GetObjects(msg,4,preselect=True,minimum_count=2,maximum_count=2)
        if not crvs: break
        if rs.IsCurveClosed(crvs[0]) and rs.IsCurveClosed(crvs[1]):
            rs.SelectObjects(crvs)
            rs.Command("_history _record=yes")
            rs.Command("_CrvSeam")
            rs.Command("-Loft _Enter"+commOpts,False)
            rs.Command("_history _record=no")
        elif not rs.IsCurveClosed(crvs[0]) and not rs.IsCurveClosed(crvs[1]):
            rs.SelectObjects(crvs)
            rs.Command("-Loft"+commOpts,False)
        else:
            print "Cannot loft an open curve with a closed curve"
            continue
LoftCurvePairsWSeamHistory()

also you have “False” after commOpts.can I ask what is False doing for??

OK, so you want to turn on History just for these objects when it’s not on to begin with? That is possible. Edit: That may be a bit difficult, the rhinoscriptsyntax method for turning on or off history is not yet implemented in Python. It mat be possible to kludge something with rs.Command, or re-write the script in vb Rhinoscript…

The “False” turns off of the command line echoing of the command options, which keeps your history cleaner. It doesn’t change the operation of the script itself.

–Mitch

I guess I would just click the history button manually.thanks for your help.you are a legend!

I said difficult, but not impossible…

First: as Rhino.EnableHistoryRecording() is implemented in vb Rhinoscript, below is a vb Rhinoscript that will turn History on (if it’s not already on) and then return it to its previous state when done. There is a small bug currently in Rhino.EnableHistoryRecording() but I was able to work around it.

Then there is a REAL kludge Python version which works around the non-implementation of rs.EnableHistoryRecording() by first executing the command History and then parsing the command line result. (I told you it was a kludge, just want to see if I could make it work). This will only work on English-speaking Rhinos, however… FWIW, just for fun…

–Mitch

Option Explicit
'Script written by Mitch Heynick
'Version January 14, 2014

Call LoftCurvePairsWSeamHistory2()
Sub LoftCurvePairsWSeamHistory2()	
	Dim msg,commOpts,crvs,prevHState
	msg = "Pick a pair of curves to loft, or press Enter to exit"
	commOpts = " _Type=_Normal _Simplify=_None _Closed=_No _Enter"
	
	'check history state, turn on
	prevHState = Rhino.EnableHistoryRecording(True)
	'the following line is a bug workaround
	If IsEmpty(prevHState) Then prevHState = False
	'turn on history
	'Call Rhino.EnableHistoryRecording(True)
	
	Do
		Call Rhino.UnselectAllObjects()
		crvs = Rhino.GetObjects(msg, 4,, True,,, 2, 2)
		If Not IsArray(crvs) Then Exit Do
		
		If Rhino.IsCurveClosed(crvs(0)) And Rhino.IsCurveClosed(crvs(1)) Then
			Call Rhino.SelectObjects(crvs)
			Call Rhino.Command("_CrvSeam")
			Call Rhino.Command("-Loft _Enter" + commOpts, False)
		ElseIf Not Rhino.IsCurveClosed(crvs(0)) And Not Rhino.IsCurveClosed(crvs(1)) Then
			Call Rhino.SelectObjects(crvs)
			Call Rhino.Command("-Loft" + commOpts, False)
		Else
			Call Rhino.Print("Cannot loft an open curve with a closed curve")
		End If		
	Loop
	
	'return history to previous state
	Call Rhino.EnableHistoryRecording(prevHState)
End Sub

Python version

import rhinoscriptsyntax as rs
import Rhino

def CheckHistoryState():
    rs.Command("_History _Enter")
    #parse the command line result
    ch=Rhino.RhinoApp.CommandHistoryWindowText
    lastline=ch.split(chr(10))[-2]
    state=lastline.split(" ")[4]
    ans=state.split("=")[1]
    if ans=="Yes": return True

def LoftCurvePairsWSeamHistory2():
    msg="Pick a pair of curves to loft, or press Enter to exit"
    commOpts=" _Type=_Normal _Simplify=_None _Closed=_No _Enter"
    setHistFlag=True
    histState=CheckHistoryState()
    if not histState: setHistFlag=False
    while True:
        rs.UnselectAllObjects()
        crvs=rs.GetObjects(msg,4,preselect=True,minimum_count=2,maximum_count=2)
        if not crvs: break        
        #turn on history
        if not setHistFlag:
            rs.Command("_History _Record=_Yes _Enter",False)
        if rs.IsCurveClosed(crvs[0]) and rs.IsCurveClosed(crvs[1]):
            rs.SelectObjects(crvs)
            rs.Command("_CrvSeam")
            rs.Command("-Loft _Enter"+commOpts,False)
        elif not rs.IsCurveClosed(crvs[0]) and not rs.IsCurveClosed(crvs[1]):
            rs.SelectObjects(crvs)
            rs.Command("-Loft"+commOpts,False)
        else:
            print "Cannot loft an open curve with a closed curve"
            continue
    if not setHistFlag:
            #turn history back off
            rs.Command("_History _Record=_No _Enter",False)
        
LoftCurvePairsWSeamHistory2()
2 Likes

You are genious!! I wish I could write my own script. Rhino should have something like this in future.many thanks for your effort. :smiley: