Adjusting cutback programmatically

By Mikako Harada

Issue

In the UI, you can control the adjustment of cutbacks between two framing structures, such as beams and columns. (i.e., Select a beam or a column  >>  contextual "Modify | Structural Framing" tab  >>  "Geometry" panel  >> "Beam/Column Joins" button, which is a rather shy looking little icon located at the center of the panel.) 

BeamColumnJoins2

How can we accomplish the same using the API? 

Solution

FamilyInstance has a property called ExtensionUtility. You can modify this property to set to desired join types. e.g.,

                IExtension ie1 = girder1.ExtensionUtility;

                if (ie1 != null)

                {

                    // This sets cutback join  

                    ie1.set_Extended(0, false);

                    ie1.set_Extended(1, false);

            
                    // This extends the ends.  

                    //ie1.set_Extended(0, true);

                    //ie1.set_Extended(1, true);

                }

where the first argument of the Extended is the index of two ends, which is either 0 or 1. The second indicates if the end is extended or not (if not, it means cutback).

Below is a sample code that demonstrates the usage of this property.

The sample creates two set of girders and place them in circular shapes: one with cutbacks at both ends. The other with miter.  When Extended property is false, it creates a cutback. If Extended is true for two ends, they create a miter end. One little caveat I found is that Revit tries to adjust those join conditions automatically when you first add elements to the document. To override this behavior, you will need to set join conditions after girders were added to the document to make sure that your setting is respected. The resulting configuration is shown in the picture at the bottom. 

Note: helper functions, FindFamilyType and FindElement, are same as the ones in our training labs, which you can find on our public ADN site under Samples and Documentation section.  

// Create a set of girders and place them in a circular shape, 
    // and set the join type (i.e., cutback and miter).  
 
    [Transaction(TransactionMode.Manual)]
    public class rvtCmd_CreateBeamCircle : IExternalCommand
    {
        //  Member variables
 
        Application m_rvtApp;
        Document m_rvtDoc;
 
        public Result Execute(
            ExternalCommandData commandData,
            ref string message,
            ElementSet elements)
        {
            //  Get the access to the top most objects. 
 
            UIApplication rvtUIApp = commandData.Application;
            UIDocument rvtUIDoc = rvtUIApp.ActiveUIDocument;
            m_rvtApp = rvtUIApp.Application;
            m_rvtDoc = rvtUIDoc.Document;
 
            // Find a family type called "M_W-Wide Flange: W310X38.7"
            // Hard coding for simplicity. 
            // Try with a metric construction template, for example. 
 
            const string GirderFamilyName = "M_W-Wide Flange"; 
            const string GirderFamilyTypeName = "W310X38.7"; 
 
            FamilySymbol girderType =
                (FamilySymbol)Utils.FindFamilyType(
                m_rvtDoc, typeof(FamilySymbol),
                GirderFamilyName, GirderFamilyTypeName,
                BuiltInCategory.OST_StructuralFraming);
 
            if (girderType == null)
            {
                TaskDialog.Show(
                    "CreateBeamCircle",
                    "Please load: " + 
                    GirderFamilyName + ": " + GirderFamilyTypeName);
 
                return Result.Failed;
            }
 
            // Find "Level 1"
 
            Level level1 = 
                (Level)Utils.FindElement(
                m_rvtDoc, typeof(Level), "Level 1");
 
            // Create a set of girders with cutback 
 
            double radius = 8.0;
            bool join = false; // cutback 
            CreateGirderCircle(girderType, level1, radius, join);
 
            // This time, create a set of girders with miter
 
            radius = 6.0;
            join = true; // miter 
            CreateGirderCircle(girderType, level1, radius, join); 
 
            return Result.Succeeded;
        }
 
        // Create a set of girders and form a circular shape 
 
        public bool CreateGirderCircle(
            FamilySymbol girderType, Level level1, 
            double radius, bool join)
        {
            Transaction tr = 
              new Transaction(m_rvtDoc, "Create Girder");
            tr.Start();
 
            // Create a set of girders and place them in circle
 
            int div = 20;    // # of division 
            double th = Math.PI * 2.0/(double)div; // angle per girder 
            double ang = 0.0;
            double z = level1.Elevation; 
            XYZ pt1 = new XYZ(radius, 0.0, z);
            List girders = new List(); 
 
            for (int i = 1; i > Edit Geometry >> Beam/Column Join 
            // 
            //   IExtension.Extended(index, isCutback) 
            //     index: 0 or 1, indicating an end point.
            //     isCutback: indicates if we can to cutback or not.
            //     If two beams with no cutback meet, they will be 
            //     miterd. 
 
            IExtension ie1 = girders.Last().ExtensionUtility;
 
            for (int i = 0; i < div; i++)
            {
                IExtension ie2 = girders[i].ExtensionUtility;
 
                if (ie1 != null && ie2 != null)
                {
                    // join = false: cutback, true: miter  
                    ie1.set_Extended(1, join);
                    ie2.set_Extended(0, join);
                }
 
                ie1 = ie2; 
            }
 
            m_rvtDoc.Regenerate(); 
 
            // Finally commit
 
            tr2.Commit();
 
            return true;
        }
 
        // Create each girder with a given family type at 
        // the given location.  
 
        private FamilyInstance CreateGirder(
            XYZ pt1, XYZ pt2, FamilySymbol symbol, Level level)
        {
            // Create a girder 
 
            Line line = m_rvtApp.Create.NewLineBound(pt1, pt2);
            FamilyInstance girder = 
                m_rvtDoc.Create.NewFamilyInstance(
                line, symbol, level, StructuralType.Beam);
 
            return girder;
        }
 
    }
 
Here is the results. The outer circle shows cutback at both ends. The inner circle shows miter joins.

Comments

Leave a Reply

Discover more from Autodesk Developer Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading