public List <ApplicationPlaceholderObject> WallToNative(BuiltElements.Wall speckleWall) { if (speckleWall.baseLine == null) { throw new Speckle.Core.Logging.SpeckleException($"Failed to create wall ${speckleWall.applicationId}. Only line based Walls are currently supported."); } var revitWall = GetExistingElementByApplicationId(speckleWall.applicationId) as DB.Wall; var wallType = GetElementType <WallType>(speckleWall); Level level = null; var structural = false; var baseCurve = CurveToNative(speckleWall.baseLine).get_Item(0); if (speckleWall is RevitWall speckleRevitWall) { level = LevelToNative(speckleRevitWall.level); structural = speckleRevitWall.structural; } else { level = LevelToNative(LevelFromCurve(baseCurve)); } //if it's a new element, we don't need to update certain properties bool isUpdate = true; if (revitWall == null) { isUpdate = false; revitWall = DB.Wall.Create(Doc, baseCurve, level.Id, structural); } if (revitWall == null) { throw new Speckle.Core.Logging.SpeckleException($"Failed to create wall ${speckleWall.applicationId}."); } //is structural update TrySetParam(revitWall, BuiltInParameter.WALL_STRUCTURAL_SIGNIFICANT, structural); if (revitWall.WallType.Name != wallType.Name) { revitWall.ChangeTypeId(wallType.Id); } if (isUpdate) { //NOTE: updating an element location can be buggy if the baseline and level elevation don't match //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 moving the base curve to match the level elevation var newz = baseCurve.GetEndPoint(0).Z; var offset = level.Elevation - newz; var newCurve = baseCurve; if (Math.Abs(offset) > 0.0164042) // level and curve are not at the same height { newCurve = baseCurve.CreateTransformed(Transform.CreateTranslation(new XYZ(0, 0, offset))); } ((LocationCurve)revitWall.Location).Curve = newCurve; TrySetParam(revitWall, BuiltInParameter.WALL_BASE_CONSTRAINT, level); } if (speckleWall is RevitWall spklRevitWall) { if (spklRevitWall.flipped != revitWall.Flipped) { revitWall.Flip(); } if (spklRevitWall.topLevel != null) { var topLevel = LevelToNative(spklRevitWall.topLevel); TrySetParam(revitWall, BuiltInParameter.WALL_HEIGHT_TYPE, topLevel); } else { TrySetParam(revitWall, BuiltInParameter.WALL_USER_HEIGHT_PARAM, speckleWall.height, speckleWall.units); } TrySetParam(revitWall, BuiltInParameter.WALL_BASE_OFFSET, spklRevitWall.baseOffset, speckleWall.units); TrySetParam(revitWall, BuiltInParameter.WALL_TOP_OFFSET, spklRevitWall.topOffset, speckleWall.units); } else // Set wall unconnected height. { TrySetParam(revitWall, BuiltInParameter.WALL_USER_HEIGHT_PARAM, speckleWall.height, speckleWall.units); } 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); Report.Log($"{(isUpdate ? "Updated" : "Created")} Wall {revitWall.Id}"); return(placeholders); }
public List <ApplicationPlaceholderObject> WallToNative(BuiltElements.Wall speckleWall) { if (speckleWall.baseLine == null) { throw new Exception("Only line based Walls are currently supported."); } var revitWall = GetExistingElementByApplicationId(speckleWall.applicationId) as DB.Wall; var wallType = GetElementType <WallType>(speckleWall); Level level = null; var structural = false; var baseCurve = CurveToNative(speckleWall.baseLine).get_Item(0); if (speckleWall is RevitWall speckleRevitWall) { level = LevelToNative(speckleRevitWall.level); structural = speckleRevitWall.structural; } else { level = LevelToNative(LevelFromCurve(baseCurve)); } //if it's a new element, we don't need to update certain properties bool isUpdate = true; if (revitWall == null) { isUpdate = false; revitWall = DB.Wall.Create(Doc, baseCurve, level.Id, structural); } if (revitWall == null) { ConversionErrors.Add(new Error { message = $"Failed to create wall ${speckleWall.applicationId}." }); return(null); } if (revitWall.WallType.Name != wallType.Name) { revitWall.ChangeTypeId(wallType.Id); } if (isUpdate) { //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 var z = ((LocationCurve)revitWall.Location).Curve.GetEndPoint(0).Z; var offsetLine = baseCurve.CreateTransformed(Transform.CreateTranslation(new XYZ(0, 0, z))); ((LocationCurve)revitWall.Location).Curve = offsetLine; TrySetParam(revitWall, BuiltInParameter.WALL_BASE_CONSTRAINT, level); } if (speckleWall is RevitWall spklRevitWall) { if (spklRevitWall.flipped != revitWall.Flipped) { revitWall.Flip(); } if (spklRevitWall.topLevel != null) { var topLevel = LevelToNative(spklRevitWall.topLevel); TrySetParam(revitWall, BuiltInParameter.WALL_HEIGHT_TYPE, topLevel); } else { TrySetParam(revitWall, BuiltInParameter.WALL_USER_HEIGHT_PARAM, speckleWall.height, speckleWall.units); } TrySetParam(revitWall, BuiltInParameter.WALL_BASE_OFFSET, spklRevitWall.baseOffset, speckleWall.units); TrySetParam(revitWall, BuiltInParameter.WALL_TOP_OFFSET, spklRevitWall.topOffset, speckleWall.units); } else // Set wall unconnected height. { TrySetParam(revitWall, BuiltInParameter.WALL_USER_HEIGHT_PARAM, speckleWall.height, speckleWall.units); } 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); }