RevitPythonShell: Forms

<<< Return to Nathan's Revit API Notebook

Introduction

The Revit API allows the user to create forms and surfaces using 6 methods. Each method requires a different set of inputs. Forms are created using the methods available through FamilyCreate

We commonly need the following element types to create forms.

  1. Points
  2. Sketch Planes
  3. Model Curves
  4. Reference Arrays

Cap

Caps are created using NewFormByCap() with the following parameters:

  • bool isSolid
  • ReferenceArray profile
Simple Cap
import clr
clr.AddReference('RevitAPI') 
clr.AddReference('RevitAPIUI') 
from Autodesk.Revit.DB import * 
 
doc = __revit__.ActiveUIDocument.Document
app = __revit__.Application
 
t = Transaction(doc, 'Create simple cap.')
 
t.Start()
#Define cap form corners XYZ to define plane corners
p1 = XYZ(0,0,0)
p2 = XYZ(20,0,0)
p3 = XYZ(20,20,10)
p4 = XYZ(0,20,10)
 
#Define edge of the cap form
line1 = app.Create.NewLine(p1, p2, True)
line2 = app.Create.NewLine(p2, p3, True)
line3 = app.Create.NewLine(p3, p4, True)
line4 = app.Create.NewLine(p4, p1, True)
 
#create and append a new CurveArray() with plane curves
crvarr = CurveArray()
crvarr.Append(line1)
crvarr.Append(line2)
 
#create a sketch plane
plane = app.Create.NewPlane(crvarr)
skplane = doc.FamilyCreate.NewSketchPlane(plane)
 
#create model curves
crv1 = doc.FamilyCreate.NewModelCurve(line1, skplane)
crv2 = doc.FamilyCreate.NewModelCurve(line2, skplane)
crv3 = doc.FamilyCreate.NewModelCurve(line3, skplane)
crv4 = doc.FamilyCreate.NewModelCurve(line4, skplane)
 
#create reference array for model curves
refarr = ReferenceArray()
refarr.Append(crv1.GeometryCurve.Reference)
refarr.Append(crv2.GeometryCurve.Reference)
refarr.Append(crv3.GeometryCurve.Reference)
refarr.Append(crv4.GeometryCurve.Reference)
 
#create cap form
cap = doc.FamilyCreate.NewFormByCap(True, refarr)
 
t.Commit()
 
__window__.Close()
RPS-Points-CreateCap.jpg

Extrusion

Extrusions are created using NewExtrusionForm() with the following parameters:

  • bool isSolid
  • ReferenceArray profile
  • XYZ direction
Simple Box

The following code creates a cube using extrusion. I am first defining the sketch plane, establishing the square vertices, creating lines with NewLine(), making model curves with NewModelCurve(), and then extruding the ReferenceArray() of model curves with NewExtrusionForm()

import clr
clr.AddReference('RevitAPI') 
clr.AddReference('RevitAPIUI') 
from Autodesk.Revit.DB import * 
 
doc = __revit__.ActiveUIDocument.Document
app = __revit__.Application
 
t = Transaction(doc, 'Create extrusion.')
 
t.Start()
 
#Create a sketch plane
origin = XYZ.Zero
normal = XYZ.BasisZ
 
plane = app.Create.NewPlane(normal, origin)
skplane = doc.FamilyCreate.NewSketchPlane(plane)
 
#Create line vertices
lnPt1 = XYZ(0,0,0)
lnPt2 = XYZ(10,0,0)
lnPt3 = XYZ(10,10,0)
lnPt4 = XYZ(0,10,0)
 
#create lines
lineA = app.Create.NewLine(lnPt1, lnPt2, True)
lineB = app.Create.NewLine(lnPt2, lnPt3, True)
lineC = app.Create.NewLine(lnPt3, lnPt4, True)
lineD = app.Create.NewLine(lnPt4, lnPt1, True)
 
#create model curves from lines
crvA = doc.FamilyCreate.NewModelCurve(lineA, skplane)
crvB = doc.FamilyCreate.NewModelCurve(lineB, skplane)
crvC = doc.FamilyCreate.NewModelCurve(lineC, skplane)
crvD = doc.FamilyCreate.NewModelCurve(lineD, skplane)
 
#create reference array and append with geometry curve references
refarr = ReferenceArray()
refarr.Append(crvA.GeometryCurve.Reference)
refarr.Append(crvB.GeometryCurve.Reference)
refarr.Append(crvC.GeometryCurve.Reference)
refarr.Append(crvD.GeometryCurve.Reference)
 
#establish extrusion vector
dir = XYZ(0,0,10)
 
#extrude the form
extrude = doc.FamilyCreate.NewExtrusionForm(True,refarr,dir)
 
t.Commit()
 
__window__.Close()
RPS-Forms-CreateExtrusion.jpg
Simple Box (Loop method)

This code creates the same simple box but instead uses a for loop for more efficient coding.

