예제 #1
0
        /// <summary>
        /// Some families eg columns, need offsets to be set in a specific way. This tries to cover that.
        /// </summary>
        /// <param name="speckleElement"></param>
        /// <param name="familyInstance"></param>
        private void SetOffsets(DB.FamilyInstance familyInstance, RevitColumn speckleRevitColumn)
        {
            var topOffsetParam  = familyInstance.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_OFFSET_PARAM);
            var baseOffsetParam = familyInstance.get_Parameter(BuiltInParameter.FAMILY_BASE_LEVEL_OFFSET_PARAM);
            var baseLevelParam  = familyInstance.get_Parameter(BuiltInParameter.FAMILY_BASE_LEVEL_PARAM);
            var topLevelParam   = familyInstance.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_PARAM);

            if (topLevelParam == null || baseLevelParam == null || baseOffsetParam == null || topOffsetParam == null)
            {
                return;
            }

            var baseOffset = ScaleToNative(speckleRevitColumn.baseOffset, speckleRevitColumn.units);
            var topOffset  = ScaleToNative(speckleRevitColumn.topOffset, speckleRevitColumn.units);

            //these have been set previously
            //DB.Level level = Doc.GetElement(baseLevelParam.AsElementId()) as DB.Level;
            //DB.Level topLevel = Doc.GetElement(topLevelParam.AsElementId()) as DB.Level;

            //checking if BASE offset needs to be set before or after TOP offset
            //      if ((topLevel != null && level.Elevation + baseOffset == topLevel.Elevation) ||
            //       (topLevel!=null && topLevel.Elevation == level.Elevation && baseOffset > 0)) //edge case
            //    {
            baseOffsetParam.Set(baseOffset);
            topOffsetParam.Set(topOffset);
            //    }
            //    else
            //    {
            //       topOffsetParam.Set(topOffset);
            //      baseOffsetParam.Set(baseOffset);
            //    }
        }
예제 #2
0
        PlaceColumn(Autodesk.Revit.ApplicationServices.Application rvtApp, Document rvtDoc, Autodesk.Revit.DB.XYZ point2, double angle, FamilySymbol columnType, ElementId baseLevelId, ElementId topLevelId)
        {
            Autodesk.Revit.DB.XYZ point = point2;
            // Note: Must use level-hosted NewFamilyInstance!
            Level instLevel = (Level)rvtDoc.GetElement(baseLevelId);

            Autodesk.Revit.DB.FamilyInstance column = rvtDoc.Create.NewFamilyInstance(point, columnType, instLevel, StructuralType.Column);

            if (column == null)
            {
                MessageBox.Show("failed to create an instance of a column.");
                return;
            }

            Autodesk.Revit.DB.XYZ zVec = new Autodesk.Revit.DB.XYZ(0, 0, 1);


            Autodesk.Revit.DB.Line axis = Line.CreateUnbound(point, zVec);

            column.Location.Rotate(axis, angle);

            // Set the level Ids
            Parameter baseLevelParameter = column.get_Parameter(Autodesk.Revit.DB.BuiltInParameter.FAMILY_BASE_LEVEL_PARAM);
            Parameter topLevelParameter  = column.get_Parameter(Autodesk.Revit.DB.BuiltInParameter.FAMILY_TOP_LEVEL_PARAM);;

            baseLevelParameter.Set(baseLevelId);
            topLevelParameter.Set(topLevelId);
        }
