Adaptive Component Creation

Here is some code that shows how to place adaptive components. In this case, the adaptive component contains 2 placement points. I wrote this to examine the shape of an element’s bounding box – you may find other uses for it.

bboxpublic void bbox()
    UIDocument uidoc = this.ActiveUIDocument;
    Document doc = uidoc.Document;   
    // select an element
    Element element = doc.GetElement(uidoc.Selection.PickObject(ObjectType.Element));
    // get bounding box of the element
    BoundingBoxXYZ bbox = element.get_BoundingBox(null);
    // get adaptive component family instance
    FamilySymbol fs = new FilteredElementCollector(doc).OfClass(typeof(FamilySymbol)).Cast<FamilySymbol>().First(q => q.Name == "Type 1" && q.Family.Name == "TwoPoint");
    // create instances of the adaptive component
    placeInstance(fs, bbox.Min, bbox.Max, "Space Diagonal");
    placeInstance(fs, bbox.Min, new XYZ(bbox.Max.X, bbox.Max.Y, bbox.Min.Z), "Base diagonal");
    placeInstance(fs, bbox.Min, new XYZ(bbox.Max.X, bbox.Min.Y, bbox.Min.Z), "vx");
    placeInstance(fs, bbox.Min, new XYZ(bbox.Min.X, bbox.Max.Y, bbox.Min.Z), "vy");
    placeInstance(fs, bbox.Min, new XYZ(bbox.Min.X, bbox.Min.Y, bbox.Max.Z), "vz");

// create a new instance of the family & set the location of endpoints and Comments parameter
private void placeInstance (FamilySymbol fs, XYZ xyz1, XYZ xyz2, string comment)
    Document doc = fs.Document;
    using (Transaction t = new Transaction(doc,"adaptive component"))
        // place the adaptive component - adaptive points are automatically given some default position during creation
        FamilyInstance fi = AdaptiveComponentInstanceUtils.CreateAdaptiveComponentInstance(doc, fs);
        // get references to the adaptive points in the newly created instance
        IList<FamilyPointPlacementReference> refs = fi.GetFamilyPointPlacementReferences();        
        // adaptive component points are named "start" and "end"
        // move these points to the input XYZ locations xyz1 and xyz2 
        movePoint(doc, refs.First(q => q.Name == "start"), xyz1);
        movePoint(doc, refs.First(q => q.Name == "end"), xyz2);
        // get Comments parameter and set its value

// move an FamilyPointPlacementReference to a specified XYZ
private void movePoint(Document doc, FamilyPointPlacementReference point, XYZ xyz)
    // need to subtract the default XYZ location of the point from the desired XYZ location
    ElementTransformUtils.MoveElement(doc, point.PointReference.ElementId, xyz.Subtract(locationFromPoint(doc, point)));

// get the XYZ location of a FamilyPointPlacementReference
private XYZ locationFromPoint(Document doc, FamilyPointPlacementReference point)
    Element e = doc.GetElement(point.PointReference.ElementId);
    ReferencePoint rp = e as ReferencePoint;
    return rp.Position;

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s