import clr
import math
clr.AddReference('RevitAPI') 
clr.AddReference('RevitAPIUI') 
from Autodesk.Revit.DB import * 
 
doc = __revit__.ActiveUIDocument.Document
app = __revit__.Application
 
t = Transaction(doc, 'Create extrusion with a loop.')
 
t.Start()
 
#Create a sketch plane
origin = XYZ.Zero
normal = XYZ.BasisZ
 
plane = app.Create.NewPlane(normal, origin)
skplane = doc.FamilyCreate.NewSketchPlane(plane)
 
#Create array and append vertices
pts = []
pts.append(XYZ(0,0,0))
pts.append(XYZ(10,0,0))
pts.append(XYZ(10,10,0))
pts.append(XYZ(0,10,0))
pts.append(XYZ(0,0,0))
 
#create Reference Array for curves
refarr = ReferenceArray()
 
#use a loop to fill reference array with model curves.
for i in range(0,len(pts)-1):
    ptA = pts[i]
    ptB = pts[i+1]
 
    line = app.Create.NewLine(ptA,ptB,True)
    crv = doc.FamilyCreate.NewModelCurve(line,skplane)
    refarr.Append(crv.GeometryCurve.Reference)
 
#establish extrusion vector
dir = XYZ(0,0,10)
 
#extrude the form
extrude = doc.FamilyCreate.NewExtrusionForm(True,refarr,dir)
 
t.Commit()
 
__window__.Close()
Row of Boxes

Using a loop, we can create an row of boxes with increasing extrusion heights.

import clr
import math
clr.AddReference('RevitAPI') 
clr.AddReference('RevitAPIUI') 
from Autodesk.Revit.DB import * 
 
doc = __revit__.ActiveUIDocument.Document
app = __revit__.Application
 
t = Transaction(doc, 'Create row of extrusion.')
 
t.Start()
 
#Create a sketch plane
origin = XYZ.Zero
normal = XYZ.BasisZ
 
plane = app.Create.NewPlane(normal, origin)
skplane = doc.FamilyCreate.NewSketchPlane(plane)
 
# the first loop changes the position of corner points
for i in range(0,10):
    #Create array of vertex points and append vertices
    pts = []
    pts.append(XYZ(0+(i*15),0+(i*15),0))
    pts.append(XYZ(10+(i*15),0+(i*15),0))
    pts.append(XYZ(10+(i*15),10+(i*15),0))
    pts.append(XYZ(0+(i*15),10+(i*15),0))
    pts.append(XYZ(0+(i*15),0+(i*15),0))
 
    refarr = ReferenceArray()
 
    # this nested loop creates curves to extrude
    for j in range(0,len(pts)-1):
        ptA = pts[j]
        ptB = pts[j+1]
 
        line = app.Create.NewLine(ptA,ptB,True)
        crv = doc.FamilyCreate.NewModelCurve(line,skplane)
        refarr.Append(crv.GeometryCurve.Reference)
 
    #The z direction is controlled by the value of i
    dir = XYZ(0,0,10+(i*10))
 
    #extrude the form
    extrude = doc.FamilyCreate.NewExtrusionForm(True,refarr,dir)
 
t.Commit()
 
__window__.Close()
RPS-Forms-CreateExtrusionRow.jpg

Revolve

Revolves are created using NewRevolveForms() with the following parameters:

  • bool isSolid
  • ReferenceArray profile
  • Reference axis
  • double startAngle
  • double endAngle
Simple Revolve Shell

The following code creates a simple shell using an axis created with NewModelCurve() and a curved profile created with NewCurveByPoints()

import clr
import math
clr.AddReference('RevitAPI') 
clr.AddReference('RevitAPIUI') 
from Autodesk.Revit.DB import * 
 
doc = __revit__.ActiveUIDocument.Document
app = __revit__.Application
 
t = Transaction(doc, 'Create revolve.')
 
t.Start()
 
#Create a sketch plane
origin = XYZ.Zero
normal = XYZ.BasisZ
 
plane = app.Create.NewPlane(normal, origin)
skplane = doc.FamilyCreate.NewSketchPlane(plane)
 
#create axis curve
lnStart = XYZ(0,0,0)
lnEnd = XYZ(0,50,0)
 
line = app.Create.NewLine(lnStart, lnEnd, True)
axis = doc.FamilyCreate.NewModelCurve(line, skplane)
axisRef = axis.GeometryCurve.Reference
 
#create revolve profile
profileRefArr = ReferenceArray()
refptarr = ReferencePointArray()
 
pts = []
pts.append(XYZ(-20,0,0))
pts.append(XYZ(-30,25,0))
pts.append(XYZ(-20,50,0))
pts.append(XYZ(-30,75,0))
pts.append(XYZ(-20,100,0))
 
