示例#1
0
        public static Panel SimilarPanel(this Geometry.Spatial.Face3D face3D, Dictionary <Panel, Geometry.Spatial.Face3D> panelsDictionary, double distanceTolerance = Core.Tolerance.MacroDistance, double coplanarTolerance = Core.Tolerance.MacroDistance)
        {
            if (face3D == null || panelsDictionary == null)
            {
                return(null);
            }

            Geometry.Spatial.Plane plane = face3D.GetPlane();
            double area = face3D.GetArea();

            Geometry.Planar.IClosed2D closed2D_1       = Geometry.Spatial.Query.Convert(plane, face3D.GetExternalEdge3D());
            Geometry.Planar.Point2D   point2D_Internal = closed2D_1.GetInternalPoint2D();

            double areaDifferece_Min = double.MaxValue;
            Panel  result            = null;

            foreach (KeyValuePair <Panel, Geometry.Spatial.Face3D> keyValuePair in panelsDictionary)
            {
                if (keyValuePair.Value == null)
                {
                    continue;
                }

                double areaDifference = System.Math.Abs(keyValuePair.Value.GetArea() - area);

                if (areaDifferece_Min < areaDifference)
                {
                    continue;
                }

                Geometry.Spatial.Face3D face3D_Temp = keyValuePair.Value;
                Geometry.Spatial.Plane  plane_Temp  = face3D_Temp.GetPlane();

                if (!plane.Coplanar(plane_Temp, coplanarTolerance))
                {
                    continue;
                }

                Geometry.Spatial.Point3D point3D_Origin  = plane_Temp.Origin;
                Geometry.Spatial.Point3D point3D_Project = Geometry.Spatial.Query.Project(plane, point3D_Origin);
                if (point3D_Origin.Distance(point3D_Project) > distanceTolerance)
                {
                    continue;
                }

                Geometry.Planar.IClosed2D closed2D_2 = Geometry.Spatial.Query.Convert(plane, face3D_Temp.GetExternalEdge3D());
                if (closed2D_2.Inside(point2D_Internal))
                {
                    result            = keyValuePair.Key;
                    areaDifferece_Min = areaDifference;
                }
            }

            return(result);
        }
