<<< Return to Nathan's Revit API Notebook
Introduction
This section describes a technique for creating parametric forms and surfaces using the API. The example will make use of form creation methods.
Parametric surfaces can be graphed in 3 dimensions by plotting points using parametric equations with x, y, and z values.
Previous API examples have already being dealing with parametric surfaces, although this concept was not explicitly explained. If you refer back to this loft wave example, you will see variables being declared for x, y, and z. The parameters for the variables are being driven by the loop variables i and j.
Most parametric forms on this page will follow a similar set-up.
Mobius Surface
To explain how to set up a parametric surface script, I will use a famous example: The Mobius band!
The Mobius surface can be parametrically described as follows….
Where -Pi < u < Pi and -1 < v < 1
- x = (R + v * Cos(T * u)) * Cos(u)
- y = (R + v * Cos(T * u)) * Sin(u)
- z = v * Sin(T * U)
Points using x, y , and z will be plotted based on the equation parameters for u, v, R, and T. A surface can then be interpolated between the points.
Parameters
In order to describe the Mobius surface, a few variables need to be established which will control the surface parameters.
#declare surface parameters R = 4.0 T = 0.5 #U and V division variables uDiv = 50 vDiv = 50 #Range variables u0 = math.pi * -1 u1 = math.pi v0 = -1.0 v1 = 1.0 #Step increments uStep = abs(u1 - u0) / uDiv vStep = abs(v1 - v0) / vDiv #Starting values for u and v u = math.pi * -1 v = -1.0 #Parametric equations for mobius plot x = (R + v * math.cos(T * u)) * math.cos(u) y = (R + v * math.cos(T * u)) * math.sin(u) z = v * math.sin(T * u)
Plotting Points with Nested Loops
In order to plot the Mobius, we must increment variables u and v using a nested loop. Reference points can be used to visualize how the system is working.
#Starting value for u u = math.pi * -1 while (u <= (u1+uStep)): #Starting value for v v = -1 while (v <= v1): #Parametric equations for Mobius plot x = (R + v * math.cos(T * u)) * math.cos(u) y = (R + v * math.cos(T * u)) * math.sin(u) z = v * math.sin(T * u) #draw reference points (note that I multiplying x,y, and z values to control scale) point = XYZ(x*10,y*10,z*10) refpt = doc.FamilyCreate.NewReferencePoint(point) #Increment v v = v + vStep #Increment u u = u + uStep
Creating the Surface
After plotting the points, it is now just a matter of implementing the method for creating a NewLoftForm()
#Start value for u u = math.pi * -1 while (u <= (u1+uStep)): #Start value for v v = -1 #Reference Point Array refptsarr = ReferencePointArray() while (v <= v1): #Parametric equations for Mobius plot x = (R + v * math.cos(T * u)) * math.cos(u) y = (R + v * math.cos(T * u)) * math.sin(u) z = v * math.sin(T * u) point = XYZ(x*10,y*10,z*10) refpt = doc.FamilyCreate.NewReferencePoint(point) refptsarr.Append(refpt) #Increment v v = v + vStep #Increment u u = u + uStep #Create curve from Reference Point Array crv = doc.FamilyCreate.NewCurveByPoints(refptsarr) #Append reference arrays for surface creation refarr = ReferenceArray() refarr.Append(crv.GeometryCurve.Reference) refarar.Append(refarr) #Create surface doc.FamilyCreate.NewLoftForm(True, refarar)
Summary
The full code is as follows
import clr import math clr.AddReference('RevitAPI') clr.AddReference('RevitAPIUI') from Autodesk.Revit.DB import * app = __revit__.Application doc = __revit__.ActiveUIDocument.Document t = Transaction(doc, 'Creates a mobius surface.') t.Start() #Declare surface parameters R = 4.0 T = 0.5 #U and V division variables uDiv = 50 vDiv = 10 #Range variables u0 = math.pi * -1 u1 = math.pi v0 = -1.0 v1 = 1.0 #Step increments uStep = abs(u1 - u0) / uDiv vStep = abs(v1 - v0) / vDiv #Starting values for u and v #Declare Reference Array Array refarar = ReferenceArrayArray() #Start value for u u = math.pi * -1 while (u <= (u1+uStep)): #Start value for v v = -1 #Reference Point Array refptsarr = ReferencePointArray() while (v <= v1): #Parametric equations for Mobius plot x = (R + v * math.cos(T * u)) * math.cos(u) y = (R + v * math.cos(T * u)) * math.sin(u) z = v * math.sin(T * u) #Plot reference points and append to array. point = XYZ(x*10,y*10,z*10) refpt = doc.FamilyCreate.NewReferencePoint(point) refptsarr.Append(refpt) #Increment v v = v + vStep #Increment u u = u + uStep #create curve from Reference Point Array crv = doc.FamilyCreate.NewCurveByPoints(refptsarr) #append reference arrays for surface creation refarr = ReferenceArray() refarr.Append(crv.GeometryCurve.Reference) refarar.Append(refarr) #create surface doc.FamilyCreate.NewLoftForm(True, refarar) t.Commit() __window__.Close()
Now that you have the code… what kinds of variations can discover…?
Hint: This variation was done by modifying the T parameter…