diff --git a/Revit_Core_Engine/Create/Sheet.cs b/Revit_Core_Engine/Create/View/Sheet.cs similarity index 73% rename from Revit_Core_Engine/Create/Sheet.cs rename to Revit_Core_Engine/Create/View/Sheet.cs index 8ca84ac72..03328876f 100644 --- a/Revit_Core_Engine/Create/Sheet.cs +++ b/Revit_Core_Engine/Create/View/Sheet.cs @@ -22,7 +22,9 @@ using Autodesk.Revit.DB; using BH.oM.Base.Attributes; +using System.Collections.Generic; using System.ComponentModel; +using System.Linq; namespace BH.Revit.Engine.Core { @@ -37,42 +39,36 @@ public static partial class Create [Input("sheetName", "Name of the new sheet.")] [Input("sheetNumber", "Number of the new sheet.")] [Input("viewTemplateId", "The Title Block Id to be applied to the sheet.")] - [Output("viewSheet", "The new sheet.")] + [Output("newSheet", "The new sheet.")] public static ViewSheet Sheet(this Document document, string sheetName, string sheetNumber, ElementId titleBlockId) { - ViewSheet result = ViewSheet.Create(document, titleBlockId); + List sheetNumbersInModel = new FilteredElementCollector(document).OfClass(typeof(ViewSheet)).WhereElementIsNotElementType().Select(x => (x as ViewSheet).SheetNumber).ToList(); + ViewSheet newSheet = ViewSheet.Create(document, titleBlockId); if (!string.IsNullOrEmpty(sheetName)) { - result.Name = sheetName; + newSheet.Name = sheetName; } if (!string.IsNullOrEmpty(sheetNumber)) { int number = 0; + string uniqueNumber = sheetNumber; - while (true) + while (sheetNumbersInModel.Contains(uniqueNumber)) { - try - { - if (number != 0) - { - result.SheetNumber = $"{sheetNumber} ({number})"; - BH.Engine.Base.Compute.RecordWarning("There is already a sheet named '" + sheetNumber + "'." + " It has been named '" + result.SheetNumber + "' instead."); - break; - } + number++; + uniqueNumber = $"{sheetNumber} ({number})"; + } - result.SheetNumber = sheetNumber; - break; - } - catch - { - number++; - } + newSheet.SheetNumber = uniqueNumber; + if (uniqueNumber != sheetNumber) + { + BH.Engine.Base.Compute.RecordWarning($"There is already a sheet named '{sheetNumber}'. It has been named '{uniqueNumber}' instead."); } } - return result; + return newSheet; } /***************************************************/ diff --git a/Revit_Core_Engine/Create/View/ViewPlan.cs b/Revit_Core_Engine/Create/View/ViewPlan.cs index a929f1fab..a8edde747 100644 --- a/Revit_Core_Engine/Create/View/ViewPlan.cs +++ b/Revit_Core_Engine/Create/View/ViewPlan.cs @@ -24,6 +24,9 @@ using System; using System.ComponentModel; using BH.oM.Base.Attributes; +using System.Collections.Generic; +using System.Linq; +using Autodesk.Revit.UI; namespace BH.Revit.Engine.Core { @@ -40,36 +43,42 @@ public static partial class Create [Input("cropBox", "Optional, the crop region to attempt to apply to the newly created view.")] [Input("viewTemplateId", "Optional, the View Template Id to be applied in the view.")] [Input("viewDetailLevel", "Optional, the Detail Level of the view.")] - [Output("viewPlan", "The new view.")] - public static View ViewPlan(this Document document, Autodesk.Revit.DB.Level level, string viewName = null, CurveLoop cropBox = null, ElementId viewTemplateId = null, ViewDetailLevel viewDetailLevel = ViewDetailLevel.Coarse) + [Output("newView", "The new view.")] + public static View ViewPlan(this Document document, Level level, string viewName = null, CurveLoop cropBox = null, ElementId viewTemplateId = null, ViewDetailLevel viewDetailLevel = ViewDetailLevel.Coarse) { - View result = null; + View newView = null; - ViewFamilyType vft = Query.ViewFamilyType(document, ViewFamily.FloorPlan); + ViewFamilyType viewFamilyType = Query.ViewFamilyType(document, ViewFamily.FloorPlan); - result = Autodesk.Revit.DB.ViewPlan.Create(document, vft.Id, level.Id); + newView = Autodesk.Revit.DB.ViewPlan.Create(document, viewFamilyType.Id, level.Id); - Modify.SetViewDetailLevel(result, viewDetailLevel); + Modify.SetViewDetailLevel(newView, viewDetailLevel); if (cropBox != null) { try { - ViewCropRegionShapeManager vcrShapeMgr = result.GetCropRegionShapeManager(); - result.CropBoxVisible = true; + ViewCropRegionShapeManager vcrShapeMgr = newView.GetCropRegionShapeManager(); + newView.CropBoxVisible = true; vcrShapeMgr.SetCropShape(cropBox); } catch (Exception) { - BH.Engine.Base.Compute.RecordWarning("Could not create the Floor Plan with the provided crop box. Check if the crop box is a valid geometry and if the view's designated template accepts it to change."); + BH.Engine.Base.Compute.RecordWarning("Could not create the Floor Plan with the provided crop box. Check if the crop box is a valid geometry."); } } if (viewTemplateId != null) { + if (!(document.GetElement(viewTemplateId) as View).IsTemplate) + { + BH.Engine.Base.Compute.RecordWarning("Could not apply the View Template of Id " + viewTemplateId + "'." + ". Please check if it's a valid View Template."); + return newView; + } + try { - result.ViewTemplateId = viewTemplateId; + newView.ViewTemplateId = viewTemplateId; } catch (Exception) { @@ -79,21 +88,27 @@ public static View ViewPlan(this Document document, Autodesk.Revit.DB.Level leve if (!string.IsNullOrEmpty(viewName)) { - try + int number = 0; + string uniqueName = viewName; + + while (uniqueName.IsExistingViewName(document)) { + number++; + uniqueName = $"{viewName} ({number})"; + } + #if (REVIT2018 || REVIT2019) - result.ViewName = viewName; + newView.ViewName = uniqueName; #else - result.Name = viewName; + newView.Name = uniqueName; #endif - } - catch + if (uniqueName != viewName) { - BH.Engine.Base.Compute.RecordWarning("There is already a view named '" + viewName + "'." + " It has been named '" + result.Name + "' instead."); + BH.Engine.Base.Compute.RecordWarning($"There is already a view named '{viewName}'. It has been named '{uniqueName}' instead."); } } - return result; + return newView; } /***************************************************/ @@ -107,32 +122,32 @@ public static View ViewPlan(this Document document, Autodesk.Revit.DB.Level leve [Input("viewTemplateId", "(Optional) A View Template Id to be applied in the view.")] [Input("cropRegionVisible", "True if the crop region should be visible.")] [Input("annotationCrop", "True if the annotation crop should be visible.")] - [Output("viewPlan", "The new view.")] + [Output("newView", "The new view.")] public static View ViewPlan(this Document document, Level level, string viewName, ViewFamily viewFamily = ViewFamily.FloorPlan, ElementId scopeBoxId = null, ElementId viewTemplateId = null, bool cropRegionVisible = false, bool annotationCrop = false) { - View result = null; + View newView = null; if (!(viewFamily == ViewFamily.FloorPlan || viewFamily == ViewFamily.CeilingPlan || viewFamily == ViewFamily.AreaPlan || viewFamily == ViewFamily.StructuralPlan)) { BH.Engine.Base.Compute.RecordWarning("Could not create View of type " + viewFamily + "'." + ". It has to be a FloorPlan, CeilingPlan, AreaPlan, or StructuralPlan ViewType."); - return result; + return newView; } ViewFamilyType viewFamilyType = Query.ViewFamilyType(document, viewFamily); - result = Autodesk.Revit.DB.ViewPlan.Create(document, viewFamilyType.Id, level.Id); + newView = Autodesk.Revit.DB.ViewPlan.Create(document, viewFamilyType.Id, level.Id); if (viewTemplateId != null) { if (!(document.GetElement(viewTemplateId) as View).IsTemplate) { BH.Engine.Base.Compute.RecordWarning("Could not apply the View Template of Id " + viewTemplateId + "'." + ". Please check if it's a valid View Template."); - return result; + return newView; } try { - result.ViewTemplateId = viewTemplateId; + newView.ViewTemplateId = viewTemplateId; } catch (Exception) { @@ -143,33 +158,22 @@ public static View ViewPlan(this Document document, Level level, string viewName if (!string.IsNullOrEmpty(viewName)) { int number = 0; + string uniqueName = viewName; - while (true) + while (uniqueName.IsExistingViewName(document)) { - try - { - if (number != 0) - { -#if (REVIT2018 || REVIT2019) - result.ViewName = $"{viewName} ({number})"; -#else - result.Name = $"{viewName} ({number})"; -#endif - BH.Engine.Base.Compute.RecordWarning("There is already a view named '" + viewName + "'." + " It has been named '" + result.Name + "' instead."); - break; - } + number++; + uniqueName = $"{viewName} ({number})"; + } #if (REVIT2018 || REVIT2019) - result.ViewName = viewName; + newView.ViewName = uniqueName; #else - result.Name = viewName; + newView.Name = uniqueName; #endif - break; - } - catch - { - number++; - } + if (uniqueName != viewName) + { + BH.Engine.Base.Compute.RecordWarning($"There is already a view named '{viewName}'. It has been named '{uniqueName}' instead."); } } @@ -180,12 +184,12 @@ public static View ViewPlan(this Document document, Level level, string viewName if (!((BuiltInCategory)scopeBox.Category.Id.IntegerValue == BuiltInCategory.OST_VolumeOfInterest)) { BH.Engine.Base.Compute.RecordWarning("Could not apply the Scope Box of Id " + scopeBoxId + "'." + ". Please check if it's a valid Scope Box element."); - return result; + return newView; } try { - result.get_Parameter(BuiltInParameter.VIEWER_VOLUME_OF_INTEREST_CROP).Set(scopeBoxId); + newView.get_Parameter(BuiltInParameter.VIEWER_VOLUME_OF_INTEREST_CROP).Set(scopeBoxId); } catch (Exception) { @@ -193,11 +197,26 @@ public static View ViewPlan(this Document document, Level level, string viewName } } - result.get_Parameter(BuiltInParameter.VIEWER_CROP_REGION_VISIBLE).Set(cropRegionVisible? 1: 0); - result.get_Parameter(BuiltInParameter.VIEWER_ANNOTATION_CROP_ACTIVE).Set(annotationCrop? 1: 0); + newView.get_Parameter(BuiltInParameter.VIEWER_CROP_REGION_VISIBLE).Set(cropRegionVisible? 1: 0); + newView.get_Parameter(BuiltInParameter.VIEWER_ANNOTATION_CROP_ACTIVE).Set(annotationCrop? 1: 0); - return result; + return newView; } + + /***************************************************/ + /**** Private Methods ****/ + /***************************************************/ + + [Description("Check if given view name exists in the Revit model.")] + private static bool IsExistingViewName(this string viewName, Document document) + { + List viewNamesInModel = new FilteredElementCollector(document).OfClass(typeof(ViewPlan)).WhereElementIsNotElementType().Select(x => x.Name).ToList(); + + return viewNamesInModel.Contains(viewName); + } + + /***************************************************/ + } } diff --git a/Revit_Core_Engine/Create/View/ViewReflectedCeilingPlan.cs b/Revit_Core_Engine/Create/View/ViewReflectedCeilingPlan.cs index cdc45ee06..59a317685 100644 --- a/Revit_Core_Engine/Create/View/ViewReflectedCeilingPlan.cs +++ b/Revit_Core_Engine/Create/View/ViewReflectedCeilingPlan.cs @@ -41,35 +41,41 @@ public static partial class Create [Input("viewTemplateId", "Optional, the View Template Id to be applied in the view.")] [Input("viewDetailLevel", "Optional, the Detail Level of the view.")] [Output("viewReflectedCeilingPlan", "The new view.")] - public static View ViewReflectedCeilingPlan(this Document document, Autodesk.Revit.DB.Level level, string viewName = null, CurveLoop cropBox = null, ElementId viewTemplateId = null, ViewDetailLevel viewDetailLevel = ViewDetailLevel.Coarse) + public static View ViewReflectedCeilingPlan(this Document document, Level level, string viewName = null, CurveLoop cropBox = null, ElementId viewTemplateId = null, ViewDetailLevel viewDetailLevel = ViewDetailLevel.Coarse) { - View result = null; + View newView = null; - ViewFamilyType vft = Query.ViewFamilyType(document, ViewFamily.CeilingPlan); + ViewFamilyType viewFamilyType = Query.ViewFamilyType(document, ViewFamily.CeilingPlan); - result = Autodesk.Revit.DB.ViewPlan.Create(document, vft.Id, level.Id); + newView = Autodesk.Revit.DB.ViewPlan.Create(document, viewFamilyType.Id, level.Id); - Modify.SetViewDetailLevel(result, viewDetailLevel); + Modify.SetViewDetailLevel(newView, viewDetailLevel); if (cropBox != null) { try { - ViewCropRegionShapeManager vcrShapeMgr = result.GetCropRegionShapeManager(); - result.CropBoxVisible = true; + ViewCropRegionShapeManager vcrShapeMgr = newView.GetCropRegionShapeManager(); + newView.CropBoxVisible = true; vcrShapeMgr.SetCropShape(cropBox); } catch (Exception) { - BH.Engine.Base.Compute.RecordWarning("Could not create the Reflected Ceiling Plan with the provided crop box. Check if the crop box is a valid geometry and if the view's designated template accepts it to change."); + BH.Engine.Base.Compute.RecordWarning("Could not create the Reflected Ceiling Plan with the provided crop box. Check if the crop box is a valid geometry."); } } if (viewTemplateId != null) { + if (!(document.GetElement(viewTemplateId) as View).IsTemplate) + { + BH.Engine.Base.Compute.RecordWarning("Could not apply the View Template of Id " + viewTemplateId + "'." + ". Please check if it's a valid View Template."); + return newView; + } + try { - result.ViewTemplateId = viewTemplateId; + newView.ViewTemplateId = viewTemplateId; } catch (Exception) { @@ -79,21 +85,23 @@ public static View ViewReflectedCeilingPlan(this Document document, Autodesk.Rev if (!string.IsNullOrEmpty(viewName)) { - try + int number = 0; + string uniqueName = viewName; + + while (uniqueName.IsExistingViewName(document)) { -#if (REVIT2018 || REVIT2019) - result.ViewName = viewName; -#else - result.Name = viewName; -#endif + number++; + uniqueName = $"{viewName} ({number})"; } - catch + + newView.get_Parameter(BuiltInParameter.VIEW_NAME).Set(uniqueName); + if (uniqueName != viewName) { - BH.Engine.Base.Compute.RecordWarning("There is already a view named '" + viewName + "'." + " It has been named '" + result.Name + "' instead."); + BH.Engine.Base.Compute.RecordWarning($"There is already a view named '{viewName}'. It has been named '{uniqueName}' instead."); } } - return result; + return newView; } /***************************************************/ diff --git a/Revit_Core_Engine/Compute/PlaceViewOnSheet.cs b/Revit_Core_Engine/Create/View/Viewport.cs similarity index 88% rename from Revit_Core_Engine/Compute/PlaceViewOnSheet.cs rename to Revit_Core_Engine/Create/View/Viewport.cs index cbc7c67a6..0979252d6 100644 --- a/Revit_Core_Engine/Compute/PlaceViewOnSheet.cs +++ b/Revit_Core_Engine/Create/View/Viewport.cs @@ -27,7 +27,7 @@ namespace BH.Revit.Engine.Core { - public static partial class Compute + public static partial class Create { /***************************************************/ /**** Public methods ****/ @@ -41,9 +41,9 @@ public static partial class Compute [Input("viewportPlacementPoint", "Placement point of the viewport on the sheet.")] [Input("viewportRotation", "Rotation type of the viewport. The default is None.")] [Output("viewPort", "The new viewport.")] - public static Viewport PlaceViewOnSheet (this Document document, ViewSheet sheet, View view, ElementId viewportTypeId, XYZ viewportPlacementPoint = null, ViewportRotation viewportRotation = ViewportRotation.None) + public static Viewport Viewport (this Document document, ViewSheet sheet, View view, ElementId viewportTypeId, XYZ viewportPlacementPoint = null, ViewportRotation viewportRotation = ViewportRotation.None) { - Viewport viewPort = Viewport.Create(document, sheet.Id, view.Id, viewportPlacementPoint); + Viewport viewPort = Autodesk.Revit.DB.Viewport.Create(document, sheet.Id, view.Id, viewportPlacementPoint); if (viewPort == null) { diff --git a/Revit_Core_Engine/Query/DrawingArea.cs b/Revit_Core_Engine/Query/DrawingArea.cs index 34be29f3b..5b9c52305 100644 --- a/Revit_Core_Engine/Query/DrawingArea.cs +++ b/Revit_Core_Engine/Query/DrawingArea.cs @@ -46,11 +46,11 @@ public static Outline DrawingArea(this Document document, FamilySymbol titleBloc Document familyDoc = document.EditFamily(titleBlock.Family); List lines = new FilteredElementCollector(familyDoc).OfCategory(Autodesk.Revit.DB.BuiltInCategory.OST_Lines).WhereElementIsNotElementType().Where(x => x is DetailLine).Cast().ToList(); - var compositeGeom = new BH.oM.Geometry.CompositeGeometry(); + var compositeGeom = new CompositeGeometry(); foreach (DetailLine dLine in lines) { - var bhomLine = (dLine.Location as LocationCurve).Curve.IFromRevit() as BH.oM.Geometry.Line; + var bhomLine = dLine.GeometryCurve.IFromRevit() as BH.oM.Geometry.Line; compositeGeom.Elements.Add(bhomLine); }