示例#2
0
        public static List <Shell> Shells(this Document document, IEnumerable <Autodesk.Revit.DB.Mechanical.Space> spaces = null, double offset = 0.1, double snapTolerance = Core.Tolerance.MacroDistance, double tolerance = Core.Tolerance.Distance)
        {
            if (document == null)
            {
                return(null);
            }

            //Collecting Space list
            List <Autodesk.Revit.DB.Mechanical.Space> spaces_Temp = new FilteredElementCollector(document).OfCategory(BuiltInCategory.OST_MEPSpaces).Cast <Autodesk.Revit.DB.Mechanical.Space>().ToList();

            if (spaces != null)
            {
                List <Autodesk.Revit.DB.Mechanical.Space> spaces_New = new List <Autodesk.Revit.DB.Mechanical.Space>();
                foreach (Autodesk.Revit.DB.Mechanical.Space space in spaces)
                {
                    int index = spaces_Temp.FindIndex(x => x.Id.IntegerValue == space.Id.IntegerValue);
                    if (index != -1)
                    {
                        spaces_New.Add(spaces_Temp[index]);
                    }
                }
                spaces_Temp = spaces_New;
            }

            if (spaces_Temp == null || spaces_Temp.Count == 0)
            {
                return(null);
            }

            //Dictionary of bottom elevations and tuples (top elevation, location 2D, Space) (Metric Units)
            Dictionary <double, List <Tuple <double, Geometry.Planar.Point2D, Autodesk.Revit.DB.Mechanical.Space> > > dictionary = new Dictionary <double, List <Tuple <double, Geometry.Planar.Point2D, Autodesk.Revit.DB.Mechanical.Space> > >();

            //Space cut elevations (Imperial Units)
            HashSet <double> cutElevations = new HashSet <double>();

            //Collecting Spaces data
            foreach (Autodesk.Revit.DB.Mechanical.Space space in spaces_Temp)
            {
                XYZ xyz = (space.Location as LocationPoint)?.Point;
                if (xyz == null)
                {
                    continue;
                }

                double elevation_Top = double.NaN;

                Parameter parameter = space.get_Parameter(BuiltInParameter.ROOM_UPPER_LEVEL);
                if (parameter != null && parameter.HasValue)
                {
                    ElementId elementId = parameter.AsElementId();
                    if (elementId != null && elementId != ElementId.InvalidElementId)
                    {
                        Level level = document.GetElement(elementId) as Level;
                        if (level != null)
                        {
#if Revit2017 || Revit2018 || Revit2019 || Revit2020
                            elevation_Top = UnitUtils.ConvertFromInternalUnits(level.Elevation, DisplayUnitType.DUT_METERS);
#else
                            elevation_Top = UnitUtils.ConvertFromInternalUnits(level.Elevation, UnitTypeId.Meters);
#endif
                        }
                    }
                }

                BoundingBoxXYZ boundingBoxXYZ = space.get_BoundingBox(null);

                if (double.IsNaN(elevation_Top) && boundingBoxXYZ != null)
                {
#if Revit2017 || Revit2018 || Revit2019 || Revit2020
                    elevation_Top = UnitUtils.ConvertFromInternalUnits(boundingBoxXYZ.Max.Z, DisplayUnitType.DUT_METERS);
#else
                    elevation_Top = UnitUtils.ConvertFromInternalUnits(boundingBoxXYZ.Max.Z, UnitTypeId.Meters);
#endif
                }

                double elevation_Bottom = double.NaN;

                if (boundingBoxXYZ != null)
                {
#if Revit2017 || Revit2018 || Revit2019 || Revit2020
                    elevation_Bottom = UnitUtils.ConvertFromInternalUnits(boundingBoxXYZ.Min.Z, DisplayUnitType.DUT_METERS);
#else
                    elevation_Bottom = UnitUtils.ConvertFromInternalUnits(boundingBoxXYZ.Min.Z, UnitTypeId.Meters);
#endif
                }


                if (double.IsNaN(elevation_Bottom))
                {
                    ElementId elementId = space.LevelId;
                    if (elementId != null && elementId != ElementId.InvalidElementId)
                    {
                        Level level = document.GetElement(elementId) as Level;
#if Revit2017 || Revit2018 || Revit2019 || Revit2020
                        elevation_Bottom = UnitUtils.ConvertFromInternalUnits(level.Elevation, DisplayUnitType.DUT_METERS);
#else
                        elevation_Bottom = UnitUtils.ConvertFromInternalUnits(level.Elevation, UnitTypeId.Meters);
#endif
                    }
                }

                Point3D point3D = Geometry.Revit.Convert.ToSAM(xyz);
                if (point3D == null)
                {
                    continue;
                }

                Geometry.Planar.Point2D point2D = Geometry.Spatial.Plane.WorldXY.Convert(point3D);
                if (point2D == null)
                {
                    continue;
                }

#if Revit2017 || Revit2018 || Revit2019 || Revit2020
                cutElevations.Add(UnitUtils.ConvertToInternalUnits(elevation_Bottom + offset, DisplayUnitType.DUT_METERS));
#else
                cutElevations.Add(UnitUtils.ConvertToInternalUnits(elevation_Bottom + offset, UnitTypeId.Meters));
#endif

                if (!dictionary.TryGetValue(elevation_Bottom, out List <Tuple <double, Geometry.Planar.Point2D, Autodesk.Revit.DB.Mechanical.Space> > tuples))
                {
                    tuples = new List <Tuple <double, Geometry.Planar.Point2D, Autodesk.Revit.DB.Mechanical.Space> >();
                    dictionary[elevation_Bottom] = tuples;
                }
                tuples.Add(new Tuple <double, Geometry.Planar.Point2D, Autodesk.Revit.DB.Mechanical.Space>(elevation_Top, point2D, space));
            }

            //Collecting Revit Walls
            List <Autodesk.Revit.DB.Wall> walls = new FilteredElementCollector(document).OfClass(typeof(Autodesk.Revit.DB.Wall)).Cast <Autodesk.Revit.DB.Wall>().ToList();
            if (walls == null || walls.Count == 0)
            {
                return(null);
            }

            //Converting Revit Walls to SAM Panels
            List <Panel> panels = new List <Panel>();
            foreach (Autodesk.Revit.DB.Wall wall in walls)
            {
                BoundingBoxXYZ boundingBoxXYZ = wall?.get_BoundingBox(null);
                if (boundingBoxXYZ == null)
                {
                    continue;
                }

                bool valid = false;
                foreach (double cutElevation in cutElevations)
                {
                    if (boundingBoxXYZ.Max.Z >= cutElevation && boundingBoxXYZ.Min.Z <= cutElevation)
                    {
                        valid = true;
                        break;
                    }
                }

                if (!valid)
                {
                    continue;
                }

                List <Panel> panels_Wall = wall.ToSAM(new Core.Revit.ConvertSettings(true, false, false));
                if (panels_Wall == null || panels_Wall.Count == 0)
                {
                    continue;
                }

                panels.AddRange(panels_Wall);
            }

            if (panels == null || panels.Count == 0)
            {
                return(null);
            }

            List <Shell> result = new List <Shell>();

            //Inerating through elevations and Spaces data
            foreach (KeyValuePair <double, List <Tuple <double, Geometry.Planar.Point2D, Autodesk.Revit.DB.Mechanical.Space> > > keyValuePair in dictionary)
            {
                double elevation_Bottom = keyValuePair.Key;
                double elevation_Cut    = elevation_Bottom + offset;

                Geometry.Spatial.Plane plane_Cut = Geometry.Spatial.Plane.WorldXY.GetMoved(new Vector3D(0, 0, elevation_Cut)) as Geometry.Spatial.Plane;

                List <Geometry.Planar.Segment2D> segment2Ds = new List <Geometry.Planar.Segment2D>();
                foreach (Panel panel in panels)
                {
                    IClosedPlanar3D closedPlanar3D = panel?.GetFace3D()?.GetExternalEdge3D();
                    if (closedPlanar3D == null)
                    {
                        continue;
                    }

                    PlanarIntersectionResult planarIntersectionResult = plane_Cut.PlanarIntersectionResult(closedPlanar3D);
                    if (planarIntersectionResult == null || !planarIntersectionResult.Intersecting)
                    {
                        continue;
                    }

                    List <Geometry.Planar.ISegmentable2D> segmentable2Ds_Temp = planarIntersectionResult.GetGeometry2Ds <Geometry.Planar.ISegmentable2D>();
                    if (segmentable2Ds_Temp == null || segmentable2Ds_Temp.Count == 0)
                    {
                        continue;
                    }

                    segmentable2Ds_Temp?.ForEach(x => segment2Ds.AddRange(x.GetSegments()));
                }

                if (panels == null || panels.Count == 0)
                {
                    continue;
                }

                segment2Ds = Geometry.Planar.Query.Split(segment2Ds, tolerance);

                segment2Ds = Geometry.Planar.Query.Snap(segment2Ds, true, snapTolerance);

                List <Tuple <Geometry.Planar.BoundingBox2D, Geometry.Planar.Polygon2D> > tuples_Polygon2D = Geometry.Planar.Create.Polygon2Ds(segment2Ds)?.ConvertAll(x => new Tuple <Geometry.Planar.BoundingBox2D, Geometry.Planar.Polygon2D>(x.GetBoundingBox(tolerance), x));
                if (tuples_Polygon2D == null || tuples_Polygon2D.Count == 0)
                {
                    continue;
                }

                Geometry.Spatial.Plane plane_Bottom = Geometry.Spatial.Plane.WorldXY.GetMoved(new Vector3D(0, 0, elevation_Bottom)) as Geometry.Spatial.Plane;

                List <Tuple <double, Geometry.Planar.Point2D, Autodesk.Revit.DB.Mechanical.Space> > tuples_Space = keyValuePair.Value;
                while (tuples_Space.Count > 0)
                {
                    Tuple <double, Geometry.Planar.Point2D, Autodesk.Revit.DB.Mechanical.Space> tuple = tuples_Space[0];
                    tuples_Space.RemoveAt(0);

                    Geometry.Spatial.Plane plane_Top = Geometry.Spatial.Plane.WorldXY.GetMoved(new Vector3D(0, 0, tuple.Item1)) as Geometry.Spatial.Plane;

                    Geometry.Planar.Point2D point2D = tuple.Item2;

                    List <Tuple <Geometry.Planar.BoundingBox2D, Geometry.Planar.Polygon2D> > tuples_Polygon2D_External = tuples_Polygon2D.FindAll(x => x.Item1.Inside(point2D, tolerance)).FindAll(x => x.Item2.Inside(point2D, tolerance));
                    tuples_Polygon2D_External.Sort((x, y) => x.Item1.GetArea().CompareTo(y.Item1.GetArea()));

                    Tuple <Geometry.Planar.BoundingBox2D, Geometry.Planar.Polygon2D> tuple_Polygon2D_External = tuples_Polygon2D_External.FirstOrDefault();
                    if (tuple_Polygon2D_External == null)
                    {
                        continue;
                    }

                    List <Tuple <Geometry.Planar.BoundingBox2D, Geometry.Planar.Polygon2D> > tuples_Polygon2D_Internal = new List <Tuple <Geometry.Planar.BoundingBox2D, Geometry.Planar.Polygon2D> >();
                    foreach (Tuple <Geometry.Planar.BoundingBox2D, Geometry.Planar.Polygon2D> tuple_Polygon2D in tuples_Polygon2D)
                    {
                        if (tuple_Polygon2D == tuple_Polygon2D_External)
                        {
                            continue;
                        }

                        if (tuple_Polygon2D_External.Item1.Inside(tuple_Polygon2D.Item1, tolerance) && tuple_Polygon2D_External.Item2.Inside(tuple_Polygon2D.Item2, tolerance))
                        {
                            tuples_Polygon2D_Internal.Add(tuple_Polygon2D);
                        }
                    }

                    List <Geometry.Planar.Face2D> face2Ds = Geometry.Planar.Query.Difference(new Geometry.Planar.Face2D(tuple_Polygon2D_External.Item2), tuples_Polygon2D_Internal.ConvertAll(x => new Geometry.Planar.Face2D(x.Item2)), tolerance);
                    if (face2Ds == null || face2Ds.Count == 0)
                    {
                        continue;
                    }


                    foreach (Geometry.Planar.Face2D face2D in face2Ds)
                    {
                        tuples_Space.RemoveAll(x => face2D.Inside(x.Item2, tolerance));
                    }

                    List <Face3D> face3Ds = new List <Face3D>();
                    face3Ds.AddRange(face2Ds.ConvertAll(x => new Face3D(plane_Bottom, x)));
                    face3Ds.AddRange(face2Ds.ConvertAll(x => new Face3D(plane_Top, x)));

                    List <Shell> shells_Temp = Geometry.Spatial.Create.Shells(face3Ds, new double[] { elevation_Bottom }, offset, snapTolerance: snapTolerance, tolerance_Distance: tolerance);
                    if (shells_Temp == null || shells_Temp.Count == 0)
                    {
                        continue;
                    }

                    result.AddRange(shells_Temp);
                }
            }

            return(result);
        }
