You only need to consider planes if you are drawing lines or other curves i.e. creating CurveElements not Curves.
Here is a simple example of sweeping a polyline. The tricky part of sweeping is getting the right plane orientation for the end of the curve. If the start curve is a line you can do the below (first example) for others you can do similar with Curve.ComputeDerivatives (2nd example) important to note that for certain curves the vectors from this function will not be normalised and sometimes not even orthogonal. However you can usually use them to create an orthogonal and normalised system. Both these cases are simple extrusions but there is scope in the API function to add different profiles along the sweep and at different parameter positions along each curve.
Private Function Obj_230129b(ByVal commandData As Autodesk.Revit.UI.ExternalCommandData,
ByRef message As String, ByVal elements As Autodesk.Revit.DB.ElementSet) As Result
Dim UIApp As UIApplication = commandData.Application
Dim UIDoc As UIDocument = commandData.Application.ActiveUIDocument
If UIDoc Is Nothing Then Return Result.Cancelled Else
Dim IntDoc As Document = UIDoc.Document
Dim Pt = Function(x As Double, y As Double, z As Double)
Return New XYZ(x, y, z)
End Function
Dim Points As XYZ() = New XYZ(10) {Pt(0, 0, 0), Pt(0.2, 0, 0.2), Pt(0.4, 0, 0.4), Pt(0.6, 0, 0.8),
Pt(0.8, 0, 0.8), Pt(1, 0, 1), Pt(1.2, 0, 0.8), Pt(1.4, 0, 0.8),
Pt(1.6, 0, 0.4), Pt(1.8, 0, 0.2), Pt(2, 0, 0)}
'check vertical case
'Points = New XYZ(1) {Pt(0, 0, 0), Pt(0, 0, 2)}
Dim CLPath As New CurveLoop
For i = 0 To Points.Length - 2
CLPath.Append(Line.CreateBound(Points(i), Points(i + 1)))
Next
Dim StartSeg As Line = CLPath(0)
Dim Dir As XYZ = StartSeg.Direction.Normalize 'should be normalised anyway
Dim V0 As XYZ = XYZ.BasisZ
'Check if direction of line is more towards 0,0,1 or 1,0,0
If Math.Abs(Dir.DotProduct(XYZ.BasisZ)) > Math.Abs(Dir.DotProduct(XYZ.BasisX)) Then
V0 = XYZ.BasisX
Else
V0 = XYZ.BasisZ
End If
Dim By As XYZ = Dir.CrossProduct(V0).Normalize
Dim Bx As XYZ = Dir.CrossProduct(By).Normalize
Dim A0 As Arc = Arc.Create(Points(0), 0.01, 0, Math.PI, Bx, By)
Dim A1 As Arc = Arc.Create(Points(0), 0.01, Math.PI, 2 * Math.PI, Bx, By)
Dim EP As Double = StartSeg.GetEndParameter(0)
Dim Profile As New CurveLoop
Profile.Append(A0)
Profile.Append(A1)
Using tx As New Transaction(IntDoc, "Curve")
If tx.Start = TransactionStatus.Started Then
Dim S As Solid = GeometryCreationUtilities.CreateSweptGeometry(CLPath, 0, EP, {Profile}.ToList)
Dim DS As DirectShape = DirectShape.CreateElement(IntDoc,
New ElementId(BuiltInCategory.OST_GenericModel))
DS.SetShape(New GeometryObject(0) {S}.ToList)
tx.Commit()
End If
End Using
Return Result.Succeeded
End Function
If you want a smooth fit then you'll have to use a spline, the most straightforward one to use is the HermiteSpline. The more points you have the less the abrupt changes in the curve. This is the advantage of NurbSpline, less control points required but other complexities to consider.
Similar example with HermiteSpline
Private Function Obj_230129b(ByVal commandData As Autodesk.Revit.UI.ExternalCommandData,
ByRef message As String, ByVal elements As Autodesk.Revit.DB.ElementSet) As Result
Dim UIApp As UIApplication = commandData.Application
Dim UIDoc As UIDocument = commandData.Application.ActiveUIDocument
If UIDoc Is Nothing Then Return Result.Cancelled Else
Dim IntDoc As Document = UIDoc.Document
Dim Pt = Function(x As Double, y As Double, z As Double)
Return New XYZ(x, y, z)
End Function
Dim Points As XYZ() = New XYZ(10) {Pt(0, 0, 0), Pt(0.2, 0, 0.2), Pt(0.4, 0, 0.4), Pt(0.6, 0, 0.8),
Pt(0.8, 0, 0.8), Pt(1, 0, 1), Pt(1.2, 0, 0.8), Pt(1.4, 0, 0.8),
Pt(1.6, 0, 0.4), Pt(1.8, 0, 0.2), Pt(2, 0, 0)}
Dim HC As HermiteSpline = HermiteSpline.Create(Points.ToList, False)
Dim T As Transform = HC.ComputeDerivatives(0, False)
Dim Bx As XYZ = T.BasisX.Normalize 'tangent with direction of curve
Dim By As XYZ = T.BasisY.Normalize
Dim Bz As XYZ = Bx.CrossProduct(By).Normalize
By = Bz.CrossProduct(Bx).Normalize
Dim A0 As Arc = Arc.Create(Points(0), 0.01, 0, Math.PI, Bz, By)
Dim A1 As Arc = Arc.Create(Points(0), 0.01, Math.PI, 2 * Math.PI, Bz, By)
Dim EP As Double = HC.GetEndParameter(0)
Dim Profile As New CurveLoop
Profile.Append(A0)
Profile.Append(A1)
Dim CLPath As New CurveLoop
CLPath.Append(HC)
Using tx As New Transaction(IntDoc, "Curve")
If tx.Start = TransactionStatus.Started Then
Dim S As Solid = GeometryCreationUtilities.CreateSweptGeometry(CLPath, 0, EP, {Profile}.ToList)
Dim DS As DirectShape = DirectShape.CreateElement(IntDoc,
New ElementId(BuiltInCategory.OST_GenericModel))
DS.SetShape(New GeometryObject(0) {S}.ToList)
tx.Commit()
End If
End Using
Return Result.Succeeded
End Function