예제 #3
0
 public static void SetTitleBlockParameters(Element existingTitleBlock, Element newTitleBlock)
 {
     try
     {
         Autodesk.Revit.DB.FamilyInstance familyInstance1 = existingTitleBlock as Autodesk.Revit.DB.FamilyInstance;
         Autodesk.Revit.DB.FamilyInstance familyInstance2 = newTitleBlock as Autodesk.Revit.DB.FamilyInstance;
         IList <Parameter> orderedParameters = familyInstance1.GetOrderedParameters();
         familyInstance2.GetOrderedParameters();
         foreach (Parameter parameter1 in (IEnumerable <Parameter>)orderedParameters)
         {
             string    name       = parameter1.Definition.Name;
             Parameter parameter2 = familyInstance1.LookupParameter(name);
             Parameter parameter3 = familyInstance2.LookupParameter(name);
             if (parameter3 != null || parameter2 != null)
             {
                 BuiltInParameter parameterId1 = BuiltInParameter.SHEET_NUMBER;
                 Parameter        parameter4   = familyInstance2.get_Parameter(parameterId1);
                 BuiltInParameter parameterId2 = BuiltInParameter.SHEET_NAME;
                 Parameter        parameter5   = familyInstance2.get_Parameter(parameterId2);
                 if (!(parameter3.Definition.Name == parameter4.Definition.Name) && !(parameter3.Definition.Name == parameter5.Definition.Name))
                 {
                     try
                     {
                         if (parameter3.StorageType == StorageType.Double)
                         {
                             parameter3.Set(parameter2.AsDouble());
                         }
                         else if (parameter3.StorageType == StorageType.ElementId)
                         {
                             parameter3.Set(parameter2.AsElementId());
                         }
                         else if (parameter3.StorageType == StorageType.Integer)
                         {
                             parameter3.Set(parameter2.AsInteger());
                         }
                         else if (parameter3.StorageType == StorageType.String)
                         {
                             parameter3.Set(parameter2.AsString());
                         }
                     }
                     catch
                     {
                     }
                 }
             }
         }
     }
     catch
     {
     }
 }
예제 #4
0
        private static void SetColParams(Column myCol, Autodesk.Revit.DB.FamilyInstance familyInstance, Autodesk.Revit.DB.Curve baseLine, List <string> exclusions, Autodesk.Revit.DB.Level myTopLevel, Autodesk.Revit.DB.Level baseLevel)
        {
            //checking if BASE offset needs to be set before or after TOP offset
            if (myTopLevel != null && myTopLevel.Elevation + (double)myCol.bottomOffset / Scale <= baseLevel.Elevation)
            {
                familyInstance.get_Parameter(BuiltInParameter.FAMILY_BASE_LEVEL_OFFSET_PARAM).Set((double)myCol.bottomOffset * Scale);
                familyInstance.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_OFFSET_PARAM).Set((double)myCol.topOffset * Scale);
            }
            else
            {
                familyInstance.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_OFFSET_PARAM).Set((double)myCol.topOffset * Scale);
                familyInstance.get_Parameter(BuiltInParameter.FAMILY_BASE_LEVEL_OFFSET_PARAM).Set((double)myCol.bottomOffset * Scale);
            }

            // Final preparations
            MatchFlippingAndRotation(familyInstance, myCol, baseLine);
            SetElementParams(familyInstance, myCol.parameters, exclusions);
        }