示例#3
0
        public static List <Panel> SimilarPanels(this Geometry.Spatial.Face3D face3D, Dictionary <Panel, Geometry.Spatial.Face3D> panelsDictionary, double distanceTolerance = Tolerance.MacroDistance, double coplanarTolerance = Tolerance.MacroDistance)
        {
            if (face3D == null || panelsDictionary == null)
            {
                return(null);
            }

            Geometry.Spatial.Plane plane = face3D.GetPlane();

            Geometry.Planar.IClosed2D closed2D_1       = Geometry.Spatial.Query.Convert(plane, face3D.GetExternalEdge3D());
            Geometry.Planar.Point2D   point2D_Internal = closed2D_1.GetInternalPoint2D();

            double area = face3D.GetArea();

            List <Tuple <Panel, double> > tuples = new List <Tuple <Panel, double> >();

            foreach (KeyValuePair <Panel, Geometry.Spatial.Face3D> keyValuePair in panelsDictionary)
            {
                if (keyValuePair.Value == null)
                {
                    continue;
                }

                Geometry.Spatial.Face3D face3D_Temp = keyValuePair.Value;
                Geometry.Spatial.Plane  plane_Temp  = face3D_Temp.GetPlane();

                if (!plane.Coplanar(plane_Temp, coplanarTolerance))
                {
                    continue;
                }

                Geometry.Spatial.Point3D point3D_Origin  = plane_Temp.Origin;
                Geometry.Spatial.Point3D point3D_Project = Geometry.Spatial.Query.Project(plane, point3D_Origin);
                if (point3D_Origin.Distance(point3D_Project) > distanceTolerance)
                {
                    continue;
                }

                Geometry.Planar.IClosed2D closed2D_2 = Geometry.Spatial.Query.Convert(plane, face3D_Temp.GetExternalEdge3D());
                if (closed2D_2.Inside(point2D_Internal))
                {
                    tuples.Add(new Tuple <Panel, double>(keyValuePair.Key, Math.Abs(keyValuePair.Value.GetArea() - area)));
                }
            }

            if (tuples == null || tuples.Count == 0)
            {
                return(null);
            }

            if (tuples.Count == 1)
            {
                return new List <Panel>()
                       {
                           tuples.First().Item1
                       }
            }
            ;

            tuples.Sort((x, y) => x.Item2.CompareTo(y.Item2));

            double       areatolerance = distanceTolerance * 10;
            List <Panel> result        = tuples.FindAll(x => x.Item2 < areatolerance).ConvertAll(x => x.Item1);

            if (result != null && result.Count > 0)
            {
                return(result);
            }

            return(new List <Panel>()
            {
                tuples.First().Item1
            });
        }
    }