public List <ApplicationPlaceholderObject> ColumnToNative(Column speckleColumn)
        {
            if (speckleColumn.baseLine == null)
            {
                throw new Speckle.Core.Logging.SpeckleException("Only line based Beams are currently supported.");
            }

            DB.FamilySymbol familySymbol = GetElementType <FamilySymbol>(speckleColumn);;
            var             baseLine     = CurveToNative(speckleColumn.baseLine).get_Item(0);

            // If the start point elevation is higher than the end point elevation, reverse the line.
            if (baseLine.GetEndPoint(0).Z > baseLine.GetEndPoint(1).Z)
            {
                baseLine = DB.Line.CreateBound(baseLine.GetEndPoint(1), baseLine.GetEndPoint(0));
            }

            DB.Level          level       = null;
            DB.Level          topLevel    = null;
            DB.FamilyInstance revitColumn = null;
            var structuralType            = StructuralType.Column;
            var isLineBased = true;

            var speckleRevitColumn = speckleColumn as RevitColumn;

            if (speckleRevitColumn != null)
            {
                level          = LevelToNative(speckleRevitColumn.level);
                topLevel       = LevelToNative(speckleRevitColumn.topLevel);
                structuralType = speckleRevitColumn.structural ? StructuralType.Column : StructuralType.NonStructural;
                //non slanted columns are point based
                isLineBased = speckleRevitColumn.isSlanted;
            }

            if (level == null)
            {
                level    = LevelToNative(LevelFromCurve(baseLine));
                topLevel = LevelToNative(LevelFromPoint(baseLine.GetEndPoint(1)));
            }

            //try update existing
            var docObj = GetExistingElementByApplicationId(speckleColumn.applicationId);

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

                    // if family changed, tough luck. delete and let us create a new one.
                    if (familySymbol.FamilyName != revitType.FamilyName)
                    {
                        Doc.Delete(docObj.Id);
                    }
                    else
                    {
                        revitColumn = (DB.FamilyInstance)docObj;
                        switch (revitColumn.Location)
                        {
                        case LocationCurve crv:
                            crv.Curve = baseLine;
                            break;

                        case LocationPoint pt:
                            pt.Point = baseLine.GetEndPoint(0);
                            break;
                        }

                        // check for a type change
                        if (!string.IsNullOrEmpty(familySymbol.FamilyName) && familySymbol.FamilyName != revitType.Name)
                        {
                            revitColumn.ChangeTypeId(familySymbol.Id);
                        }
                    }
                }
                catch { }
            }

            if (revitColumn == null && isLineBased)
            {
                revitColumn = Doc.Create.NewFamilyInstance(baseLine, familySymbol, level, structuralType);
                StructuralFramingUtils.DisallowJoinAtEnd(revitColumn, 0);
                StructuralFramingUtils.DisallowJoinAtEnd(revitColumn, 1);
            }

            //try with a point based column
            if (speckleRevitColumn != null && revitColumn == null && !isLineBased)
            {
                var start = baseLine.GetEndPoint(0);
                var end   = baseLine.GetEndPoint(1);

                var basePoint = start.Z < end.Z ? start : end; // pick the lowest
                revitColumn = Doc.Create.NewFamilyInstance(basePoint, familySymbol, level, StructuralType.NonStructural);

                //rotate, we know it must be a RevitColumn
                var axis = DB.Line.CreateBound(new XYZ(basePoint.X, basePoint.Y, 0), new XYZ(basePoint.X, basePoint.Y, 1000));
                (revitColumn.Location as LocationPoint).Rotate(axis, speckleRevitColumn.rotation - (revitColumn.Location as LocationPoint).Rotation);
            }

            if (revitColumn == null)
            {
                ConversionErrors.Add(new Exception($"Failed to create column for {speckleColumn.applicationId}."));
                return(null);
            }



            TrySetParam(revitColumn, BuiltInParameter.FAMILY_BASE_LEVEL_PARAM, level);
            TrySetParam(revitColumn, BuiltInParameter.FAMILY_TOP_LEVEL_PARAM, topLevel);


            if (speckleRevitColumn != null)
            {
                if (speckleRevitColumn.handFlipped != revitColumn.HandFlipped)
                {
                    revitColumn.flipHand();
                }

                if (speckleRevitColumn.facingFlipped != revitColumn.FacingFlipped)
                {
                    revitColumn.flipFacing();
                }

                SetOffsets(revitColumn, speckleRevitColumn);

                SetInstanceParameters(revitColumn, speckleRevitColumn);
            }

            var placeholders = new List <ApplicationPlaceholderObject>()
            {
                new ApplicationPlaceholderObject {
                    applicationId = speckleColumn.applicationId, ApplicationGeneratedId = revitColumn.UniqueId, NativeObject = revitColumn
                }
            };

            // TODO: nested elements.

            return(placeholders);
        }
Exemple #2
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);
        }
