diff --git a/OpenMEPRevit/ClassModel/GridItem.cs b/OpenMEPRevit/ClassModel/GridItem.cs index bb62b38..25040c2 100644 --- a/OpenMEPRevit/ClassModel/GridItem.cs +++ b/OpenMEPRevit/ClassModel/GridItem.cs @@ -6,11 +6,11 @@ namespace OpenMEPRevit.ClassModel; [IsVisibleInDynamoLibrary(false)] public class GridItem { - public Autodesk.Revit.DB.Grid Grid { get; set; } + public Grid? Grid { get; set; } public bool IsHorizontal => Direction(Grid.Curve)!.IsAlmostEqualTo(XYZ.BasisX); - public GridItem(Autodesk.Revit.DB.Grid grid) + public GridItem(Grid? grid) { Grid = grid; } diff --git a/OpenMEPRevit/Element/Element.cs b/OpenMEPRevit/Element/Element.cs index f8bac10..8bb8904 100644 --- a/OpenMEPRevit/Element/Element.cs +++ b/OpenMEPRevit/Element/Element.cs @@ -11,6 +11,7 @@ using Grid = Autodesk.Revit.DB.Grid; using Level = Autodesk.Revit.DB.Level; using Point = Autodesk.DesignScript.Geometry.Point; +using Revision = Revit.Elements.Revision; namespace OpenMEPRevit.Element; @@ -168,12 +169,106 @@ private Element() }; } + /// + /// Get the location of the element belong to the grid line with the closest distance + /// the location include the top, bottom, left, right grid line + /// + /// the elements + /// list grids need to check with + /// + [NodeCategory("Query")] + [MultiReturn("TopGrid", "BottomGrid", "LeftGrid", "RightGrid")] + public static Dictionary GetLocationGridLine(Revit.Elements.Element element,List grids) + { + var gridItems = grids.Select(x => new GridItem(x.InternalElement as Grid)).ToList(); + XYZ? location = GetLocation(element)?.ToXyz(); + if (location == null) + { + return new Dictionary() + { + { "TopGrid", null }, + { "BottomGrid", null }, + { "LeftGrid", null }, + { "RightGrid", null } + }; + } + + Grid? topGrid = null; + Grid? bottomGrid = null; + Grid? leftGrid = null; + Grid? rightGrid = null; + + var xGrids = gridItems.Where(x => x.IsHorizontal).ToList(); + var yGrids = gridItems.Where(x => !x.IsHorizontal).ToList(); + // top + double locationY = location.Y; + double yDistance = double.MaxValue; + foreach (var item in xGrids) + { + double yCurrent = item.Grid.Curve.GetEndPoint(0).Y; + double distanceTo = item.DistanceTo(location); + if (yCurrent >= locationY && distanceTo <= yDistance) + { + yDistance = distanceTo; + topGrid = item.Grid; + } + } + + // bottom + yDistance = double.MaxValue; + foreach (var item in xGrids) + { + double yCurrent = item.Grid.Curve.GetEndPoint(0).Y; + double distanceTo = item.DistanceTo(location); + if (yCurrent <= locationY && distanceTo <= yDistance) + { + yDistance = distanceTo; + bottomGrid = item.Grid; + } + } + + // left + double locationX = location.X; + double xDistance = double.MaxValue; + foreach (var item in yGrids) + { + double xCurrent = item.Grid.Curve.GetEndPoint(0).X; + double distanceTo = item.DistanceTo(location); + if (xCurrent <= locationX && distanceTo <= xDistance) + { + xDistance = distanceTo; + leftGrid = item.Grid; + } + } + + // right + xDistance = double.MaxValue; + foreach (var item in yGrids) + { + double xCurrent = item.Grid.Curve.GetEndPoint(0).X; + double distanceTo = item.DistanceTo(location); + if (xCurrent >= locationX && distanceTo <= xDistance) + { + xDistance = distanceTo; + rightGrid = item.Grid; + } + } + + return new Dictionary() + { + { "TopGrid", topGrid?.ToDynamoType() }, + { "BottomGrid", bottomGrid?.ToDynamoType() }, + { "LeftGrid", leftGrid?.ToDynamoType() }, + { "RightGrid", rightGrid?.ToDynamoType() } + }; + } + private static List GetGrids(Autodesk.Revit.DB.Document doc) { List gridItems = new List(); FilteredElementCollector collector = new FilteredElementCollector(doc); - var grids = collector.OfClass(typeof(Grid)).Cast().ToList(); - foreach (Grid grid in grids) + List grids = collector.OfClass(typeof(Grid)).Cast().ToList(); + foreach (Grid? grid in grids) { gridItems.Add(new GridItem(grid)); }