예제 #5
0
        public RevitColumn ColumnToSpeckle(DB.FamilyInstance revitColumn)
        {
            var speckleColumn = new RevitColumn();

            speckleColumn.type          = Doc.GetElement(revitColumn.GetTypeId()).Name;
            speckleColumn.level         = ConvertAndCacheLevel(revitColumn, BuiltInParameter.FAMILY_BASE_LEVEL_PARAM);
            speckleColumn.topLevel      = ConvertAndCacheLevel(revitColumn, BuiltInParameter.FAMILY_TOP_LEVEL_PARAM);
            speckleColumn.baseOffset    = GetParamValue <double>(revitColumn, BuiltInParameter.FAMILY_BASE_LEVEL_OFFSET_PARAM);
            speckleColumn.topOffset     = GetParamValue <double>(revitColumn, BuiltInParameter.FAMILY_TOP_LEVEL_OFFSET_PARAM);
            speckleColumn.facingFlipped = revitColumn.FacingFlipped;
            speckleColumn.handFlipped   = revitColumn.HandFlipped;
            speckleColumn.isSlanted     = revitColumn.IsSlantedColumn;
            speckleColumn.structural    = revitColumn.StructuralType == StructuralType.Column;

            //geometry
            var baseGeometry = LocationToSpeckle(revitColumn);
            var baseLine     = baseGeometry as ICurve;

            //make line from point and height
            if (baseLine == null && baseGeometry is Point basePoint)
            {
                var topLevelParam = revitColumn.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_PARAM);
                var elevation     = (double)((RevitLevel)ParameterToSpeckle(topLevelParam).value).elevation;
                baseLine = new Line(basePoint, new Point(basePoint.x, basePoint.y, elevation + speckleColumn.topOffset, ModelUnits), ModelUnits);
            }

            if (baseLine == null)
            {
                throw new Speckle.Core.Logging.SpeckleException("Only line based Columns are currently supported.");
            }

            speckleColumn.baseLine = baseLine; //all speckle columns should be line based

            GetAllRevitParamsAndIds(speckleColumn, revitColumn,
                                    new List <string> {
                "FAMILY_BASE_LEVEL_PARAM", "FAMILY_TOP_LEVEL_PARAM", "FAMILY_BASE_LEVEL_OFFSET_PARAM", "FAMILY_TOP_LEVEL_OFFSET_PARAM"
            });

            if (revitColumn.Location is LocationPoint)
            {
                speckleColumn.rotation = ((LocationPoint)revitColumn.Location).Rotation;
            }

            speckleColumn["@displayMesh"] = GetElementMesh(revitColumn);

            return(speckleColumn);
        }