Exemple #3
0
        //TODO: delete temp family after creation
        //TODO: allow updates to family..?

        //NOTE: FaceWalls cannot be updated, as well we can't seem to get their base face easily so they are ToNatvie only
        public List <ApplicationPlaceholderObject> FaceWallToNative(RevitFaceWall speckleWall)
        {
            if (speckleWall.surface == null)
            {
                throw new Speckle.Core.Logging.SpeckleException("Only surface based FaceWalls are currently supported.");
            }

            // Cannot update revit wall to new mass face
            FaceWall revitWall = GetExistingElementByApplicationId(speckleWall.applicationId) as FaceWall;

            if (revitWall != null)
            {
                Doc.Delete(revitWall.Id);
            }

            var famPath = Path.Combine(Doc.Application.FamilyTemplatePath, @"Conceptual Mass\Metric Mass.rft");

            if (!File.Exists(famPath))
            {
                ConversionErrors.Add(new Exception($"Could not find file Metric Mass.rft"));
                return(null);
            }

            var    tempMassFamilyPath = CreateMassFamily(famPath, speckleWall.surface, speckleWall.applicationId);
            Family fam;

            Doc.LoadFamily(tempMassFamilyPath, new FamilyLoadOption(), out fam);
            var symbol = Doc.GetElement(fam.GetFamilySymbolIds().First()) as FamilySymbol;

            symbol.Activate();

            try
            {
                File.Delete(tempMassFamilyPath);
            }
            catch
            {
            }

            var mass = Doc.Create.NewFamilyInstance(XYZ.Zero, symbol, DB.Structure.StructuralType.NonStructural);
            // NOTE: must set a schedule level!
            // otherwise the wall creation will fail with "Could not create a face wall."
            var level = new FilteredElementCollector(Doc)
                        .WhereElementIsNotElementType()
                        .OfCategory(BuiltInCategory.OST_Levels) // this throws a null error if user tries to recieve stream in a file with no levels
                        .ToElements().FirstOrDefault();

            if (level == null) // create a new level at 0 if no levels could be retrieved from doc
            {
                level = Level.Create(Doc, 0);
            }

            TrySetParam(mass, BuiltInParameter.INSTANCE_SCHEDULE_ONLY_LEVEL_PARAM, level);

            //must regenerate before getting the elem geometry
            Doc.Regenerate();
            Reference faceRef = GetFaceRef(mass);

            var wallType = GetElementType <WallType>(speckleWall);

            if (!FaceWall.IsWallTypeValidForFaceWall(Doc, wallType.Id))
            {
                ConversionErrors.Add(new Exception($"Wall type not valid for face wall ${speckleWall.applicationId}."));
                return(null);
            }

            revitWall = null;
            try
            {
                revitWall = DB.FaceWall.Create(Doc, wallType.Id, GetWallLocationLine(speckleWall.locationLine), faceRef);
            }
            catch (Exception e)
            { }

            if (revitWall == null)
            {
                ConversionErrors.Add(new Exception($"Failed to create face wall ${speckleWall.applicationId}."));
                return(null);
            }

            Doc.Delete(mass.Id);

            SetInstanceParameters(revitWall, speckleWall);

            var placeholders = new List <ApplicationPlaceholderObject>()
            {
                new ApplicationPlaceholderObject
                {
                    applicationId          = speckleWall.applicationId,
                    ApplicationGeneratedId = revitWall.UniqueId,
                    NativeObject           = revitWall
                }
            };

            var hostedElements = SetHostedElements(speckleWall, revitWall);

            placeholders.AddRange(hostedElements);

            return(placeholders);
        }
Exemple #4
0
        public List <ApplicationPlaceholderObject> RailingToNative(BuiltElements.Revit.RevitRailing speckleRailing)
        {
            if (speckleRailing.path == null)
            {
                throw new Speckle.Core.Logging.SpeckleException("Only line based Railings are currently supported.");
            }

            var revitRailing = GetExistingElementByApplicationId(speckleRailing.applicationId) as Railing;

            var   railingType = GetElementType <RailingType>(speckleRailing);
            Level level       = LevelToNative(speckleRailing.level);

            //we currently don't support railings hosted on stairs, and these have null level
            if (level == null)
            {
                return(null);
            }
            var baseCurve = CurveArrayToCurveLoop(CurveToNative(speckleRailing.path));

            //if it's a new element, we don't need to update certain properties
            bool isUpdate = true;

            if (revitRailing == null)
            {
                isUpdate     = false;
                revitRailing = Railing.Create(Doc, baseCurve, railingType.Id, level.Id);
            }
            if (revitRailing == null)
            {
                ConversionErrors.Add(new Exception($"Failed to create railing ${speckleRailing.applicationId}."));
                return(null);
            }

            if (revitRailing.GetTypeId() != railingType.Id)
            {
                revitRailing.ChangeTypeId(railingType.Id);
            }

            if (isUpdate)
            {
                revitRailing.SetPath(baseCurve);
                TrySetParam(revitRailing, BuiltInParameter.WALL_BASE_CONSTRAINT, level);
            }

            if (speckleRailing.flipped != revitRailing.Flipped)
            {
                revitRailing.Flip();
            }

            SetInstanceParameters(revitRailing, speckleRailing);

            var placeholders = new List <ApplicationPlaceholderObject>()
            {
                new ApplicationPlaceholderObject
                {
                    applicationId          = speckleRailing.applicationId,
                    ApplicationGeneratedId = revitRailing.UniqueId,
                    NativeObject           = revitRailing
                }
            };

            Doc.Regenerate();

            return(placeholders);
        }