From ad1eea98535937dfb7156fc9c2012129a421c779 Mon Sep 17 00:00:00 2001 From: Michal Pekacki Date: Tue, 11 Jul 2023 16:52:03 +0200 Subject: [PATCH 01/10] align viewport method created --- Revit_Core_Engine/Query/AlignViewports.cs | 146 ++++++++++++++++++++++ Revit_oM/Enums/AlignViewDirection.cs | 40 ++++++ 2 files changed, 186 insertions(+) create mode 100644 Revit_Core_Engine/Query/AlignViewports.cs create mode 100644 Revit_oM/Enums/AlignViewDirection.cs diff --git a/Revit_Core_Engine/Query/AlignViewports.cs b/Revit_Core_Engine/Query/AlignViewports.cs new file mode 100644 index 000000000..ebfba3dce --- /dev/null +++ b/Revit_Core_Engine/Query/AlignViewports.cs @@ -0,0 +1,146 @@ +/* + * This file is part of the Buildings and Habitats object Model (BHoM) + * Copyright (c) 2015 - 2023, the respective contributors. All rights reserved. + * + * Each contributor holds copyright over their respective contributions. + * The project versioning (Git) records all such contribution source information. + * + * + * The BHoM is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3.0 of the License, or + * (at your option) any later version. + * + * The BHoM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this code. If not, see . + */ + +using Autodesk.Revit.DB; +using BH.Engine.Adapters.Revit; +using BH.Engine.Geometry; +using BH.oM.Adapters.Revit.Settings; +using BH.oM.Geometry; +using BH.oM.Physical.Elements; +using BH.oM.Base; +using System; +using System.ComponentModel; +using BH.oM.Base.Attributes; +using System.Collections.Generic; +using BH.oM.Revit.Enums; +using System.Linq; + +namespace BH.Revit.Engine.Core +{ + public static partial class Query + { + /***************************************************/ + /**** Public methods ****/ + /***************************************************/ + + [Description("Finds the location curve that should be assigned to the Revit FamilyInstance representing a framing element in order to make this instance's centroid overlap with the centreline of a given BHoM framing element, taken all offsets and justifications into account.")] + [Input("framingElement", "BHoM framing element to align the Revit framing to.")] + [Output("curve", "Location curve for the input Revit FamilyInstance that aligns its centreline to the input BHoM framing element.")] + public static List AlignViewports(this Outline drawingArea, List viewports, out Outline totalOutline, double borderOffset = 0.1, double viewportOffset = 0.1, AlignViewDirection direction = AlignViewDirection.Right) + { + int rows = 1; + Outline rowOutline; + List viewportPoints = AlignViewportsInRow(drawingArea, viewports, out rowOutline, borderOffset, viewportOffset, direction); + totalOutline = new Outline(rowOutline); + + while (totalOutline.MaximumPoint.X > drawingArea.MaximumPoint.X) + { + rows++; + + double totalOutlineMinX = double.MaxValue; + double totalOutlineMinY = double.MaxValue; + double totalOutlineMaxX = double.MinValue; + double totalOutlineMaxY = double.MinValue; + + Outline newDrawingArea = new Outline(drawingArea); + viewportPoints = new List(); + + int chunkSize = (int)Math.Ceiling((double)viewports.Count / rows); + List> listOfViewports = viewports + .Select((value, index) => new { Index = index, Value = value }) + .GroupBy(x => x.Index / chunkSize) + .Select(group => group.Select(x => x.Value).ToList()) + .ToList(); + + foreach (List viewportsInRow in listOfViewports) + { + viewportPoints.AddRange(AlignViewportsInRow(newDrawingArea, viewportsInRow, out rowOutline, borderOffset, viewportOffset, direction)); + + if (rowOutline.MinimumPoint.X < totalOutlineMinX) + totalOutlineMinX = rowOutline.MinimumPoint.X; + if (rowOutline.MinimumPoint.Y < totalOutlineMinY) + totalOutlineMinY = rowOutline.MinimumPoint.Y; + if (rowOutline.MaximumPoint.X > totalOutlineMaxX) + totalOutlineMaxX = rowOutline.MaximumPoint.X; + if (rowOutline.MaximumPoint.Y > totalOutlineMaxY) + totalOutlineMaxY = rowOutline.MaximumPoint.Y; + + XYZ newDrawingAreaMaxPoint = new XYZ(totalOutlineMaxX, totalOutlineMinY, 0); + newDrawingArea = new Outline(newDrawingArea.MinimumPoint, newDrawingAreaMaxPoint); + } + + XYZ totalOutlineMinPoint = new XYZ(totalOutlineMinX, totalOutlineMinY, 0); + XYZ totalOutlineMaxPoint = new XYZ(totalOutlineMaxX, totalOutlineMaxY, 0); + + totalOutline = new Outline(totalOutlineMinPoint, totalOutlineMaxPoint); + } + + return viewportPoints; + } + + /***************************************************/ + + [Description("Finds the location curve that should be assigned to the Revit FamilyInstance representing a framing element in order to make this instance's centroid overlap with the centreline of a given BHoM framing element, taken all offsets and justifications into account.")] + [Input("framingElement", "BHoM framing element to align the Revit framing to.")] + [Output("curve", "Location curve for the input Revit FamilyInstance that aligns its centreline to the input BHoM framing element.")] + public static List AlignViewportsInRow(this Outline drawingArea, List viewports, out Outline totalOutline, double borderOffset = 0.1, double viewportOffset = 0.1, AlignViewDirection direction = AlignViewDirection.Right) + { + //topleft point of drawing area with border offset + XYZ topLeftPoint = new XYZ(drawingArea.MinimumPoint.X + borderOffset, drawingArea.MaximumPoint.Y - borderOffset, 0); + List viewportCenterPoints = new List(); + + XYZ viewportsTotalMinPoint = new XYZ(); + XYZ viewportsTotalMaxPoint = new XYZ(); + + for (int i = 0; i < viewports.Count; i++) + { + Viewport viewport = viewports[i]; + Outline viewportOutline = viewport.GetBoxOutline(); + double viewportWidth = viewportOutline.MaximumPoint.X - viewportOutline.MinimumPoint.X; + double viewportHeight = viewportOutline.MaximumPoint.Y - viewportOutline.MinimumPoint.Y; + double viewportCenterX; + + if (i == 0) + { + viewportCenterX = topLeftPoint.X + viewportWidth / 2; + viewportsTotalMinPoint = new XYZ(topLeftPoint.X, topLeftPoint.Y - viewportHeight, 0); + } + else + viewportCenterX = topLeftPoint.X + viewportOffset + viewportWidth / 2; + + double viewportCenterY = topLeftPoint.Y - viewportHeight / 2; + XYZ viewportPoint = new XYZ(viewportCenterX, viewportCenterY, 0); + viewportCenterPoints.Add(viewportPoint); + + topLeftPoint = new XYZ(viewportCenterX + viewportWidth / 2, viewportCenterY + viewportHeight / 2, 0); + viewportsTotalMaxPoint = new XYZ(viewportPoint.X + viewportWidth / 2, viewportPoint.Y + viewportHeight / 2, 0); + } + + totalOutline = new Outline(viewportsTotalMinPoint, viewportsTotalMaxPoint); + + return viewportCenterPoints; + } + + /***************************************************/ + } +} + diff --git a/Revit_oM/Enums/AlignViewDirection.cs b/Revit_oM/Enums/AlignViewDirection.cs new file mode 100644 index 000000000..a3e90b3e7 --- /dev/null +++ b/Revit_oM/Enums/AlignViewDirection.cs @@ -0,0 +1,40 @@ +/* + * This file is part of the Buildings and Habitats object Model (BHoM) + * Copyright (c) 2015 - 2023, the respective contributors. All rights reserved. + * + * Each contributor holds copyright over their respective contributions. + * The project versioning (Git) records all such contribution source information. + * + * + * The BHoM is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3.0 of the License, or + * (at your option) any later version. + * + * The BHoM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this code. If not, see . + */ + +using System.ComponentModel; + +namespace BH.oM.Revit.Enums +{ + /***************************************************/ + + [Description("Enumerator defining the way in which two strings are compared.")] + public enum AlignViewDirection + { + Right, + Down + } + + /***************************************************/ +} + + + From 8a371759f2c6e0fc879f913748d98c5340e6afc2 Mon Sep 17 00:00:00 2001 From: Michal Pekacki Date: Wed, 12 Jul 2023 12:39:43 +0200 Subject: [PATCH 02/10] outline private methods added --- Revit_Core_Engine/Query/AlignViewports.cs | 106 ++++++++++++---------- 1 file changed, 60 insertions(+), 46 deletions(-) diff --git a/Revit_Core_Engine/Query/AlignViewports.cs b/Revit_Core_Engine/Query/AlignViewports.cs index ebfba3dce..8e21747e6 100644 --- a/Revit_Core_Engine/Query/AlignViewports.cs +++ b/Revit_Core_Engine/Query/AlignViewports.cs @@ -48,19 +48,19 @@ public static partial class Query public static List AlignViewports(this Outline drawingArea, List viewports, out Outline totalOutline, double borderOffset = 0.1, double viewportOffset = 0.1, AlignViewDirection direction = AlignViewDirection.Right) { int rows = 1; - Outline rowOutline; - List viewportPoints = AlignViewportsInRow(drawingArea, viewports, out rowOutline, borderOffset, viewportOffset, direction); + + XYZ borderOffsetVec = new XYZ(borderOffset, borderOffset, 0); + drawingArea.MinimumPoint += borderOffsetVec; + drawingArea.MaximumPoint -= borderOffsetVec; + + List viewportPoints = AlignViewportsInRow(drawingArea, viewports, out Outline rowOutline, viewportOffset, direction); totalOutline = new Outline(rowOutline); while (totalOutline.MaximumPoint.X > drawingArea.MaximumPoint.X) { rows++; - double totalOutlineMinX = double.MaxValue; - double totalOutlineMinY = double.MaxValue; - double totalOutlineMaxX = double.MinValue; - double totalOutlineMaxY = double.MinValue; - + totalOutline = null; Outline newDrawingArea = new Outline(drawingArea); viewportPoints = new List(); @@ -73,43 +73,28 @@ public static List AlignViewports(this Outline drawingArea, List foreach (List viewportsInRow in listOfViewports) { - viewportPoints.AddRange(AlignViewportsInRow(newDrawingArea, viewportsInRow, out rowOutline, borderOffset, viewportOffset, direction)); - - if (rowOutline.MinimumPoint.X < totalOutlineMinX) - totalOutlineMinX = rowOutline.MinimumPoint.X; - if (rowOutline.MinimumPoint.Y < totalOutlineMinY) - totalOutlineMinY = rowOutline.MinimumPoint.Y; - if (rowOutline.MaximumPoint.X > totalOutlineMaxX) - totalOutlineMaxX = rowOutline.MaximumPoint.X; - if (rowOutline.MaximumPoint.Y > totalOutlineMaxY) - totalOutlineMaxY = rowOutline.MaximumPoint.Y; - - XYZ newDrawingAreaMaxPoint = new XYZ(totalOutlineMaxX, totalOutlineMinY, 0); + viewportPoints.AddRange(AlignViewportsInRow(newDrawingArea, viewportsInRow, out rowOutline, viewportOffset, direction)); + totalOutline = totalOutline.Add(rowOutline); + + XYZ newDrawingAreaMaxPoint = new XYZ(totalOutline.MaximumPoint.X, totalOutline.MinimumPoint.Y - viewportOffset, 0); newDrawingArea = new Outline(newDrawingArea.MinimumPoint, newDrawingAreaMaxPoint); } - - XYZ totalOutlineMinPoint = new XYZ(totalOutlineMinX, totalOutlineMinY, 0); - XYZ totalOutlineMaxPoint = new XYZ(totalOutlineMaxX, totalOutlineMaxY, 0); - - totalOutline = new Outline(totalOutlineMinPoint, totalOutlineMaxPoint); } return viewportPoints; } + /***************************************************/ + /**** Private methods ****/ /***************************************************/ - [Description("Finds the location curve that should be assigned to the Revit FamilyInstance representing a framing element in order to make this instance's centroid overlap with the centreline of a given BHoM framing element, taken all offsets and justifications into account.")] - [Input("framingElement", "BHoM framing element to align the Revit framing to.")] - [Output("curve", "Location curve for the input Revit FamilyInstance that aligns its centreline to the input BHoM framing element.")] - public static List AlignViewportsInRow(this Outline drawingArea, List viewports, out Outline totalOutline, double borderOffset = 0.1, double viewportOffset = 0.1, AlignViewDirection direction = AlignViewDirection.Right) + [Description("Return center points of viewports in the given direction.")] + private static List AlignViewportsInRow(this Outline drawingArea, List viewports, out Outline totalOutline, double viewportOffset = 0.1, AlignViewDirection direction = AlignViewDirection.Right) { //topleft point of drawing area with border offset - XYZ topLeftPoint = new XYZ(drawingArea.MinimumPoint.X + borderOffset, drawingArea.MaximumPoint.Y - borderOffset, 0); - List viewportCenterPoints = new List(); - - XYZ viewportsTotalMinPoint = new XYZ(); - XYZ viewportsTotalMaxPoint = new XYZ(); + XYZ topLeftPoint = new XYZ(drawingArea.MinimumPoint.X, drawingArea.MaximumPoint.Y, 0); + List viewportNewCenterPoints = new List(); + totalOutline = null; for (int i = 0; i < viewports.Count; i++) { @@ -117,27 +102,56 @@ public static List AlignViewportsInRow(this Outline drawingArea, List Date: Thu, 13 Jul 2023 10:47:57 +0200 Subject: [PATCH 03/10] grouping viewports updated --- Revit_Core_Engine/Query/AlignViewports.cs | 113 ++++++++++++++---- ...ction.cs => ViewportAlignmentDirection.cs} | 6 +- 2 files changed, 90 insertions(+), 29 deletions(-) rename Revit_oM/Enums/{AlignViewDirection.cs => ViewportAlignmentDirection.cs} (95%) diff --git a/Revit_Core_Engine/Query/AlignViewports.cs b/Revit_Core_Engine/Query/AlignViewports.cs index 8e21747e6..0dac547aa 100644 --- a/Revit_Core_Engine/Query/AlignViewports.cs +++ b/Revit_Core_Engine/Query/AlignViewports.cs @@ -45,41 +45,84 @@ public static partial class Query [Description("Finds the location curve that should be assigned to the Revit FamilyInstance representing a framing element in order to make this instance's centroid overlap with the centreline of a given BHoM framing element, taken all offsets and justifications into account.")] [Input("framingElement", "BHoM framing element to align the Revit framing to.")] [Output("curve", "Location curve for the input Revit FamilyInstance that aligns its centreline to the input BHoM framing element.")] - public static List AlignViewports(this Outline drawingArea, List viewports, out Outline totalOutline, double borderOffset = 0.1, double viewportOffset = 0.1, AlignViewDirection direction = AlignViewDirection.Right) + public static List AlignViewports(this Outline drawingArea, List viewports, double borderOffset, double viewportOffset, ViewportAlignmentDirection direction, out Outline totalOutline) { - int rows = 1; + List viewportPoints = new List(); + totalOutline = null; + //add border offset to drawing area XYZ borderOffsetVec = new XYZ(borderOffset, borderOffset, 0); drawingArea.MinimumPoint += borderOffsetVec; drawingArea.MaximumPoint -= borderOffsetVec; + + if (direction == ViewportAlignmentDirection.Horizontal) + { + //group viewports in rows + List pendingViewports = viewports; + List> listOfViewports = new List>(); - List viewportPoints = AlignViewportsInRow(drawingArea, viewports, out Outline rowOutline, viewportOffset, direction); - totalOutline = new Outline(rowOutline); + while (pendingViewports.Count > 0) + { + List rowViewports = pendingViewports; + AlignViewportsInRow(drawingArea, rowViewports, viewportOffset, direction, out Outline rowOutline); - while (totalOutline.MaximumPoint.X > drawingArea.MaximumPoint.X) - { - rows++; + while (rowOutline.MaximumPoint.X > drawingArea.MaximumPoint.X) + { + rowViewports = rowViewports.Take(rowViewports.Count - 1).ToList(); + AlignViewportsInRow(drawingArea, rowViewports, viewportOffset, direction, out rowOutline); + } + listOfViewports.Add(rowViewports); + pendingViewports = pendingViewports.Skip(rowViewports.Count).ToList(); + } + + //get viewport center points totalOutline = null; Outline newDrawingArea = new Outline(drawingArea); - viewportPoints = new List(); - - int chunkSize = (int)Math.Ceiling((double)viewports.Count / rows); - List> listOfViewports = viewports - .Select((value, index) => new { Index = index, Value = value }) - .GroupBy(x => x.Index / chunkSize) - .Select(group => group.Select(x => x.Value).ToList()) - .ToList(); foreach (List viewportsInRow in listOfViewports) { - viewportPoints.AddRange(AlignViewportsInRow(newDrawingArea, viewportsInRow, out rowOutline, viewportOffset, direction)); + viewportPoints.AddRange(AlignViewportsInRow(newDrawingArea, viewportsInRow, viewportOffset, direction, out Outline rowOutline)); totalOutline = totalOutline.Add(rowOutline); XYZ newDrawingAreaMaxPoint = new XYZ(totalOutline.MaximumPoint.X, totalOutline.MinimumPoint.Y - viewportOffset, 0); newDrawingArea = new Outline(newDrawingArea.MinimumPoint, newDrawingAreaMaxPoint); } } + else if (direction == ViewportAlignmentDirection.Vertical) + { + //group viewports in rows + List pendingViewports = viewports; + List> listOfViewports = new List>(); + + while (pendingViewports.Count > 0) + { + List rowViewports = pendingViewports; + AlignViewportsInRow(drawingArea, rowViewports, viewportOffset, direction, out Outline rowOutline); + + while (rowOutline.MinimumPoint.Y < drawingArea.MinimumPoint.Y) + { + rowViewports = rowViewports.Take(rowViewports.Count - 1).ToList(); + AlignViewportsInRow(drawingArea, rowViewports, viewportOffset, direction, out rowOutline); + } + + listOfViewports.Add(rowViewports); + pendingViewports = pendingViewports.Skip(rowViewports.Count).ToList(); + } + + //get viewport center points + totalOutline = null; + Outline newDrawingArea = new Outline(drawingArea); + + foreach (List viewportsInRow in listOfViewports) + { + viewportPoints.AddRange(AlignViewportsInRow(newDrawingArea, viewportsInRow, viewportOffset, direction, out Outline rowOutline)); + totalOutline = totalOutline.Add(rowOutline); + + XYZ newDrawingAreaMinPoint = new XYZ(totalOutline.MaximumPoint.X + viewportOffset, totalOutline.MinimumPoint.Y, 0); + newDrawingArea = new Outline(newDrawingAreaMinPoint, newDrawingArea.MaximumPoint); + } + } return viewportPoints; } @@ -89,7 +132,7 @@ public static List AlignViewports(this Outline drawingArea, List /***************************************************/ [Description("Return center points of viewports in the given direction.")] - private static List AlignViewportsInRow(this Outline drawingArea, List viewports, out Outline totalOutline, double viewportOffset = 0.1, AlignViewDirection direction = AlignViewDirection.Right) + private static List AlignViewportsInRow(this Outline drawingArea, List viewports, double viewportOffset, ViewportAlignmentDirection direction, out Outline totalOutline) { //topleft point of drawing area with border offset XYZ topLeftPoint = new XYZ(drawingArea.MinimumPoint.X, drawingArea.MaximumPoint.Y, 0); @@ -102,18 +145,36 @@ private static List AlignViewportsInRow(this Outline drawingArea, List Date: Thu, 13 Jul 2023 13:25:43 +0200 Subject: [PATCH 04/10] organize outlines in row method created --- Revit_Core_Engine/Query/AlignViewports.cs | 99 ++++++++++++++++------- 1 file changed, 71 insertions(+), 28 deletions(-) diff --git a/Revit_Core_Engine/Query/AlignViewports.cs b/Revit_Core_Engine/Query/AlignViewports.cs index 0dac547aa..88de9fb3c 100644 --- a/Revit_Core_Engine/Query/AlignViewports.cs +++ b/Revit_Core_Engine/Query/AlignViewports.cs @@ -134,58 +134,78 @@ public static List AlignViewports(this Outline drawingArea, List [Description("Return center points of viewports in the given direction.")] private static List AlignViewportsInRow(this Outline drawingArea, List viewports, double viewportOffset, ViewportAlignmentDirection direction, out Outline totalOutline) { - //topleft point of drawing area with border offset XYZ topLeftPoint = new XYZ(drawingArea.MinimumPoint.X, drawingArea.MaximumPoint.Y, 0); - List viewportNewCenterPoints = new List(); - totalOutline = null; + List viewportOutlines = viewports.Select(x => x.GetBoxOutline()).ToList(); + List alignedOutlines = viewportOutlines.OrganizeOutlinesInRow(topLeftPoint, viewportOffset, direction); + List viewportCenterPoints = alignedOutlines.Select(x => x.CenterPoint()).ToList(); + totalOutline = alignedOutlines.Bounds(); + + return viewportCenterPoints; + } + + /***************************************************/ + + private static List OrganizeOutlinesInRow(this List outlines, XYZ topLeftPoint, double offset, ViewportAlignmentDirection direction) + { + List outlinesInRow = new List(); - for (int i = 0; i < viewports.Count; i++) + for (int i = 0; i < outlines.Count; i++) { - Viewport viewport = viewports[i]; - Outline viewportOutline = viewport.GetBoxOutline(); - double viewportWidth = viewportOutline.MaximumPoint.X - viewportOutline.MinimumPoint.X; - double viewportHeight = viewportOutline.MaximumPoint.Y - viewportOutline.MinimumPoint.Y; - XYZ viewportNewCenterPoint = new XYZ(); + Outline outline = outlines[i]; + double outlineWidth = outline.MaximumPoint.X - outline.MinimumPoint.X; + double outlineHeight = outline.MaximumPoint.Y - outline.MinimumPoint.Y; if (direction == ViewportAlignmentDirection.Horizontal) { - double viewportNewCenterX; + double outlineTopLeftX; if (i == 0) - viewportNewCenterX = topLeftPoint.X + viewportWidth / 2; + outlineTopLeftX = topLeftPoint.X; else - viewportNewCenterX = topLeftPoint.X + viewportOffset + viewportWidth / 2; + outlineTopLeftX = topLeftPoint.X + offset; + + double outlineTopLeftY = topLeftPoint.Y; - double viewportNewCenterY = topLeftPoint.Y - viewportHeight / 2; - viewportNewCenterPoint = new XYZ(viewportNewCenterX, viewportNewCenterY, 0); - topLeftPoint = new XYZ(viewportNewCenterPoint.X + viewportWidth / 2, viewportNewCenterPoint.Y + viewportHeight / 2, 0); + XYZ outlineNewCenterPoint = new XYZ(outlineTopLeftX + outlineWidth / 2, outlineTopLeftY - outlineHeight / 2, 0); + outline = outline.MovedToCenterPoint(outlineNewCenterPoint); + outlinesInRow.Add(outline); + + topLeftPoint = new XYZ(outlineTopLeftX + outlineWidth, outlineTopLeftY, 0); } else if (direction == ViewportAlignmentDirection.Vertical) { - double viewportNewCenterX = topLeftPoint.X + viewportWidth / 2; - double viewportNewCenterY; + double outlineTopLeftX = topLeftPoint.X; + double outlineTopLeftY; if (i == 0) - viewportNewCenterY = topLeftPoint.Y - viewportHeight / 2; + outlineTopLeftY = topLeftPoint.Y; else - viewportNewCenterY = topLeftPoint.Y - viewportOffset - viewportHeight / 2; + outlineTopLeftY = topLeftPoint.Y - offset; - viewportNewCenterPoint = new XYZ(viewportNewCenterX, viewportNewCenterY, 0); - topLeftPoint = new XYZ(viewportNewCenterPoint.X - viewportWidth / 2, viewportNewCenterPoint.Y - viewportHeight / 2, 0); - } - - viewportNewCenterPoints.Add(viewportNewCenterPoint); + XYZ outlineNewCenterPoint = new XYZ(outlineTopLeftX + outlineWidth / 2, outlineTopLeftY - outlineHeight / 2, 0); + outline = outline.MovedToCenterPoint(outlineNewCenterPoint); + outlinesInRow.Add(outline); - viewportOutline = MovedToPoint(viewportOutline, viewportNewCenterPoint); - totalOutline = totalOutline.Add(viewportOutline); + topLeftPoint = new XYZ(outlineTopLeftX, outlineTopLeftY - outlineHeight, 0); + } } - return viewportNewCenterPoints; + return outlinesInRow; + } + + /***************************************************/ + + private static XYZ CenterPoint(this Outline outline) + { + double centerX = outline.MinimumPoint.X + (outline.MaximumPoint.X - outline.MinimumPoint.X) / 2; + double centerY = outline.MinimumPoint.Y + (outline.MaximumPoint.Y - outline.MinimumPoint.Y) / 2; + + return new XYZ(centerX, centerY, 0); } /***************************************************/ - private static Outline MovedToPoint(this Outline outline, XYZ centerPoint) + private static Outline MovedToCenterPoint(this Outline outline, XYZ centerPoint) { double outlineWidth = outline.MaximumPoint.X - outline.MinimumPoint.X; double outlineHeight = outline.MaximumPoint.Y - outline.MinimumPoint.Y; @@ -199,6 +219,29 @@ private static Outline MovedToPoint(this Outline outline, XYZ centerPoint) /***************************************************/ + private static Outline Bounds(this List outlines) + { + double minX = double.MaxValue; + double minY = double.MaxValue; + double maxX = double.MinValue; + double maxY = double.MinValue; + + foreach (Outline outline in outlines) + { + minX = Math.Min(outline.MinimumPoint.X, minX); + minY = Math.Min(outline.MinimumPoint.Y, minY); + maxX = Math.Max(outline.MaximumPoint.X, maxX); + maxY = Math.Max(outline.MaximumPoint.Y, maxY); + } + + XYZ minPoint = new XYZ(minX, minY, 0); + XYZ maxPoint = new XYZ(maxX, maxY, 0); + + return new Outline(minPoint, maxPoint); + } + + /***************************************************/ + private static Outline Add(this Outline outline, Outline outlineToAdd) { if (outline == null) From 637521a1744cb83903dc0c1c2f2808f05cf70858 Mon Sep 17 00:00:00 2001 From: Michal Pekacki Date: Thu, 13 Jul 2023 14:49:59 +0200 Subject: [PATCH 05/10] update methods for vertical alignment --- Revit_Core_Engine/Query/AlignViewports.cs | 155 +++++++++++++--------- 1 file changed, 89 insertions(+), 66 deletions(-) diff --git a/Revit_Core_Engine/Query/AlignViewports.cs b/Revit_Core_Engine/Query/AlignViewports.cs index 88de9fb3c..d15a6f2eb 100644 --- a/Revit_Core_Engine/Query/AlignViewports.cs +++ b/Revit_Core_Engine/Query/AlignViewports.cs @@ -33,6 +33,8 @@ using System.Collections.Generic; using BH.oM.Revit.Enums; using System.Linq; +using BH.oM.Structure.Offsets; +using BH.oM.Structure.Results; namespace BH.Revit.Engine.Core { @@ -47,105 +49,126 @@ public static partial class Query [Output("curve", "Location curve for the input Revit FamilyInstance that aligns its centreline to the input BHoM framing element.")] public static List AlignViewports(this Outline drawingArea, List viewports, double borderOffset, double viewportOffset, ViewportAlignmentDirection direction, out Outline totalOutline) { - List viewportPoints = new List(); - totalOutline = null; - //add border offset to drawing area XYZ borderOffsetVec = new XYZ(borderOffset, borderOffset, 0); drawingArea.MinimumPoint += borderOffsetVec; drawingArea.MaximumPoint -= borderOffsetVec; - - if (direction == ViewportAlignmentDirection.Horizontal) - { - //group viewports in rows - List pendingViewports = viewports; - List> listOfViewports = new List>(); - while (pendingViewports.Count > 0) - { - List rowViewports = pendingViewports; - AlignViewportsInRow(drawingArea, rowViewports, viewportOffset, direction, out Outline rowOutline); + List viewportOutlines = viewports.Select(x => x.GetBoxOutline()).ToList(); + List alignedOutlines = drawingArea.AlignOutlines(viewportOutlines, viewportOffset, direction); + List viewportCenterPoints = alignedOutlines.Select(x => x.CenterPoint()).ToList(); + totalOutline = alignedOutlines.Bounds(); - while (rowOutline.MaximumPoint.X > drawingArea.MaximumPoint.X) - { - rowViewports = rowViewports.Take(rowViewports.Count - 1).ToList(); - AlignViewportsInRow(drawingArea, rowViewports, viewportOffset, direction, out rowOutline); - } + return viewportCenterPoints; + } - listOfViewports.Add(rowViewports); - pendingViewports = pendingViewports.Skip(rowViewports.Count).ToList(); - } + /***************************************************/ + /**** Private methods ****/ + /***************************************************/ - //get viewport center points - totalOutline = null; - Outline newDrawingArea = new Outline(drawingArea); + private static List AlignOutlines(this Outline drawingArea, List outlines, double offset, ViewportAlignmentDirection direction) + { + List alignedOutlines = new List(); + XYZ topLeftPoint = new XYZ(drawingArea.MinimumPoint.X, drawingArea.MaximumPoint.Y, 0); - foreach (List viewportsInRow in listOfViewports) + if (direction == ViewportAlignmentDirection.Horizontal) + { + //group outlines into rows + List> listOfOutlines = DivideOutlinesInRows(drawingArea, outlines, offset, direction); + + //align outline by rows + XYZ newTopLeftPoint = topLeftPoint; + foreach (List outlinesInRow in listOfOutlines) { - viewportPoints.AddRange(AlignViewportsInRow(newDrawingArea, viewportsInRow, viewportOffset, direction, out Outline rowOutline)); - totalOutline = totalOutline.Add(rowOutline); + List alignedOutlinesInRow = outlinesInRow.OutlinesInRow(newTopLeftPoint, offset, direction); + alignedOutlines.AddRange(alignedOutlinesInRow); + Outline rowOutlinesBound = alignedOutlinesInRow.Bounds(); - XYZ newDrawingAreaMaxPoint = new XYZ(totalOutline.MaximumPoint.X, totalOutline.MinimumPoint.Y - viewportOffset, 0); - newDrawingArea = new Outline(newDrawingArea.MinimumPoint, newDrawingAreaMaxPoint); + newTopLeftPoint = new XYZ(rowOutlinesBound.MinimumPoint.X, rowOutlinesBound.MinimumPoint.Y - offset, 0); } } else if (direction == ViewportAlignmentDirection.Vertical) { - //group viewports in rows - List pendingViewports = viewports; - List> listOfViewports = new List>(); + //group outlines into rows + List> listOfOutlines = DivideOutlinesInRows(drawingArea, outlines, offset, direction); - while (pendingViewports.Count > 0) + //align outline by rows + XYZ newTopLeftPoint = topLeftPoint; + foreach (List outlinesInRow in listOfOutlines) { - List rowViewports = pendingViewports; - AlignViewportsInRow(drawingArea, rowViewports, viewportOffset, direction, out Outline rowOutline); + List alignedOutlinesInRow = outlinesInRow.OutlinesInRow(newTopLeftPoint, offset, direction); + alignedOutlines.AddRange(alignedOutlinesInRow); + Outline rowOutlinesBound = alignedOutlinesInRow.Bounds(); - while (rowOutline.MinimumPoint.Y < drawingArea.MinimumPoint.Y) - { - rowViewports = rowViewports.Take(rowViewports.Count - 1).ToList(); - AlignViewportsInRow(drawingArea, rowViewports, viewportOffset, direction, out rowOutline); - } - - listOfViewports.Add(rowViewports); - pendingViewports = pendingViewports.Skip(rowViewports.Count).ToList(); + newTopLeftPoint = new XYZ(rowOutlinesBound.MaximumPoint.X + offset, rowOutlinesBound.MaximumPoint.Y, 0); } + } - //get viewport center points - totalOutline = null; - Outline newDrawingArea = new Outline(drawingArea); + return alignedOutlines; + } + + /***************************************************/ - foreach (List viewportsInRow in listOfViewports) + private static List> DivideOutlinesInRows(this Outline drawingArea, List outlines, double offset, ViewportAlignmentDirection direction) + { + List> listOfOutlines = new List>(); + XYZ topLeftPoint = new XYZ(drawingArea.MinimumPoint.X, drawingArea.MaximumPoint.Y, 0); + double drawingAreaWidth = drawingArea.MaximumPoint.X - drawingArea.MinimumPoint.X; + double drawingAreaHeight = drawingArea.MaximumPoint.Y - drawingArea.MinimumPoint.Y; + + if (direction == ViewportAlignmentDirection.Horizontal) + { + List pendingOutlines = outlines; + + while (pendingOutlines.Count > 0) { - viewportPoints.AddRange(AlignViewportsInRow(newDrawingArea, viewportsInRow, viewportOffset, direction, out Outline rowOutline)); - totalOutline = totalOutline.Add(rowOutline); + List rowOutlines = pendingOutlines; + List alignedRowOutlines = rowOutlines.OutlinesInRow(topLeftPoint, offset, direction); + Outline rowOutline = alignedRowOutlines.Bounds(); + double rowOutlineWidth = rowOutline.MaximumPoint.X - rowOutline.MinimumPoint.X; - XYZ newDrawingAreaMinPoint = new XYZ(totalOutline.MaximumPoint.X + viewportOffset, totalOutline.MinimumPoint.Y, 0); - newDrawingArea = new Outline(newDrawingAreaMinPoint, newDrawingArea.MaximumPoint); + while (rowOutlineWidth > drawingAreaWidth) + { + rowOutlines = rowOutlines.Take(rowOutlines.Count - 1).ToList(); + alignedRowOutlines = rowOutlines.OutlinesInRow(topLeftPoint, offset, direction); + rowOutline = alignedRowOutlines.Bounds(); + rowOutlineWidth = rowOutline.MaximumPoint.X - rowOutline.MinimumPoint.X; + } + + listOfOutlines.Add(rowOutlines); + pendingOutlines = pendingOutlines.Skip(rowOutlines.Count).ToList(); } } + else if (direction == ViewportAlignmentDirection.Vertical) + { + List pendingOutlines = outlines; - return viewportPoints; - } + while (pendingOutlines.Count > 0) + { + List rowOutlines = pendingOutlines; + List alignedRowOutlines = rowOutlines.OutlinesInRow(topLeftPoint, offset, direction); + Outline rowOutline = alignedRowOutlines.Bounds(); + double rowOutlineHeight = rowOutline.MaximumPoint.Y - rowOutline.MinimumPoint.Y; - /***************************************************/ - /**** Private methods ****/ - /***************************************************/ + while (rowOutlineHeight > drawingAreaHeight) + { + rowOutlines = rowOutlines.Take(rowOutlines.Count - 1).ToList(); + alignedRowOutlines = rowOutlines.OutlinesInRow(topLeftPoint, offset, direction); + rowOutline = alignedRowOutlines.Bounds(); + rowOutlineHeight = rowOutline.MaximumPoint.Y - rowOutline.MinimumPoint.Y; + } - [Description("Return center points of viewports in the given direction.")] - private static List AlignViewportsInRow(this Outline drawingArea, List viewports, double viewportOffset, ViewportAlignmentDirection direction, out Outline totalOutline) - { - XYZ topLeftPoint = new XYZ(drawingArea.MinimumPoint.X, drawingArea.MaximumPoint.Y, 0); - List viewportOutlines = viewports.Select(x => x.GetBoxOutline()).ToList(); - List alignedOutlines = viewportOutlines.OrganizeOutlinesInRow(topLeftPoint, viewportOffset, direction); - List viewportCenterPoints = alignedOutlines.Select(x => x.CenterPoint()).ToList(); - totalOutline = alignedOutlines.Bounds(); + listOfOutlines.Add(rowOutlines); + pendingOutlines = pendingOutlines.Skip(rowOutlines.Count).ToList(); + } + } - return viewportCenterPoints; + return listOfOutlines; } /***************************************************/ - private static List OrganizeOutlinesInRow(this List outlines, XYZ topLeftPoint, double offset, ViewportAlignmentDirection direction) + private static List OutlinesInRow(this List outlines, XYZ topLeftPoint, double offset, ViewportAlignmentDirection direction) { List outlinesInRow = new List(); From 38fe97cfbfc0e788114c2b59a8b823615f3dbf5e Mon Sep 17 00:00:00 2001 From: Michal Pekacki Date: Thu, 13 Jul 2023 15:58:57 +0200 Subject: [PATCH 06/10] right to left alignment added --- Revit_Core_Engine/Query/AlignViewports.cs | 146 +++++++++++------- ...nmentDirection.cs => ViewportAlignment.cs} | 10 +- 2 files changed, 94 insertions(+), 62 deletions(-) rename Revit_oM/Enums/{ViewportAlignmentDirection.cs => ViewportAlignment.cs} (87%) diff --git a/Revit_Core_Engine/Query/AlignViewports.cs b/Revit_Core_Engine/Query/AlignViewports.cs index d15a6f2eb..3f3609e95 100644 --- a/Revit_Core_Engine/Query/AlignViewports.cs +++ b/Revit_Core_Engine/Query/AlignViewports.cs @@ -21,20 +21,12 @@ */ using Autodesk.Revit.DB; -using BH.Engine.Adapters.Revit; -using BH.Engine.Geometry; -using BH.oM.Adapters.Revit.Settings; -using BH.oM.Geometry; -using BH.oM.Physical.Elements; -using BH.oM.Base; -using System; -using System.ComponentModel; using BH.oM.Base.Attributes; -using System.Collections.Generic; using BH.oM.Revit.Enums; +using System; +using System.Collections.Generic; +using System.ComponentModel; using System.Linq; -using BH.oM.Structure.Offsets; -using BH.oM.Structure.Results; namespace BH.Revit.Engine.Core { @@ -44,10 +36,15 @@ public static partial class Query /**** Public methods ****/ /***************************************************/ - [Description("Finds the location curve that should be assigned to the Revit FamilyInstance representing a framing element in order to make this instance's centroid overlap with the centreline of a given BHoM framing element, taken all offsets and justifications into account.")] - [Input("framingElement", "BHoM framing element to align the Revit framing to.")] - [Output("curve", "Location curve for the input Revit FamilyInstance that aligns its centreline to the input BHoM framing element.")] - public static List AlignViewports(this Outline drawingArea, List viewports, double borderOffset, double viewportOffset, ViewportAlignmentDirection direction, out Outline totalOutline) + [Description("Returns center points of the viewports aligned in the drawing area in given direction and offsets.")] + [Input("drawingArea", "Outline in which viewports will be aligned.")] + [Input("viewports", "Viewports to aligned in the drawing area.")] + [Input("borderOffset", "Distance between border of the drawing area and viewports.")] + [Input("viewportOffset", "Distance between each viewport.")] + [Input("direction", "Direction of the viewport alignment.")] + [Input("totalOutline", "Bounded outline of the aligned viewports.")] + [Output("viewportCenterPoints", "Center points of the aligned viewports.")] + public static List AlignViewports(this Outline drawingArea, List viewports, double borderOffset, double viewportOffset, ViewportAlignment direction, out Outline totalOutline) { //add border offset to drawing area XYZ borderOffsetVec = new XYZ(borderOffset, borderOffset, 0); @@ -66,17 +63,15 @@ public static List AlignViewports(this Outline drawingArea, List /**** Private methods ****/ /***************************************************/ - private static List AlignOutlines(this Outline drawingArea, List outlines, double offset, ViewportAlignmentDirection direction) + private static List AlignOutlines(this Outline drawingArea, List outlines, double offset, ViewportAlignment direction) { List alignedOutlines = new List(); XYZ topLeftPoint = new XYZ(drawingArea.MinimumPoint.X, drawingArea.MaximumPoint.Y, 0); + XYZ topRightPoint = new XYZ(drawingArea.MaximumPoint.X, drawingArea.MaximumPoint.Y, 0); + List> listOfOutlines = DivideOutlinesInRows(drawingArea, outlines, offset, direction); - if (direction == ViewportAlignmentDirection.Horizontal) + if (direction == ViewportAlignment.HorizontalFromLeftToRight) { - //group outlines into rows - List> listOfOutlines = DivideOutlinesInRows(drawingArea, outlines, offset, direction); - - //align outline by rows XYZ newTopLeftPoint = topLeftPoint; foreach (List outlinesInRow in listOfOutlines) { @@ -87,12 +82,8 @@ private static List AlignOutlines(this Outline drawingArea, List> listOfOutlines = DivideOutlinesInRows(drawingArea, outlines, offset, direction); - - //align outline by rows XYZ newTopLeftPoint = topLeftPoint; foreach (List outlinesInRow in listOfOutlines) { @@ -103,20 +94,44 @@ private static List AlignOutlines(this Outline drawingArea, List outlinesInRow in listOfOutlines) + { + List alignedOutlinesInRow = outlinesInRow.OutlinesInRow(newTopRightPoint, offset, direction); + alignedOutlines.AddRange(alignedOutlinesInRow); + Outline rowOutlinesBound = alignedOutlinesInRow.Bounds(); + + newTopRightPoint = new XYZ(rowOutlinesBound.MaximumPoint.X, rowOutlinesBound.MinimumPoint.Y - offset, 0); + } + } + else if (direction == ViewportAlignment.VerticalFromRightToLeft) + { + XYZ newTopRightPoint = topRightPoint; + foreach (List outlinesInRow in listOfOutlines) + { + List alignedOutlinesInRow = outlinesInRow.OutlinesInRow(newTopRightPoint, offset, direction); + alignedOutlines.AddRange(alignedOutlinesInRow); + Outline rowOutlinesBound = alignedOutlinesInRow.Bounds(); + + newTopRightPoint = new XYZ(rowOutlinesBound.MinimumPoint.X - offset, rowOutlinesBound.MaximumPoint.Y, 0); + } + } return alignedOutlines; } /***************************************************/ - private static List> DivideOutlinesInRows(this Outline drawingArea, List outlines, double offset, ViewportAlignmentDirection direction) + private static List> DivideOutlinesInRows(this Outline drawingArea, List outlines, double offset, ViewportAlignment direction) { List> listOfOutlines = new List>(); XYZ topLeftPoint = new XYZ(drawingArea.MinimumPoint.X, drawingArea.MaximumPoint.Y, 0); double drawingAreaWidth = drawingArea.MaximumPoint.X - drawingArea.MinimumPoint.X; double drawingAreaHeight = drawingArea.MaximumPoint.Y - drawingArea.MinimumPoint.Y; - if (direction == ViewportAlignmentDirection.Horizontal) + if (direction == ViewportAlignment.HorizontalFromLeftToRight || direction == ViewportAlignment.HorizontalFromRightToLeft) { List pendingOutlines = outlines; @@ -139,7 +154,7 @@ private static List> DivideOutlinesInRows(this Outline drawingArea pendingOutlines = pendingOutlines.Skip(rowOutlines.Count).ToList(); } } - else if (direction == ViewportAlignmentDirection.Vertical) + else if (direction == ViewportAlignment.VerticalFromLeftToRight || direction == ViewportAlignment.VerticalFromRightToLeft) { List pendingOutlines = outlines; @@ -168,7 +183,7 @@ private static List> DivideOutlinesInRows(this Outline drawingArea /***************************************************/ - private static List OutlinesInRow(this List outlines, XYZ topLeftPoint, double offset, ViewportAlignmentDirection direction) + private static List OutlinesInRow(this List outlines, XYZ startingPoint, double offset, ViewportAlignment direction) { List outlinesInRow = new List(); @@ -178,38 +193,71 @@ private static List OutlinesInRow(this List outlines, XYZ topL double outlineWidth = outline.MaximumPoint.X - outline.MinimumPoint.X; double outlineHeight = outline.MaximumPoint.Y - outline.MinimumPoint.Y; - if (direction == ViewportAlignmentDirection.Horizontal) + if (direction == ViewportAlignment.HorizontalFromLeftToRight) { double outlineTopLeftX; if (i == 0) - outlineTopLeftX = topLeftPoint.X; + outlineTopLeftX = startingPoint.X; else - outlineTopLeftX = topLeftPoint.X + offset; + outlineTopLeftX = startingPoint.X + offset; - double outlineTopLeftY = topLeftPoint.Y; + double outlineTopLeftY = startingPoint.Y; XYZ outlineNewCenterPoint = new XYZ(outlineTopLeftX + outlineWidth / 2, outlineTopLeftY - outlineHeight / 2, 0); outline = outline.MovedToCenterPoint(outlineNewCenterPoint); outlinesInRow.Add(outline); - topLeftPoint = new XYZ(outlineTopLeftX + outlineWidth, outlineTopLeftY, 0); + startingPoint = new XYZ(outlineTopLeftX + outlineWidth, outlineTopLeftY, 0); } - else if (direction == ViewportAlignmentDirection.Vertical) + else if (direction == ViewportAlignment.VerticalFromLeftToRight) { - double outlineTopLeftX = topLeftPoint.X; + double outlineTopLeftX = startingPoint.X; double outlineTopLeftY; if (i == 0) - outlineTopLeftY = topLeftPoint.Y; + outlineTopLeftY = startingPoint.Y; else - outlineTopLeftY = topLeftPoint.Y - offset; + outlineTopLeftY = startingPoint.Y - offset; XYZ outlineNewCenterPoint = new XYZ(outlineTopLeftX + outlineWidth / 2, outlineTopLeftY - outlineHeight / 2, 0); outline = outline.MovedToCenterPoint(outlineNewCenterPoint); outlinesInRow.Add(outline); - topLeftPoint = new XYZ(outlineTopLeftX, outlineTopLeftY - outlineHeight, 0); + startingPoint = new XYZ(outlineTopLeftX, outlineTopLeftY - outlineHeight, 0); + } + else if (direction == ViewportAlignment.HorizontalFromRightToLeft) + { + double outlineTopRightX; + + if (i == 0) + outlineTopRightX = startingPoint.X; + else + outlineTopRightX = startingPoint.X - offset; + + double outlineTopRightY = startingPoint.Y; + + XYZ outlineNewCenterPoint = new XYZ(outlineTopRightX - outlineWidth / 2, outlineTopRightY - outlineHeight / 2, 0); + outline = outline.MovedToCenterPoint(outlineNewCenterPoint); + outlinesInRow.Add(outline); + + startingPoint = new XYZ(outlineTopRightX - outlineWidth, outlineTopRightY, 0); + } + else if (direction == ViewportAlignment.VerticalFromRightToLeft) + { + double outlineTopRightX = startingPoint.X; + double outlineTopRightY; + + if (i == 0) + outlineTopRightY = startingPoint.Y; + else + outlineTopRightY = startingPoint.Y - offset; + + XYZ outlineNewCenterPoint = new XYZ(outlineTopRightX - outlineWidth / 2, outlineTopRightY - outlineHeight / 2, 0); + outline = outline.MovedToCenterPoint(outlineNewCenterPoint); + outlinesInRow.Add(outline); + + startingPoint = new XYZ(outlineTopRightX, outlineTopRightY - outlineHeight, 0); } } @@ -264,24 +312,6 @@ private static Outline Bounds(this List outlines) } /***************************************************/ - - private static Outline Add(this Outline outline, Outline outlineToAdd) - { - if (outline == null) - return new Outline(outlineToAdd); - - double minX = Math.Min(outline.MinimumPoint.X, outlineToAdd.MinimumPoint.X); - double minY = Math.Min(outline.MinimumPoint.Y, outlineToAdd.MinimumPoint.Y); - double maxX = Math.Max(outline.MaximumPoint.X, outlineToAdd.MaximumPoint.X); - double maxY = Math.Max(outline.MaximumPoint.Y, outlineToAdd.MaximumPoint.Y); - - XYZ minPoint = new XYZ(minX, minY, 0); - XYZ maxPoint = new XYZ(maxX, maxY, 0); - - return new Outline(minPoint, maxPoint); - } - - /***************************************************/ } } diff --git a/Revit_oM/Enums/ViewportAlignmentDirection.cs b/Revit_oM/Enums/ViewportAlignment.cs similarity index 87% rename from Revit_oM/Enums/ViewportAlignmentDirection.cs rename to Revit_oM/Enums/ViewportAlignment.cs index fd64a2ed8..164739f2e 100644 --- a/Revit_oM/Enums/ViewportAlignmentDirection.cs +++ b/Revit_oM/Enums/ViewportAlignment.cs @@ -26,11 +26,13 @@ namespace BH.oM.Revit.Enums { /***************************************************/ - [Description("Enumerator defining the way in which two strings are compared.")] - public enum ViewportAlignmentDirection + [Description("Direction of the sheet viewport alignment.")] + public enum ViewportAlignment { - Horizontal, - Vertical + HorizontalFromLeftToRight, + VerticalFromLeftToRight, + HorizontalFromRightToLeft, + VerticalFromRightToLeft } /***************************************************/ From e32134f7eac01c2e8797f2d9929d8536b851836c Mon Sep 17 00:00:00 2001 From: Michal Pekacki Date: Thu, 13 Jul 2023 16:22:32 +0200 Subject: [PATCH 07/10] changed align viewports to align outlines --- .../{AlignViewports.cs => AlignOutlines.cs} | 103 +++++------------- Revit_Core_Engine/Query/Bounds.cs | 30 ++++- Revit_Core_Engine/Query/CenterPoint.cs | 49 +++++++++ ...ewportAlignment.cs => OutlineAlignment.cs} | 2 +- 4 files changed, 103 insertions(+), 81 deletions(-) rename Revit_Core_Engine/Query/{AlignViewports.cs => AlignOutlines.cs} (72%) create mode 100644 Revit_Core_Engine/Query/CenterPoint.cs rename Revit_oM/Enums/{ViewportAlignment.cs => OutlineAlignment.cs} (98%) diff --git a/Revit_Core_Engine/Query/AlignViewports.cs b/Revit_Core_Engine/Query/AlignOutlines.cs similarity index 72% rename from Revit_Core_Engine/Query/AlignViewports.cs rename to Revit_Core_Engine/Query/AlignOutlines.cs index 3f3609e95..bb64f6e2b 100644 --- a/Revit_Core_Engine/Query/AlignViewports.cs +++ b/Revit_Core_Engine/Query/AlignOutlines.cs @@ -23,7 +23,6 @@ using Autodesk.Revit.DB; using BH.oM.Base.Attributes; using BH.oM.Revit.Enums; -using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; @@ -33,44 +32,23 @@ namespace BH.Revit.Engine.Core public static partial class Query { /***************************************************/ - /**** Public methods ****/ + /**** Public methods ****/ /***************************************************/ - [Description("Returns center points of the viewports aligned in the drawing area in given direction and offsets.")] - [Input("drawingArea", "Outline in which viewports will be aligned.")] - [Input("viewports", "Viewports to aligned in the drawing area.")] - [Input("borderOffset", "Distance between border of the drawing area and viewports.")] - [Input("viewportOffset", "Distance between each viewport.")] - [Input("direction", "Direction of the viewport alignment.")] - [Input("totalOutline", "Bounded outline of the aligned viewports.")] - [Output("viewportCenterPoints", "Center points of the aligned viewports.")] - public static List AlignViewports(this Outline drawingArea, List viewports, double borderOffset, double viewportOffset, ViewportAlignment direction, out Outline totalOutline) - { - //add border offset to drawing area - XYZ borderOffsetVec = new XYZ(borderOffset, borderOffset, 0); - drawingArea.MinimumPoint += borderOffsetVec; - drawingArea.MaximumPoint -= borderOffsetVec; - - List viewportOutlines = viewports.Select(x => x.GetBoxOutline()).ToList(); - List alignedOutlines = drawingArea.AlignOutlines(viewportOutlines, viewportOffset, direction); - List viewportCenterPoints = alignedOutlines.Select(x => x.CenterPoint()).ToList(); - totalOutline = alignedOutlines.Bounds(); - - return viewportCenterPoints; - } - - /***************************************************/ - /**** Private methods ****/ - /***************************************************/ - - private static List AlignOutlines(this Outline drawingArea, List outlines, double offset, ViewportAlignment direction) + [Description("Aligns outlines in the bounding outline in given direction.")] + [Input("boudingOutline", "Bounding outline in which outline will be aligned.")] + [Input("outlines", "Outlines to aligned in the bounding outline.")] + [Input("offset", "Distance between each outline.")] + [Input("direction", "Direction of the outline alignment.")] + [Output("alignedOutlines", "Outlines aligned in the bounding outline.")] + public static List AlignOutlines(this Outline boudingOutline, List outlines, double offset, OutlineAlignment direction) { List alignedOutlines = new List(); - XYZ topLeftPoint = new XYZ(drawingArea.MinimumPoint.X, drawingArea.MaximumPoint.Y, 0); - XYZ topRightPoint = new XYZ(drawingArea.MaximumPoint.X, drawingArea.MaximumPoint.Y, 0); - List> listOfOutlines = DivideOutlinesInRows(drawingArea, outlines, offset, direction); + XYZ topLeftPoint = new XYZ(boudingOutline.MinimumPoint.X, boudingOutline.MaximumPoint.Y, 0); + XYZ topRightPoint = new XYZ(boudingOutline.MaximumPoint.X, boudingOutline.MaximumPoint.Y, 0); + List> listOfOutlines = DivideOutlinesInRows(boudingOutline, outlines, offset, direction); - if (direction == ViewportAlignment.HorizontalFromLeftToRight) + if (direction == OutlineAlignment.HorizontalFromLeftToRight) { XYZ newTopLeftPoint = topLeftPoint; foreach (List outlinesInRow in listOfOutlines) @@ -82,7 +60,7 @@ private static List AlignOutlines(this Outline drawingArea, List outlinesInRow in listOfOutlines) @@ -94,7 +72,7 @@ private static List AlignOutlines(this Outline drawingArea, List outlinesInRow in listOfOutlines) @@ -106,7 +84,7 @@ private static List AlignOutlines(this Outline drawingArea, List outlinesInRow in listOfOutlines) @@ -122,16 +100,18 @@ private static List AlignOutlines(this Outline drawingArea, List> DivideOutlinesInRows(this Outline drawingArea, List outlines, double offset, ViewportAlignment direction) + private static List> DivideOutlinesInRows(this Outline drawingArea, List outlines, double offset, OutlineAlignment direction) { List> listOfOutlines = new List>(); XYZ topLeftPoint = new XYZ(drawingArea.MinimumPoint.X, drawingArea.MaximumPoint.Y, 0); double drawingAreaWidth = drawingArea.MaximumPoint.X - drawingArea.MinimumPoint.X; double drawingAreaHeight = drawingArea.MaximumPoint.Y - drawingArea.MinimumPoint.Y; - if (direction == ViewportAlignment.HorizontalFromLeftToRight || direction == ViewportAlignment.HorizontalFromRightToLeft) + if (direction == OutlineAlignment.HorizontalFromLeftToRight || direction == OutlineAlignment.HorizontalFromRightToLeft) { List pendingOutlines = outlines; @@ -154,7 +134,7 @@ private static List> DivideOutlinesInRows(this Outline drawingArea pendingOutlines = pendingOutlines.Skip(rowOutlines.Count).ToList(); } } - else if (direction == ViewportAlignment.VerticalFromLeftToRight || direction == ViewportAlignment.VerticalFromRightToLeft) + else if (direction == OutlineAlignment.VerticalFromLeftToRight || direction == OutlineAlignment.VerticalFromRightToLeft) { List pendingOutlines = outlines; @@ -183,7 +163,7 @@ private static List> DivideOutlinesInRows(this Outline drawingArea /***************************************************/ - private static List OutlinesInRow(this List outlines, XYZ startingPoint, double offset, ViewportAlignment direction) + private static List OutlinesInRow(this List outlines, XYZ startingPoint, double offset, OutlineAlignment direction) { List outlinesInRow = new List(); @@ -193,7 +173,7 @@ private static List OutlinesInRow(this List outlines, XYZ star double outlineWidth = outline.MaximumPoint.X - outline.MinimumPoint.X; double outlineHeight = outline.MaximumPoint.Y - outline.MinimumPoint.Y; - if (direction == ViewportAlignment.HorizontalFromLeftToRight) + if (direction == OutlineAlignment.HorizontalFromLeftToRight) { double outlineTopLeftX; @@ -210,7 +190,7 @@ private static List OutlinesInRow(this List outlines, XYZ star startingPoint = new XYZ(outlineTopLeftX + outlineWidth, outlineTopLeftY, 0); } - else if (direction == ViewportAlignment.VerticalFromLeftToRight) + else if (direction == OutlineAlignment.VerticalFromLeftToRight) { double outlineTopLeftX = startingPoint.X; double outlineTopLeftY; @@ -226,7 +206,7 @@ private static List OutlinesInRow(this List outlines, XYZ star startingPoint = new XYZ(outlineTopLeftX, outlineTopLeftY - outlineHeight, 0); } - else if (direction == ViewportAlignment.HorizontalFromRightToLeft) + else if (direction == OutlineAlignment.HorizontalFromRightToLeft) { double outlineTopRightX; @@ -243,7 +223,7 @@ private static List OutlinesInRow(this List outlines, XYZ star startingPoint = new XYZ(outlineTopRightX - outlineWidth, outlineTopRightY, 0); } - else if (direction == ViewportAlignment.VerticalFromRightToLeft) + else if (direction == OutlineAlignment.VerticalFromRightToLeft) { double outlineTopRightX = startingPoint.X; double outlineTopRightY; @@ -266,16 +246,6 @@ private static List OutlinesInRow(this List outlines, XYZ star /***************************************************/ - private static XYZ CenterPoint(this Outline outline) - { - double centerX = outline.MinimumPoint.X + (outline.MaximumPoint.X - outline.MinimumPoint.X) / 2; - double centerY = outline.MinimumPoint.Y + (outline.MaximumPoint.Y - outline.MinimumPoint.Y) / 2; - - return new XYZ(centerX, centerY, 0); - } - - /***************************************************/ - private static Outline MovedToCenterPoint(this Outline outline, XYZ centerPoint) { double outlineWidth = outline.MaximumPoint.X - outline.MinimumPoint.X; @@ -289,29 +259,6 @@ private static Outline MovedToCenterPoint(this Outline outline, XYZ centerPoint) } /***************************************************/ - - private static Outline Bounds(this List outlines) - { - double minX = double.MaxValue; - double minY = double.MaxValue; - double maxX = double.MinValue; - double maxY = double.MinValue; - - foreach (Outline outline in outlines) - { - minX = Math.Min(outline.MinimumPoint.X, minX); - minY = Math.Min(outline.MinimumPoint.Y, minY); - maxX = Math.Max(outline.MaximumPoint.X, maxX); - maxY = Math.Max(outline.MaximumPoint.Y, maxY); - } - - XYZ minPoint = new XYZ(minX, minY, 0); - XYZ maxPoint = new XYZ(maxX, maxY, 0); - - return new Outline(minPoint, maxPoint); - } - - /***************************************************/ } } diff --git a/Revit_Core_Engine/Query/Bounds.cs b/Revit_Core_Engine/Query/Bounds.cs index d9ab8ecd9..f8d47edbb 100644 --- a/Revit_Core_Engine/Query/Bounds.cs +++ b/Revit_Core_Engine/Query/Bounds.cs @@ -36,10 +36,10 @@ public static partial class Query /**** Public methods ****/ /***************************************************/ - [Description("Returns the combined bounding box of a given colection of volumetric solids.")] + [Description("Returns the combined bounding box of a given collection of volumetric solids.")] [Input("solids", "A collection of solids to find the bounds for.")] [Input("transform", "Optional transform of the bounding box's coordinate system.")] - [Output("bounds", "Combined bounding box of the input colection of volumetric solids.")] + [Output("bounds", "Combined bounding box of the input collection of volumetric solids.")] public static BoundingBoxXYZ Bounds(this IEnumerable solids, Transform transform = null) { solids = solids?.Where(x => x != null && x.Volume > 1e-6).ToList(); @@ -81,6 +81,32 @@ public static BoundingBoxXYZ Bounds(this IEnumerable solids, Transform tr } /***************************************************/ + + [Description("Returns the combined outline of the given outlines.")] + [Input("outlines", "A list of outlines to combine.")] + [Output("bounds", "Combined outline of the given outlines.")] + public static Outline Bounds(this List outlines) + { + double minX = double.MaxValue; + double minY = double.MaxValue; + double maxX = double.MinValue; + double maxY = double.MinValue; + + foreach (Outline outline in outlines) + { + minX = Math.Min(outline.MinimumPoint.X, minX); + minY = Math.Min(outline.MinimumPoint.Y, minY); + maxX = Math.Max(outline.MaximumPoint.X, maxX); + maxY = Math.Max(outline.MaximumPoint.Y, maxY); + } + + XYZ minPoint = new XYZ(minX, minY, 0); + XYZ maxPoint = new XYZ(maxX, maxY, 0); + + return new Outline(minPoint, maxPoint); + } + + /***************************************************/ } } diff --git a/Revit_Core_Engine/Query/CenterPoint.cs b/Revit_Core_Engine/Query/CenterPoint.cs new file mode 100644 index 000000000..d18ec4378 --- /dev/null +++ b/Revit_Core_Engine/Query/CenterPoint.cs @@ -0,0 +1,49 @@ +/* + * This file is part of the Buildings and Habitats object Model (BHoM) + * Copyright (c) 2015 - 2023, the respective contributors. All rights reserved. + * + * Each contributor holds copyright over their respective contributions. + * The project versioning (Git) records all such contribution source information. + * + * + * The BHoM is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3.0 of the License, or + * (at your option) any later version. + * + * The BHoM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this code. If not, see . + */ + +using Autodesk.Revit.DB; +using BH.oM.Base.Attributes; +using System.ComponentModel; + +namespace BH.Revit.Engine.Core +{ + public static partial class Query + { + /***************************************************/ + /**** Public methods ****/ + /***************************************************/ + + [Description("Returns the center point of the outline.")] + [Input("outline", "Outline to get the center point from.")] + [Output("point", "Center point of the outline.")] + public static XYZ CenterPoint(this Outline outline) + { + double centerX = outline.MinimumPoint.X + (outline.MaximumPoint.X - outline.MinimumPoint.X) / 2; + double centerY = outline.MinimumPoint.Y + (outline.MaximumPoint.Y - outline.MinimumPoint.Y) / 2; + + return new XYZ(centerX, centerY, 0); + } + + /***************************************************/ + } +} + diff --git a/Revit_oM/Enums/ViewportAlignment.cs b/Revit_oM/Enums/OutlineAlignment.cs similarity index 98% rename from Revit_oM/Enums/ViewportAlignment.cs rename to Revit_oM/Enums/OutlineAlignment.cs index 164739f2e..d1b453cef 100644 --- a/Revit_oM/Enums/ViewportAlignment.cs +++ b/Revit_oM/Enums/OutlineAlignment.cs @@ -27,7 +27,7 @@ namespace BH.oM.Revit.Enums /***************************************************/ [Description("Direction of the sheet viewport alignment.")] - public enum ViewportAlignment + public enum OutlineAlignment { HorizontalFromLeftToRight, VerticalFromLeftToRight, From 7d6435cf067b3dbab5054dab30c4b9b365c5d544 Mon Sep 17 00:00:00 2001 From: Michal Pekacki Date: Mon, 17 Jul 2023 12:25:45 +0200 Subject: [PATCH 08/10] update after @vietle-bh comments --- Revit_Core_Engine/Query/AlignOutlines.cs | 87 ++++++++++++------------ Revit_Core_Engine/Query/Bounds.cs | 18 ++--- Revit_Core_Engine/Query/CenterPoint.cs | 5 +- 3 files changed, 51 insertions(+), 59 deletions(-) diff --git a/Revit_Core_Engine/Query/AlignOutlines.cs b/Revit_Core_Engine/Query/AlignOutlines.cs index bb64f6e2b..c7d67a79f 100644 --- a/Revit_Core_Engine/Query/AlignOutlines.cs +++ b/Revit_Core_Engine/Query/AlignOutlines.cs @@ -35,23 +35,23 @@ public static partial class Query /**** Public methods ****/ /***************************************************/ - [Description("Aligns outlines in the bounding outline in given direction.")] + [Description("Aligns outlines in the bounding outline along a given direction.")] [Input("boudingOutline", "Bounding outline in which outline will be aligned.")] [Input("outlines", "Outlines to aligned in the bounding outline.")] [Input("offset", "Distance between each outline.")] [Input("direction", "Direction of the outline alignment.")] [Output("alignedOutlines", "Outlines aligned in the bounding outline.")] - public static List AlignOutlines(this Outline boudingOutline, List outlines, double offset, OutlineAlignment direction) + public static List AlignOutlines(this Outline drawingArea, List outlines, double offset, OutlineAlignment direction) { List alignedOutlines = new List(); - XYZ topLeftPoint = new XYZ(boudingOutline.MinimumPoint.X, boudingOutline.MaximumPoint.Y, 0); - XYZ topRightPoint = new XYZ(boudingOutline.MaximumPoint.X, boudingOutline.MaximumPoint.Y, 0); - List> listOfOutlines = DivideOutlinesInRows(boudingOutline, outlines, offset, direction); + XYZ topLeftPoint = new XYZ(drawingArea.MinimumPoint.X, drawingArea.MaximumPoint.Y, 0); + XYZ topRightPoint = new XYZ(drawingArea.MaximumPoint.X, drawingArea.MaximumPoint.Y, 0); + List> outlinesByRows = DivideOutlinesInRows(drawingArea, outlines, offset, direction); if (direction == OutlineAlignment.HorizontalFromLeftToRight) { XYZ newTopLeftPoint = topLeftPoint; - foreach (List outlinesInRow in listOfOutlines) + foreach (List outlinesInRow in outlinesByRows) { List alignedOutlinesInRow = outlinesInRow.OutlinesInRow(newTopLeftPoint, offset, direction); alignedOutlines.AddRange(alignedOutlinesInRow); @@ -63,7 +63,7 @@ public static List AlignOutlines(this Outline boudingOutline, List outlinesInRow in listOfOutlines) + foreach (List outlinesInRow in outlinesByRows) { List alignedOutlinesInRow = outlinesInRow.OutlinesInRow(newTopLeftPoint, offset, direction); alignedOutlines.AddRange(alignedOutlinesInRow); @@ -75,7 +75,7 @@ public static List AlignOutlines(this Outline boudingOutline, List outlinesInRow in listOfOutlines) + foreach (List outlinesInRow in outlinesByRows) { List alignedOutlinesInRow = outlinesInRow.OutlinesInRow(newTopRightPoint, offset, direction); alignedOutlines.AddRange(alignedOutlinesInRow); @@ -87,7 +87,7 @@ public static List AlignOutlines(this Outline boudingOutline, List outlinesInRow in listOfOutlines) + foreach (List outlinesInRow in outlinesByRows) { List alignedOutlinesInRow = outlinesInRow.OutlinesInRow(newTopRightPoint, offset, direction); alignedOutlines.AddRange(alignedOutlinesInRow); @@ -106,59 +106,62 @@ public static List AlignOutlines(this Outline boudingOutline, List> DivideOutlinesInRows(this Outline drawingArea, List outlines, double offset, OutlineAlignment direction) { - List> listOfOutlines = new List>(); - XYZ topLeftPoint = new XYZ(drawingArea.MinimumPoint.X, drawingArea.MaximumPoint.Y, 0); - double drawingAreaWidth = drawingArea.MaximumPoint.X - drawingArea.MinimumPoint.X; - double drawingAreaHeight = drawingArea.MaximumPoint.Y - drawingArea.MinimumPoint.Y; + List> outlinesByRows = new List>(); if (direction == OutlineAlignment.HorizontalFromLeftToRight || direction == OutlineAlignment.HorizontalFromRightToLeft) { - List pendingOutlines = outlines; + List currentRowOutlines = new List(); + double drawingAreaWidth = drawingArea.MaximumPoint.X - drawingArea.MinimumPoint.X; + double currentRowWidth = -offset; - while (pendingOutlines.Count > 0) + foreach (Outline outline in outlines) { - List rowOutlines = pendingOutlines; - List alignedRowOutlines = rowOutlines.OutlinesInRow(topLeftPoint, offset, direction); - Outline rowOutline = alignedRowOutlines.Bounds(); - double rowOutlineWidth = rowOutline.MaximumPoint.X - rowOutline.MinimumPoint.X; + double outlineWidth = outline.MaximumPoint.X - outline.MinimumPoint.X; + currentRowWidth += outlineWidth + offset; - while (rowOutlineWidth > drawingAreaWidth) + if (currentRowWidth < drawingAreaWidth) { - rowOutlines = rowOutlines.Take(rowOutlines.Count - 1).ToList(); - alignedRowOutlines = rowOutlines.OutlinesInRow(topLeftPoint, offset, direction); - rowOutline = alignedRowOutlines.Bounds(); - rowOutlineWidth = rowOutline.MaximumPoint.X - rowOutline.MinimumPoint.X; + currentRowOutlines.Add(outline); + } + else + { + outlinesByRows.Add(currentRowOutlines); + currentRowOutlines = new List { outline }; + currentRowWidth = outlineWidth; } - - listOfOutlines.Add(rowOutlines); - pendingOutlines = pendingOutlines.Skip(rowOutlines.Count).ToList(); } + + if (currentRowOutlines.Any()) + outlinesByRows.Add(currentRowOutlines); } else if (direction == OutlineAlignment.VerticalFromLeftToRight || direction == OutlineAlignment.VerticalFromRightToLeft) { - List pendingOutlines = outlines; + List currentRowOutlines = new List(); + double drawingAreaHeight = drawingArea.MaximumPoint.Y - drawingArea.MinimumPoint.Y; + double currentRowHeight = -offset; - while (pendingOutlines.Count > 0) + foreach (Outline outline in outlines) { - List rowOutlines = pendingOutlines; - List alignedRowOutlines = rowOutlines.OutlinesInRow(topLeftPoint, offset, direction); - Outline rowOutline = alignedRowOutlines.Bounds(); - double rowOutlineHeight = rowOutline.MaximumPoint.Y - rowOutline.MinimumPoint.Y; + double outlineHeight = outline.MaximumPoint.Y - outline.MinimumPoint.Y; + currentRowHeight += outlineHeight + offset; - while (rowOutlineHeight > drawingAreaHeight) + if (currentRowHeight < drawingAreaHeight) { - rowOutlines = rowOutlines.Take(rowOutlines.Count - 1).ToList(); - alignedRowOutlines = rowOutlines.OutlinesInRow(topLeftPoint, offset, direction); - rowOutline = alignedRowOutlines.Bounds(); - rowOutlineHeight = rowOutline.MaximumPoint.Y - rowOutline.MinimumPoint.Y; + currentRowOutlines.Add(outline); + } + else + { + outlinesByRows.Add(currentRowOutlines); + currentRowOutlines = new List { outline }; + currentRowHeight = outlineHeight; } - - listOfOutlines.Add(rowOutlines); - pendingOutlines = pendingOutlines.Skip(rowOutlines.Count).ToList(); } + + if (currentRowOutlines.Any()) + outlinesByRows.Add(currentRowOutlines); } - return listOfOutlines; + return outlinesByRows; } /***************************************************/ diff --git a/Revit_Core_Engine/Query/Bounds.cs b/Revit_Core_Engine/Query/Bounds.cs index f8d47edbb..0e6cbd559 100644 --- a/Revit_Core_Engine/Query/Bounds.cs +++ b/Revit_Core_Engine/Query/Bounds.cs @@ -87,23 +87,15 @@ public static BoundingBoxXYZ Bounds(this IEnumerable solids, Transform tr [Output("bounds", "Combined outline of the given outlines.")] public static Outline Bounds(this List outlines) { - double minX = double.MaxValue; - double minY = double.MaxValue; - double maxX = double.MinValue; - double maxY = double.MinValue; + Outline newOutline = new Outline(outlines[0]); - foreach (Outline outline in outlines) + foreach (Outline outline in outlines.Skip(1)) { - minX = Math.Min(outline.MinimumPoint.X, minX); - minY = Math.Min(outline.MinimumPoint.Y, minY); - maxX = Math.Max(outline.MaximumPoint.X, maxX); - maxY = Math.Max(outline.MaximumPoint.Y, maxY); + newOutline.AddPoint(outline.MinimumPoint); + newOutline.AddPoint(outline.MaximumPoint); } - XYZ minPoint = new XYZ(minX, minY, 0); - XYZ maxPoint = new XYZ(maxX, maxY, 0); - - return new Outline(minPoint, maxPoint); + return newOutline; } /***************************************************/ diff --git a/Revit_Core_Engine/Query/CenterPoint.cs b/Revit_Core_Engine/Query/CenterPoint.cs index d18ec4378..dcca66be0 100644 --- a/Revit_Core_Engine/Query/CenterPoint.cs +++ b/Revit_Core_Engine/Query/CenterPoint.cs @@ -37,10 +37,7 @@ public static partial class Query [Output("point", "Center point of the outline.")] public static XYZ CenterPoint(this Outline outline) { - double centerX = outline.MinimumPoint.X + (outline.MaximumPoint.X - outline.MinimumPoint.X) / 2; - double centerY = outline.MinimumPoint.Y + (outline.MaximumPoint.Y - outline.MinimumPoint.Y) / 2; - - return new XYZ(centerX, centerY, 0); + return (outline.MinimumPoint + outline.MaximumPoint) / 2; } /***************************************************/ From a6b713bb9c2607b99ac425a6c612ce5e03a54937 Mon Sep 17 00:00:00 2001 From: Michal Pekacki Date: Mon, 24 Jul 2023 10:30:51 +0200 Subject: [PATCH 09/10] methods removed, null check added --- Revit_Core_Engine/Query/AlignOutlines.cs | 267 ----------------------- Revit_Core_Engine/Query/Bounds.cs | 3 + Revit_oM/Enums/OutlineAlignment.cs | 42 ---- 3 files changed, 3 insertions(+), 309 deletions(-) delete mode 100644 Revit_Core_Engine/Query/AlignOutlines.cs delete mode 100644 Revit_oM/Enums/OutlineAlignment.cs diff --git a/Revit_Core_Engine/Query/AlignOutlines.cs b/Revit_Core_Engine/Query/AlignOutlines.cs deleted file mode 100644 index c7d67a79f..000000000 --- a/Revit_Core_Engine/Query/AlignOutlines.cs +++ /dev/null @@ -1,267 +0,0 @@ -/* - * This file is part of the Buildings and Habitats object Model (BHoM) - * Copyright (c) 2015 - 2023, the respective contributors. All rights reserved. - * - * Each contributor holds copyright over their respective contributions. - * The project versioning (Git) records all such contribution source information. - * - * - * The BHoM is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3.0 of the License, or - * (at your option) any later version. - * - * The BHoM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this code. If not, see . - */ - -using Autodesk.Revit.DB; -using BH.oM.Base.Attributes; -using BH.oM.Revit.Enums; -using System.Collections.Generic; -using System.ComponentModel; -using System.Linq; - -namespace BH.Revit.Engine.Core -{ - public static partial class Query - { - /***************************************************/ - /**** Public methods ****/ - /***************************************************/ - - [Description("Aligns outlines in the bounding outline along a given direction.")] - [Input("boudingOutline", "Bounding outline in which outline will be aligned.")] - [Input("outlines", "Outlines to aligned in the bounding outline.")] - [Input("offset", "Distance between each outline.")] - [Input("direction", "Direction of the outline alignment.")] - [Output("alignedOutlines", "Outlines aligned in the bounding outline.")] - public static List AlignOutlines(this Outline drawingArea, List outlines, double offset, OutlineAlignment direction) - { - List alignedOutlines = new List(); - XYZ topLeftPoint = new XYZ(drawingArea.MinimumPoint.X, drawingArea.MaximumPoint.Y, 0); - XYZ topRightPoint = new XYZ(drawingArea.MaximumPoint.X, drawingArea.MaximumPoint.Y, 0); - List> outlinesByRows = DivideOutlinesInRows(drawingArea, outlines, offset, direction); - - if (direction == OutlineAlignment.HorizontalFromLeftToRight) - { - XYZ newTopLeftPoint = topLeftPoint; - foreach (List outlinesInRow in outlinesByRows) - { - List alignedOutlinesInRow = outlinesInRow.OutlinesInRow(newTopLeftPoint, offset, direction); - alignedOutlines.AddRange(alignedOutlinesInRow); - Outline rowOutlinesBound = alignedOutlinesInRow.Bounds(); - - newTopLeftPoint = new XYZ(rowOutlinesBound.MinimumPoint.X, rowOutlinesBound.MinimumPoint.Y - offset, 0); - } - } - else if (direction == OutlineAlignment.VerticalFromLeftToRight) - { - XYZ newTopLeftPoint = topLeftPoint; - foreach (List outlinesInRow in outlinesByRows) - { - List alignedOutlinesInRow = outlinesInRow.OutlinesInRow(newTopLeftPoint, offset, direction); - alignedOutlines.AddRange(alignedOutlinesInRow); - Outline rowOutlinesBound = alignedOutlinesInRow.Bounds(); - - newTopLeftPoint = new XYZ(rowOutlinesBound.MaximumPoint.X + offset, rowOutlinesBound.MaximumPoint.Y, 0); - } - } - else if (direction == OutlineAlignment.HorizontalFromRightToLeft) - { - XYZ newTopRightPoint = topRightPoint; - foreach (List outlinesInRow in outlinesByRows) - { - List alignedOutlinesInRow = outlinesInRow.OutlinesInRow(newTopRightPoint, offset, direction); - alignedOutlines.AddRange(alignedOutlinesInRow); - Outline rowOutlinesBound = alignedOutlinesInRow.Bounds(); - - newTopRightPoint = new XYZ(rowOutlinesBound.MaximumPoint.X, rowOutlinesBound.MinimumPoint.Y - offset, 0); - } - } - else if (direction == OutlineAlignment.VerticalFromRightToLeft) - { - XYZ newTopRightPoint = topRightPoint; - foreach (List outlinesInRow in outlinesByRows) - { - List alignedOutlinesInRow = outlinesInRow.OutlinesInRow(newTopRightPoint, offset, direction); - alignedOutlines.AddRange(alignedOutlinesInRow); - Outline rowOutlinesBound = alignedOutlinesInRow.Bounds(); - - newTopRightPoint = new XYZ(rowOutlinesBound.MinimumPoint.X - offset, rowOutlinesBound.MaximumPoint.Y, 0); - } - } - - return alignedOutlines; - } - - /***************************************************/ - /**** Private methods ****/ - /***************************************************/ - - private static List> DivideOutlinesInRows(this Outline drawingArea, List outlines, double offset, OutlineAlignment direction) - { - List> outlinesByRows = new List>(); - - if (direction == OutlineAlignment.HorizontalFromLeftToRight || direction == OutlineAlignment.HorizontalFromRightToLeft) - { - List currentRowOutlines = new List(); - double drawingAreaWidth = drawingArea.MaximumPoint.X - drawingArea.MinimumPoint.X; - double currentRowWidth = -offset; - - foreach (Outline outline in outlines) - { - double outlineWidth = outline.MaximumPoint.X - outline.MinimumPoint.X; - currentRowWidth += outlineWidth + offset; - - if (currentRowWidth < drawingAreaWidth) - { - currentRowOutlines.Add(outline); - } - else - { - outlinesByRows.Add(currentRowOutlines); - currentRowOutlines = new List { outline }; - currentRowWidth = outlineWidth; - } - } - - if (currentRowOutlines.Any()) - outlinesByRows.Add(currentRowOutlines); - } - else if (direction == OutlineAlignment.VerticalFromLeftToRight || direction == OutlineAlignment.VerticalFromRightToLeft) - { - List currentRowOutlines = new List(); - double drawingAreaHeight = drawingArea.MaximumPoint.Y - drawingArea.MinimumPoint.Y; - double currentRowHeight = -offset; - - foreach (Outline outline in outlines) - { - double outlineHeight = outline.MaximumPoint.Y - outline.MinimumPoint.Y; - currentRowHeight += outlineHeight + offset; - - if (currentRowHeight < drawingAreaHeight) - { - currentRowOutlines.Add(outline); - } - else - { - outlinesByRows.Add(currentRowOutlines); - currentRowOutlines = new List { outline }; - currentRowHeight = outlineHeight; - } - } - - if (currentRowOutlines.Any()) - outlinesByRows.Add(currentRowOutlines); - } - - return outlinesByRows; - } - - /***************************************************/ - - private static List OutlinesInRow(this List outlines, XYZ startingPoint, double offset, OutlineAlignment direction) - { - List outlinesInRow = new List(); - - for (int i = 0; i < outlines.Count; i++) - { - Outline outline = outlines[i]; - double outlineWidth = outline.MaximumPoint.X - outline.MinimumPoint.X; - double outlineHeight = outline.MaximumPoint.Y - outline.MinimumPoint.Y; - - if (direction == OutlineAlignment.HorizontalFromLeftToRight) - { - double outlineTopLeftX; - - if (i == 0) - outlineTopLeftX = startingPoint.X; - else - outlineTopLeftX = startingPoint.X + offset; - - double outlineTopLeftY = startingPoint.Y; - - XYZ outlineNewCenterPoint = new XYZ(outlineTopLeftX + outlineWidth / 2, outlineTopLeftY - outlineHeight / 2, 0); - outline = outline.MovedToCenterPoint(outlineNewCenterPoint); - outlinesInRow.Add(outline); - - startingPoint = new XYZ(outlineTopLeftX + outlineWidth, outlineTopLeftY, 0); - } - else if (direction == OutlineAlignment.VerticalFromLeftToRight) - { - double outlineTopLeftX = startingPoint.X; - double outlineTopLeftY; - - if (i == 0) - outlineTopLeftY = startingPoint.Y; - else - outlineTopLeftY = startingPoint.Y - offset; - - XYZ outlineNewCenterPoint = new XYZ(outlineTopLeftX + outlineWidth / 2, outlineTopLeftY - outlineHeight / 2, 0); - outline = outline.MovedToCenterPoint(outlineNewCenterPoint); - outlinesInRow.Add(outline); - - startingPoint = new XYZ(outlineTopLeftX, outlineTopLeftY - outlineHeight, 0); - } - else if (direction == OutlineAlignment.HorizontalFromRightToLeft) - { - double outlineTopRightX; - - if (i == 0) - outlineTopRightX = startingPoint.X; - else - outlineTopRightX = startingPoint.X - offset; - - double outlineTopRightY = startingPoint.Y; - - XYZ outlineNewCenterPoint = new XYZ(outlineTopRightX - outlineWidth / 2, outlineTopRightY - outlineHeight / 2, 0); - outline = outline.MovedToCenterPoint(outlineNewCenterPoint); - outlinesInRow.Add(outline); - - startingPoint = new XYZ(outlineTopRightX - outlineWidth, outlineTopRightY, 0); - } - else if (direction == OutlineAlignment.VerticalFromRightToLeft) - { - double outlineTopRightX = startingPoint.X; - double outlineTopRightY; - - if (i == 0) - outlineTopRightY = startingPoint.Y; - else - outlineTopRightY = startingPoint.Y - offset; - - XYZ outlineNewCenterPoint = new XYZ(outlineTopRightX - outlineWidth / 2, outlineTopRightY - outlineHeight / 2, 0); - outline = outline.MovedToCenterPoint(outlineNewCenterPoint); - outlinesInRow.Add(outline); - - startingPoint = new XYZ(outlineTopRightX, outlineTopRightY - outlineHeight, 0); - } - } - - return outlinesInRow; - } - - /***************************************************/ - - private static Outline MovedToCenterPoint(this Outline outline, XYZ centerPoint) - { - double outlineWidth = outline.MaximumPoint.X - outline.MinimumPoint.X; - double outlineHeight = outline.MaximumPoint.Y - outline.MinimumPoint.Y; - XYZ halfDiagonal = new XYZ(outlineWidth / 2, outlineHeight / 2, 0); - - XYZ newMin = centerPoint - halfDiagonal; - XYZ newMax = centerPoint + halfDiagonal; - - return new Outline(newMin, newMax); - } - - /***************************************************/ - } -} - diff --git a/Revit_Core_Engine/Query/Bounds.cs b/Revit_Core_Engine/Query/Bounds.cs index 0e6cbd559..60d054122 100644 --- a/Revit_Core_Engine/Query/Bounds.cs +++ b/Revit_Core_Engine/Query/Bounds.cs @@ -87,6 +87,9 @@ public static BoundingBoxXYZ Bounds(this IEnumerable solids, Transform tr [Output("bounds", "Combined outline of the given outlines.")] public static Outline Bounds(this List outlines) { + if (outlines == null || !outlines.Any()) + return null; + Outline newOutline = new Outline(outlines[0]); foreach (Outline outline in outlines.Skip(1)) diff --git a/Revit_oM/Enums/OutlineAlignment.cs b/Revit_oM/Enums/OutlineAlignment.cs deleted file mode 100644 index d1b453cef..000000000 --- a/Revit_oM/Enums/OutlineAlignment.cs +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of the Buildings and Habitats object Model (BHoM) - * Copyright (c) 2015 - 2023, the respective contributors. All rights reserved. - * - * Each contributor holds copyright over their respective contributions. - * The project versioning (Git) records all such contribution source information. - * - * - * The BHoM is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3.0 of the License, or - * (at your option) any later version. - * - * The BHoM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this code. If not, see . - */ - -using System.ComponentModel; - -namespace BH.oM.Revit.Enums -{ - /***************************************************/ - - [Description("Direction of the sheet viewport alignment.")] - public enum OutlineAlignment - { - HorizontalFromLeftToRight, - VerticalFromLeftToRight, - HorizontalFromRightToLeft, - VerticalFromRightToLeft - } - - /***************************************************/ -} - - - From 4f63585894af46227a5a8ee72571858d3562c1b1 Mon Sep 17 00:00:00 2001 From: Michal Pekacki Date: Thu, 27 Jul 2023 10:45:43 +0200 Subject: [PATCH 10/10] added null check error --- Revit_Core_Engine/Query/Bounds.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Revit_Core_Engine/Query/Bounds.cs b/Revit_Core_Engine/Query/Bounds.cs index 60d054122..f79bc2fa2 100644 --- a/Revit_Core_Engine/Query/Bounds.cs +++ b/Revit_Core_Engine/Query/Bounds.cs @@ -88,7 +88,11 @@ public static BoundingBoxXYZ Bounds(this IEnumerable solids, Transform tr public static Outline Bounds(this List outlines) { if (outlines == null || !outlines.Any()) + { + BH.Engine.Base.Compute.RecordError("Outline collection cannot be null or empty."); return null; + } + Outline newOutline = new Outline(outlines[0]);