예제 #6
0
        void ReconstructBeamByCurve
        (
            DB.Document doc,
            ref DB.FamilyInstance element,

            Rhino.Geometry.Curve curve,
            Optional <DB.FamilySymbol> type,
            Optional <DB.Level> level
        )
        {
            var scaleFactor = 1.0 / Revit.ModelUnits;

            if
            (
                ((curve = curve.ChangeUnits(scaleFactor)) is null) ||
                curve.IsClosed ||
                !curve.TryGetPlane(out var axisPlane, Revit.VertexTolerance) ||
                curve.GetNextDiscontinuity(Rhino.Geometry.Continuity.C2_continuous, curve.Domain.Min, curve.Domain.Max, out var _)
            )
            {
                ThrowArgumentException(nameof(curve), "Curve must be a C2 continuous planar non closed curve.");
            }

            SolveOptionalLevel(ref level, doc, curve, nameof(level));

            var centerLine = curve.ToHost();

            if (type.HasValue)
            {
                ChangeElementTypeId(ref element, type.Value.Id);
            }

            if (element is object && element.Location is DB.LocationCurve locationCurve && centerLine.IsSameKindAs(locationCurve.Curve))
            {
                element.get_Parameter(DB.BuiltInParameter.LEVEL_PARAM).Set(level.Value.Id);

                locationCurve.Curve = centerLine;
            }
예제 #7
0
        void ReconstructFamilyInstanceByLocation
        (
            DB.Document doc,
            ref DB.FamilyInstance element,

            [Description("Location where to place the element. Point or plane is accepted.")]
            Rhino.Geometry.Plane location,
            DB.FamilySymbol type,
            Optional <DB.Level> level,
            [Optional] DB.Element host
        )
        {
            var scaleFactor = 1.0 / Revit.ModelUnits;

            location = location.ChangeUnits(scaleFactor);

            if (!location.IsValid)
            {
                ThrowArgumentException(nameof(location), "Should be a valid point or plane.");
            }

            SolveOptionalLevel(doc, location.Origin, ref level, out var bbox);

            if (host == null && type.Family.FamilyPlacementType == DB.FamilyPlacementType.OneLevelBasedHosted)
            {
                ThrowArgumentException(nameof(host), $"This family requires a host.");
            }

            if (!type.IsActive)
            {
                type.Activate();
            }

            ChangeElementTypeId(ref element, type.Id);

            bool hasSameHost = false;

            if (element is DB.FamilyInstance)
            {
                hasSameHost = (element.Host?.Id ?? DB.ElementId.InvalidElementId) == (host?.Id ?? DB.ElementId.InvalidElementId);
                if (element.Host == null)
                {
                    if (element?.get_Parameter(DB.BuiltInParameter.INSTANCE_FREE_HOST_PARAM) is DB.Parameter freeHostParam)
                    {
                        var freeHostName = freeHostParam.AsString();
                        hasSameHost = freeHostName.EndsWith(host?.Name ?? level.Value.Name);
                    }
                }
            }

            if
            (
                hasSameHost &&
                element is DB.FamilyInstance &&
                element.Location is DB.LocationPoint locationPoint
            )
            {
                using (var levelParam = element.get_Parameter(DB.BuiltInParameter.FAMILY_LEVEL_PARAM))
                {
                    if (levelParam.AsElementId() != level.Value.Id)
                    {
                        levelParam.Set(level.Value.Id);
                        doc.Regenerate();
                    }
                }

                if (host is object)
                {
                    var newOrigin = location.Origin.ToHost();
                    if (!newOrigin.IsAlmostEqualTo(locationPoint.Point))
                    {
                        element.Pinned      = false;
                        locationPoint.Point = newOrigin;
                        element.Pinned      = true;
                    }
                }
            }
            else
            {
                var creationData = new List <Autodesk.Revit.Creation.FamilyInstanceCreationData>()
                {
                    new Autodesk.Revit.Creation.FamilyInstanceCreationData(location.Origin.ToHost(), type, host, level.Value, DB.Structure.StructuralType.NonStructural)
                };

                var newElementIds = doc.IsFamilyDocument ?
                                    doc.FamilyCreate.NewFamilyInstances2(creationData) :
                                    doc.Create.NewFamilyInstances2(creationData);

                if (newElementIds.Count != 1)
                {
                    doc.Delete(newElementIds);
                    throw new InvalidOperationException();
                }

                var parametersMask = new DB.BuiltInParameter[]
                {
                    DB.BuiltInParameter.ELEM_FAMILY_AND_TYPE_PARAM,
                    DB.BuiltInParameter.ELEM_FAMILY_PARAM,
                    DB.BuiltInParameter.ELEM_TYPE_PARAM,
                    DB.BuiltInParameter.FAMILY_LEVEL_PARAM
                };

                ReplaceElement(ref element, doc.GetElement(newElementIds.First()) as DB.FamilyInstance, parametersMask);
                doc.Regenerate();
            }

            if (element is object && element.Host is null)
            {
                element.Pinned = false;
                element.SetTransform(location.Origin.ToHost(), location.XAxis.ToHost(), location.YAxis.ToHost());
                element.Pinned = true;
            }
        }
예제 #8
0
        public static SpeckleObject ColumnToSpeckle(Autodesk.Revit.DB.FamilyInstance myFamily)
        {
            var myColumn = new Column();

            var baseLevel = (Autodesk.Revit.DB.Level)Doc.GetElement(myFamily.get_Parameter(BuiltInParameter.FAMILY_BASE_LEVEL_PARAM).AsElementId());
            var topLevel  = (Autodesk.Revit.DB.Level)Doc.GetElement(myFamily.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_PARAM).AsElementId());

            myColumn.baseLevel = baseLevel?.ToSpeckle();
            myColumn.topLevel  = topLevel?.ToSpeckle();

            try
            {
                myColumn.baseLine = (SpeckleCoreGeometryClasses.SpeckleLine)SpeckleCore.Converter.Serialise(myFamily.GetAnalyticalModel().GetCurve());
            }
            catch
            {
                var basePt = (myFamily.Location as LocationPoint).Point;
                var topPt  = new XYZ(basePt.X, basePt.Y, topLevel.Elevation);
                myColumn.baseLine = (SpeckleCoreGeometryClasses.SpeckleLine)SpeckleCore.Converter.Serialise(Autodesk.Revit.DB.Line.CreateBound(basePt, topPt));
            }

            myColumn.columnFamily = myFamily.Symbol.FamilyName;
            myColumn.columnType   = Doc.GetElement(myFamily.GetTypeId()).Name;

            myColumn.parameters = GetElementParams(myFamily);



            // TODO: Maybe move this column properties in the class defintion
            myColumn.Properties["__facingFlipped"] = myFamily.FacingFlipped;
            myColumn.Properties["__handFlipped"]   = myFamily.HandFlipped;

            if (myFamily.Location is LocationPoint)
            {
                myColumn.Properties["__rotation"] = ((LocationPoint)myFamily.Location).Rotation;
            }
            else if (myFamily.Location is LocationCurve)
            {
                var myAngle = myFamily.get_Parameter(BuiltInParameter.STRUCTURAL_BEND_DIR_ANGLE).AsDouble(); // Stands for cross-section rotation!
                var rads    = UnitUtils.ConvertFromInternalUnits(myAngle, DisplayUnitType.DUT_RADIANS);
                myColumn.Properties["__rotation"] = rads;

                // TODO: Figure this column rotation shit out.
                // For now... Do nothing??
                //var t = myFamily.GetTotalTransform();
            }


            myColumn.GenerateHash();
            myColumn.ApplicationId = myFamily.UniqueId;
            myColumn.elementId     = myFamily.Id.ToString();

            // leaving the mesh out of the hashing process might address the randomatic hash generation we're getting
            // and hence the nuking the usability of local caching and diffing
            var allSolids = GetElementSolids(myFamily, opt: new Options()
            {
                DetailLevel = ViewDetailLevel.Fine, ComputeReferences = true
            });

            (myColumn.Faces, myColumn.Vertices) = GetFaceVertexArrFromSolids(allSolids);

            return(myColumn);
        }
