RevitPythonShell: Adaptive Components

<<< Return to Nathan's Revit API Notebook

Introduction

Adaptive Components are a special Family type and a powerful parametric feature of Revit and Vasari. Users can create complex parametric relationships which are anchored on adaptive points. This can be thought of as a family with 3 or more insertion points. When the component is placed in the project, the adaptive points position may vary but the inherent parametric relationships of the component will remain in tact.

Placing Adaptive Components through the API gives us some powerful new capabilities for creating a model.

Placing an Adaptive Component

This example shows how to place an Adaptive Component that has been loaded into the project and has 4 insertion points. The Adaptive Component looks like this…

RPS-Adaptive-ExampleComponent.jpg

Getting the Family

We will use the same filtering method introduced in the Family and Parameters section. This is used to to find the loaded Adaptive Component in our document.

#Name of the Adaptive Componet
symbName = 'AdaptiveComponentTest'
 
#Create a filtered element collector set to Category OST_Mass and Class FamilySymbol 
collector = FilteredElementCollector(doc)
collector.OfCategory(BuiltInCategory.OST_GenericModel)
collector.OfClass(FamilySymbol)
 
famtypeitr = collector.GetElementIdIterator()
famtypeitr.Reset()
 
#Search Family Symbols in document.
for item in famtypeitr:
    famtypeID = item
    famsymb = doc.get_Element(famtypeID)
 
    #If the FamilySymbol is the name we are looking for, create a new instance.
    if famsymb.Family.Name == symbName:

Create Adaptive Component Instance

We can place an instance of an Adaptive Component using AdaptiveComponentInstanceUtils and the CreateAdaptiveComponentInstance()

adaptComp = AdaptiveComponentInstanceUtils.CreateAdaptiveComponentInstance(doc, famsymb)

Get Instance Placement Points

After we have the Adaptive Component instance, we need to access the adaptive points that are used to place the component. This is done with GetInstancePlacementPointElementRefIds(). This will return a list of point Element IDs.

adptPoints = AdaptiveComponentInstanceUtils.GetInstancePlacementPointElementRefIds(adaptComp)

Move Placement Points

Once we have access to the point Element IDs, we can then move them in place using ElementTransformUtils.MoveElement()

        #Starting adaptive point locations.  get_Element returns a Reference Point
        aPt1 = doc.get_Element(adptPoints[0])
        aPt2 = doc.get_Element(adptPoints[1])
        aPt3 = doc.get_Element(adptPoints[2])
        aPt4 = doc.get_Element(adptPoints[3])
 
        #Desired Adaptive Point Locations
        loc1 = XYZ(0,0,0)
        loc2 = XYZ(0,40,20) 
        loc3 = XYZ(40,40,0) 
        loc4 = XYZ(40,0,20) 
 
        #Some vector math to get the translation for MoveElement()
        trans1 = loc1.Subtract(aPt1.Position)
        trans2 = loc2.Subtract(aPt2.Position)
        trans3 = loc3.Subtract(aPt3.Position)
        trans4 = loc4.Subtract(aPt4.Position)
 
        #Position Adaptive Component using MoveElement()
        ElementTransformUtils.MoveElement(doc, points[0], trans1)
        ElementTransformUtils.MoveElement(doc, points[1], trans2)
        ElementTransformUtils.MoveElement(doc, points[2], trans3)
        ElementTransformUtils.MoveElement(doc, points[3], trans4)

Summary

The final code will look like…

import clr
clr.AddReference('RevitAPI') 
clr.AddReference('RevitAPIUI') 
from Autodesk.Revit.DB import * 
 
app = __revit__.Application
doc = __revit__.ActiveUIDocument.Document
 
t = Transaction(doc, 'Place an Adaptive Component.')
 
t.Start()
 
#Family symbol name to place.
symbName = 'AdaptiveComponentTest'
 
#create a filtered element collector set to Category OST_Mass and Class FamilySymbol 
collector = FilteredElementCollector(doc)
collector.OfCategory(BuiltInCategory.OST_GenericModel)
collector.OfClass(FamilySymbol)
 
famtypeitr = collector.GetElementIdIterator()
famtypeitr.Reset()
 
#Search Family Symbols in document.
for item in famtypeitr:
    famtypeID = item
    famsymb = doc.get_Element(famtypeID)
 
    #If the FamilySymbol is the name we are looking for, create a new instance.
    if famsymb.Family.Name == symbName:
 
        adaptComp = AdaptiveComponentInstanceUtils.CreateAdaptiveComponentInstance(doc, famsymb)
        adptPoints = AdaptiveComponentInstanceUtils.GetInstancePlacementPointElementRefIds(adaptComp)
 
        #Starting adaptive point locations.  get_Element returns a Reference Point
        aPt1 = doc.get_Element(adptPoints[0])
        aPt2 = doc.get_Element(adptPoints[1])
        aPt3 = doc.get_Element(adptPoints[2])
        aPt4 = doc.get_Element(adptPoints[3])
 
        #Desired Adaptive Point Locations
        loc1 = XYZ(0,0,0)
        loc2 = XYZ(0,40,20) 
        loc3 = XYZ(40,40,0) 
        loc4 = XYZ(40,0,20) 
 
        #Some vector math to get the translation for MoveElement()
        trans1 = loc1.Subtract(aPt1.Position)
        trans2 = loc2.Subtract(aPt2.Position)
        trans3 = loc3.Subtract(aPt3.Position)
        trans4 = loc4.Subtract(aPt4.Position)
 
        #Position Adaptive Component using MoveElement()
        ElementTransformUtils.MoveElement(doc, adptPoints[0], trans1)
        ElementTransformUtils.MoveElement(doc, adptPoints[1], trans2)
        ElementTransformUtils.MoveElement(doc, adptPoints[2], trans3)
        ElementTransformUtils.MoveElement(doc, adptPoints[3], trans4)
 
t.Commit()
 
__window__.Close()
RPS-Adaptive-PlacedComponent.jpg
RPS-Adaptive-PlacedComponentMulti.jpg
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License