for i in range(0,5):
    refpt = doc.FamilyCreate.NewReferencePoint(pts[i])
    refptarr.Append(refpt)
 
profile = doc.FamilyCreate.NewCurveByPoints(refptarr)
profileRefArr.Append(profile.GeometryCurve.Reference)
 
#Revolve parameters
startAngle = 0
endAngle = 2*math.pi
 
#Create revolve
revolve = doc.FamilyCreate.NewRevolveForms(True, profileRefArr, axisRef, startAngle, endAngle)
 
t.Commit()
 
__window__.Close()
RPS-Forms-CreateRevolveShell.jpg

Loft

Lofts are created using NewLoftForm() with the following parameters:

  • bool isSolid
  • ReferenceArrayArray profiles
Simple Loft

The following code creates a simple loft between 3 profile curves. Each curve is defined individually.

import clr
import math
clr.AddReference('RevitAPI') 
clr.AddReference('RevitAPIUI') 
from Autodesk.Revit.DB import * 
 
doc = __revit__.ActiveUIDocument.Document
app = __revit__.Application
 
t = Transaction(doc, 'Create loft.')
 
t.Start()
 
refarr = ReferenceArray()
refarrarr = ReferenceArrayArray()
 
#Create first profile curve
refptarr1 = ReferencePointArray()
pt1 = XYZ(0,0,5)
pt2 = XYZ(20,0,-5)
pt3 = XYZ(40,0,5)
refptarr1.Append(doc.FamilyCreate.NewReferencePoint(pt1))
refptarr1.Append(doc.FamilyCreate.NewReferencePoint(pt2))
refptarr1.Append(doc.FamilyCreate.NewReferencePoint(pt3))
crv1 = doc.FamilyCreate.NewCurveByPoints(refptarr1)
 
#Append reference arrays
refarr1 = ReferenceArray()
refarr1.Append(crv1.GeometryCurve.Reference)
refarrarr.Append(refarr1)
 
#Create second profile curve
refptarr2 = ReferencePointArray()
pt4 = XYZ(0,20,0)
pt5 = XYZ(20,20,10)
pt6 = XYZ(40,20,0)
refptarr2.Append(doc.FamilyCreate.NewReferencePoint(pt4))
refptarr2.Append(doc.FamilyCreate.NewReferencePoint(pt5))
refptarr2.Append(doc.FamilyCreate.NewReferencePoint(pt6))
crv2 = doc.FamilyCreate.NewCurveByPoints(refptarr2)
 
#Append reference arrays
refarr2 = ReferenceArray()
refarr2.Append(crv2.GeometryCurve.Reference)
refarrarr.Append(refarr2)
 
#Create third profile curve
refptarr3 = ReferencePointArray()
pt7 = XYZ(0,40,5)
pt8 = XYZ(20,40,-5)
pt9 = XYZ(40,40,5)
refptarr3.Append(doc.FamilyCreate.NewReferencePoint(pt7))
refptarr3.Append(doc.FamilyCreate.NewReferencePoint(pt8))
refptarr3.Append(doc.FamilyCreate.NewReferencePoint(pt9))
crv3 = doc.FamilyCreate.NewCurveByPoints(refptarr3)
 
#Append reference arrays
refarr3 = ReferenceArray()
refarr3.Append(crv3.GeometryCurve.Reference)
refarrarr.Append(refarr3)
 
#create Loft
loft = doc.FamilyCreate.NewLoftForm(True, refarrarr)
 
t.Commit()
 
__window__.Close()
RPS-Forms-CreateLoft.jpg
Loft Wave

We can create even more complexity to our surface (and simplify the code) by using nested loops to define a series of profile curves. This uses the same code from the curve wave example to create a surface from loft.

import clr
import math
clr.AddReference('RevitAPI') 
clr.AddReference('RevitAPIUI') 
from Autodesk.Revit.DB import * 
 
doc = __revit__.ActiveUIDocument.Document
app = __revit__.Application 
 
t = Transaction(doc, 'wave curve array')
 
t.Start()
 
refarrarr = ReferenceArrayArray()
 
#use a nested loop to create rows of profile curves
for i in range(0,20):
    refptarr = ReferencePointArray()
    for j in range(0,20):
        x = i * 10
        y = j * 10
        z = (10*math.cos(i)) + (10*math.sin(j))
 
        myXYZ = XYZ(x,y,z)
        refPoint = doc.FamilyCreate.NewReferencePoint(myXYZ)
        refptarr.Append(refPoint)
 
    crv = doc.FamilyCreate.NewCurveByPoints(refptarr)
 
    #append curves to reference arrays
    refarr = ReferenceArray()
    refarr.Append(crv.GeometryCurve.Reference)
    refarrarr.Append(refarr)
 
#create loft
loft = doc.FamilyCreate.NewLoftForm(True, refarrarr)
 
t.Commit()
 
__window__.Close()
RPS-Forms-CreateLoftWave.jpg
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License