RevitPythonShell: Parametric Forms

<<< 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
RPS-Parametric-MobiusPoints.jpg

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)
RPS-Parametric-MobiusSurface.jpg

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…

RPS-Parametric-MobiusSurface2.jpg
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License