예제 #9
0
        //TODO
        public static Element ToNative(this Column myCol)
        {
            var(docObj, stateObj) = GetExistingElementByApplicationId(myCol.ApplicationId, myCol.Type);

            var exclusions = new List <string> {
                "Base Offset", "Top Offset"
            };

            //setting params on myCol from myCol.parameters, if they are missing
            if (myCol.parameters != null)
            {
                if (myCol.bottomOffset == null && myCol.parameters.ContainsKey("Base Offset"))
                {
                    myCol.bottomOffset = myCol.parameters["Base Offset"] as double?;
                }

                if (myCol.topOffset == null && myCol.parameters.ContainsKey("Top Offset"))
                {
                    myCol.topOffset = myCol.parameters["Top Offset"] as double?;
                }
            }

            var baseLine = (Autodesk.Revit.DB.Curve)SpeckleCore.Converter.Deserialise(obj: myCol.baseLine, excludeAssebmlies: new string[] { "SpeckleCoreGeometryDynamo" });
            var start    = baseLine.GetEndPoint(0);
            var end      = baseLine.GetEndPoint(1);

            var isVertical = IsColumnVertical(myCol);

            // get family symbol; it's used throughout
            FamilySymbol familySymbol = TryGetColumnFamilySymbol(myCol.columnFamily, myCol.columnType);

            // Freak out if we don't have a symbol.
            if (familySymbol == null)
            {
                ConversionErrors.Add(new SpeckleConversionError {
                    Message = $"Missing family: {myCol.columnFamily} {myCol.columnType}"
                });
                throw new RevitFamilyNotFoundException($"No 'Column' family found in the project");
            }


            // Activate the symbol yo!
            if (!familySymbol.IsActive)
            {
                familySymbol.Activate();
            }

            if (docObj != null)
            {
                var type = Doc.GetElement(docObj.GetTypeId()) as ElementType;

                // if family changed, tough luck - delete and rewind
                if (myCol.columnFamily != type.FamilyName)
                {
                    Doc.Delete(docObj.Id);
                }
                else
                {
                    // Edit Endpoints and return
                    var existingFamilyInstance = (Autodesk.Revit.DB.FamilyInstance)docObj;

                    // Edit curve only if i'm not vertical
                    if (existingFamilyInstance.Location is LocationCurve)
                    {
                        existingFamilyInstance.get_Parameter(BuiltInParameter.SLANTED_COLUMN_TYPE_PARAM).Set((double)SlantedOrVerticalColumnType.CT_EndPoint);

                        var existingLocationCurve = existingFamilyInstance.Location as LocationCurve;
                        existingLocationCurve.Curve = baseLine;
                    }
                    else if (existingFamilyInstance.Location is LocationPoint)
                    {
                        var existingLocationPoint = existingFamilyInstance.Location as LocationPoint;
                        existingLocationPoint.Point = start;
                    }

                    // check if type changed, and try and change it
                    if (myCol.columnType != null && (myCol.columnType != type.Name))
                    {
                        existingFamilyInstance.ChangeTypeId(familySymbol.Id);
                    }

                    // Final preparations for good measure
                    Autodesk.Revit.DB.Level mytopLevel;
                    if (myCol.topLevel == null)
                    {
                        mytopLevel = Doc.GetElement(existingFamilyInstance.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_PARAM).AsElementId()) as Autodesk.Revit.DB.Level;
                    }
                    else
                    {
                        mytopLevel = myCol.topLevel.ToNative() as Autodesk.Revit.DB.Level;
                    }

                    Autodesk.Revit.DB.Level mybaseLevel;
                    if (myCol.baseLevel == null)
                    {
                        mybaseLevel = Doc.GetElement(existingFamilyInstance.get_Parameter(BuiltInParameter.FAMILY_BASE_LEVEL_PARAM).AsElementId()) as Autodesk.Revit.DB.Level;
                    }
                    else
                    {
                        mybaseLevel = myCol.baseLevel.ToNative() as Autodesk.Revit.DB.Level;
                    }

                    SetColParams(myCol, existingFamilyInstance, baseLine, exclusions, mytopLevel, mybaseLevel);

                    MatchFlippingAndRotation(existingFamilyInstance, myCol, baseLine);
                    SetElementParams(existingFamilyInstance, myCol.parameters, exclusions);
                    return(existingFamilyInstance);
                }
            }

            // Create base level
            if (myCol.baseLevel == null)
            {
                myCol.baseLevel = new SpeckleElementsClasses.Level()
                {
                    elevation = baseLine.GetEndPoint(0).Z / Scale, levelName = "Speckle Level " + baseLine.GetEndPoint(0).Z / Scale
                }
            }
            ;
            var baseLevel = myCol.baseLevel.ToNative() as Autodesk.Revit.DB.Level;

            Autodesk.Revit.DB.FamilyInstance familyInstance = null;

            if (myCol.parameters != null && myCol.parameters.ContainsKey("Column Style")) // Comes from revit
            {
                if (Convert.ToInt16(myCol.parameters["Column Style"]) == 2)               // SLANTED
                {
                    familyInstance = Doc.Create.NewFamilyInstance(baseLine, familySymbol, baseLevel, Autodesk.Revit.DB.Structure.StructuralType.Column);
                }
                else // NOT SLANTED
                {
                    familyInstance = Doc.Create.NewFamilyInstance(start, familySymbol, baseLevel, Autodesk.Revit.DB.Structure.StructuralType.Column);
                }
            }
            else // Comes from gh
            {
                if (isVertical)
                {
                    familyInstance = Doc.Create.NewFamilyInstance(start, familySymbol, baseLevel, Autodesk.Revit.DB.Structure.StructuralType.Column);
                }
                else
                {
                    familyInstance = Doc.Create.NewFamilyInstance(baseLine, familySymbol, baseLevel, Autodesk.Revit.DB.Structure.StructuralType.Column);
                }
            }


            Autodesk.Revit.DB.Level myTopLevel = null;
            // Set the top level
            if (myCol.topLevel != null)
            {
                myTopLevel = myCol.topLevel.ToNative();
                familyInstance.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_PARAM).Set(myTopLevel.Id);
            }

            SetColParams(myCol, familyInstance, baseLine, exclusions, myTopLevel, baseLevel);

            return(familyInstance);
        }
