private static void MatchFlippingAndRotation(Autodesk.Revit.DB.FamilyInstance myInstance, Column myColumn, Autodesk.Revit.DB.Curve baseLine) { // TODO: All these try catches can be replaced with if ( Dictionary.ContainsKey(LOLOLO) ) try { var handFlip = Convert.ToBoolean(myColumn.Properties["__handFlipped"]); if (handFlip != myInstance.HandFlipped) { myInstance.flipHand(); } } catch { } try { var faceFlip = Convert.ToBoolean(myColumn.Properties["__facingFlipped"]); if (faceFlip != myInstance.FacingFlipped) { myInstance.flipFacing(); } } catch { } try { // TODO: Check against existing rotation (if any) and deduct that) var rotation = Convert.ToDouble(myColumn.Properties["__rotation"]); var start = baseLine.GetEndPoint(0); var end = baseLine.GetEndPoint(1); var myLine = Autodesk.Revit.DB.Line.CreateBound(start, end); if (myInstance.Location is LocationPoint) { ((LocationPoint)myInstance.Location).Rotate(myLine, rotation - ((LocationPoint)myInstance.Location).Rotation); } //else // ElementTransformUtils.RotateElement( Doc, myInstance.Id, myLine, rotation ); } catch (Exception e) { } }
//TODO: might need to clean this up and split the ConversionLog.Addic by beam, FI, etc... public List <ApplicationPlaceholderObject> FamilyInstanceToNative(BuiltElements.Revit.FamilyInstance speckleFi) { DB.FamilySymbol familySymbol = GetElementType <FamilySymbol>(speckleFi); XYZ basePoint = PointToNative(speckleFi.basePoint); DB.Level level = LevelToNative(speckleFi.level); DB.FamilyInstance familyInstance = null; var isUpdate = false; //try update existing var docObj = GetExistingElementByApplicationId(speckleFi.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 { familyInstance = (DB.FamilyInstance)docObj; //NOTE: updating an element location is quite buggy in Revit! //Let's say the first time an element is created its base point/curve is @ 10m and the Level is @ 0m //the element will be created @ 0m //but when this element is updated (let's say with no changes), it will jump @ 10m (unless there is a level change)! //to avoid this behavior we're always setting the previous location Z coordinate when updating an element //this means the Z coord of an element will only be set by its Level //and by additional parameters as sill height, base offset etc (familyInstance.Location as LocationPoint).Point = new XYZ(basePoint.X, basePoint.Y, (familyInstance.Location as LocationPoint).Point.Z); // check for a type change if (speckleFi.type != null && speckleFi.type != revitType.Name) { familyInstance.ChangeTypeId(familySymbol.Id); } TrySetParam(familyInstance, BuiltInParameter.FAMILY_LEVEL_PARAM, level); TrySetParam(familyInstance, BuiltInParameter.FAMILY_BASE_LEVEL_PARAM, level); } isUpdate = true; } catch { //something went wrong, re-create it } } //create family instance if (familyInstance == null) { //If the current host element is not null, it means we're coming from inside a nested conversion. if (CurrentHostElement != null) { familyInstance = Doc.Create.NewFamilyInstance(basePoint, familySymbol, CurrentHostElement, level, StructuralType.NonStructural); } //Otherwise, proceed as normal. else { familyInstance = Doc.Create.NewFamilyInstance(basePoint, familySymbol, level, StructuralType.NonStructural); } } //required for face flipping to work! Doc.Regenerate(); if (familyInstance.CanFlipHand && speckleFi.handFlipped != familyInstance.HandFlipped) { familyInstance.flipHand(); } if (familyInstance.CanFlipFacing && speckleFi.facingFlipped != familyInstance.FacingFlipped) { familyInstance.flipFacing(); } // NOTE: do not check for the CanRotate prop as it doesn't work (at least on some families I tried)! // some point based families don't have a rotation, so keep this in a try catch try { if (speckleFi.rotation != (familyInstance.Location as LocationPoint).Rotation) { var axis = DB.Line.CreateBound(new XYZ(basePoint.X, basePoint.Y, 0), new XYZ(basePoint.X, basePoint.Y, 1000)); (familyInstance.Location as LocationPoint).Rotate(axis, speckleFi.rotation - (familyInstance.Location as LocationPoint).Rotation); } } catch { } SetInstanceParameters(familyInstance, speckleFi); var placeholders = new List <ApplicationPlaceholderObject>() { new ApplicationPlaceholderObject { applicationId = speckleFi.applicationId, ApplicationGeneratedId = familyInstance.UniqueId, NativeObject = familyInstance } }; Report.Log($"{(isUpdate ? "Updated" : "Created")} FamilyInstance ({familyInstance.Category.Name}) {familyInstance.Id}"); return(placeholders); }
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); bool isUpdate = false; 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); } } isUpdate = true; } catch { } } if (revitColumn == null && isLineBased) { revitColumn = Doc.Create.NewFamilyInstance(baseLine, familySymbol, level, StructuralType.Column); if (revitColumn.Symbol.Family.FamilyPlacementType == FamilyPlacementType.CurveDrivenStructural) { 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) { throw (new Exception($"Failed to create column for {speckleColumn.applicationId}.")); } 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(); } //do change offset for slanted columns, it's automatic if (!isLineBased) { SetOffsets(revitColumn, speckleRevitColumn); } SetInstanceParameters(revitColumn, speckleRevitColumn); } var placeholders = new List <ApplicationPlaceholderObject>() { new ApplicationPlaceholderObject { applicationId = speckleColumn.applicationId, ApplicationGeneratedId = revitColumn.UniqueId, NativeObject = revitColumn } }; // TODO: nested elements. Report.Log($"{(isUpdate ? "Updated" : "Created")} Column {revitColumn.Id}"); return(placeholders); }