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); }
//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); }
//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); }
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); }