예제 #10
0
        void ReconstructBeamByCurve
        (
            DB.Document doc,
            ref DB.FamilyInstance element,

            Rhino.Geometry.Curve curve,
            Optional <DB.FamilySymbol> type,
            Optional <DB.Level> level
        )
        {
            if
            (
                curve.IsClosed ||
                !curve.IsPlanar(Revit.VertexTolerance * Revit.ModelUnits) ||
                curve.GetNextDiscontinuity(Rhino.Geometry.Continuity.C2_continuous, curve.Domain.Min, curve.Domain.Max, out var _)
            )
            {
                ThrowArgumentException(nameof(curve), "Curve must be a C2 continuous planar non closed curve.");
            }

            SolveOptionalLevel(doc, curve, ref level, out var bbox);

            var centerLine = curve.ToCurve();

            if (type.HasValue)
            {
                ChangeElementTypeId(ref element, type.Value.Id);
            }

            // Try to update Beam
            if (element is object && element.Location is DB.LocationCurve locationCurve && centerLine.IsSameKindAs(locationCurve.Curve))
            {
                var referenceLevel = element.get_Parameter(DB.BuiltInParameter.INSTANCE_REFERENCE_LEVEL_PARAM);
                var updateLevel    = referenceLevel.AsElementId() != level.Value.Id;

                if (!updateLevel || !referenceLevel.IsReadOnly)
                {
                    if (updateLevel)
                    {
                        referenceLevel.Set(level.Value.Id);
                    }

                    locationCurve.Curve = centerLine;
                    return;
                }
            }

            // Reconstruct Beam
            {
                SolveOptionalType(ref type, doc, DB.BuiltInCategory.OST_StructuralFraming, nameof(type));

                var newBeam = doc.Create.NewFamilyInstance
                              (
                    centerLine,
                    type.Value,
                    level.Value,
                    DB.Structure.StructuralType.Beam
                              );

                newBeam.get_Parameter(DB.BuiltInParameter.Y_JUSTIFICATION).Set((int)DB.Structure.YJustification.Origin);
                newBeam.get_Parameter(DB.BuiltInParameter.Z_JUSTIFICATION).Set((int)DB.Structure.ZJustification.Origin);

                if (element is object && DB.Structure.StructuralFramingUtils.IsJoinAllowedAtEnd(element, 0))
                {
                    DB.Structure.StructuralFramingUtils.AllowJoinAtEnd(newBeam, 0);
                }
                else
                {
                    DB.Structure.StructuralFramingUtils.DisallowJoinAtEnd(newBeam, 0);
                }

                if (element is object && DB.Structure.StructuralFramingUtils.IsJoinAllowedAtEnd(element, 1))
                {
                    DB.Structure.StructuralFramingUtils.AllowJoinAtEnd(newBeam, 1);
                }
                else
                {
                    DB.Structure.StructuralFramingUtils.DisallowJoinAtEnd(newBeam, 1);
                }

                var parametersMask = new DB.BuiltInParameter[]
                {
                    DB.BuiltInParameter.ELEM_FAMILY_AND_TYPE_PARAM,
                    DB.BuiltInParameter.ELEM_FAMILY_PARAM,
                    DB.BuiltInParameter.ELEM_TYPE_PARAM,
                    DB.BuiltInParameter.INSTANCE_REFERENCE_LEVEL_PARAM
                };

                ReplaceElement(ref element, newBeam, parametersMask);
            }
        }