コード例 #1
0
ファイル: SimilarPanel.cs プロジェクト: lanicon/SAM_Topologic
        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
        /// <summary>
        /// Converts Face3D to Wall
        /// </summary>
        /// <param name="face3D">SAM Geometry Face3D</param>
        /// <param name="document">Revit Document</param>
        /// <param name="wallType">Revit WallType. Default WallType will be used if null</param>
        /// <param name="level">Revit Level. Low Level for Face3D will be used if null</param>
        /// <returns>Revit Wall</returns>
        public static Autodesk.Revit.DB.Wall ToRevit_Wall(this Geometry.Spatial.Face3D face3D, Document document, Autodesk.Revit.DB.WallType wallType = null, Level level = null)
        {
            if (face3D == null || document == null)
            {
                return(null);
            }

            if (face3D.GetArea() < Core.Tolerance.MacroDistance)
            {
                return(null);
            }

            Geometry.Spatial.Vector3D normal = face3D.GetPlane().Normal;
            if (normal == null)
            {
                return(null);
            }

            if (wallType == null)
            {
                ElementId elementId = document.Settings.Categories.get_Item(BuiltInCategory.OST_Walls).Id;
                if (elementId != null && elementId != ElementId.InvalidElementId)
                {
                    elementId = document.GetDefaultFamilyTypeId(elementId);
                    if (elementId != null && elementId != ElementId.InvalidElementId)
                    {
                        wallType = document.GetElement(elementId) as Autodesk.Revit.DB.WallType;
                    }
                }
            }

            if (wallType == null)
            {
                return(null);
            }

            if (level == null)
            {
                double elevation = Geometry.Revit.Convert.ToRevit(face3D.GetBoundingBox().Min).Z;
                level = Core.Revit.Query.LowLevel(document, elevation);
            }

            if (level == null)
            {
                return(null);
            }

            List <CurveLoop> curveLoops = Geometry.Revit.Convert.ToRevit(face3D);

            curveLoops?.RemoveAll(x => x == null);
            if (curveLoops == null || curveLoops.Count == 0)
            {
                return(null);
            }

            XYZ xyz_Normal = Geometry.Revit.Convert.ToRevit(normal, false);

            if (curveLoops.Count == 1)
            {
                return(Autodesk.Revit.DB.Wall.Create(document, curveLoops[0].ToList(), wallType.Id, level.Id, false, xyz_Normal));
            }

            //The Wall.Create method requires the curveLoops to be in either all counter-clockwise direction or all clockwise direction.
            for (int i = 0; i < curveLoops.Count; i++)
            {
                if (curveLoops[i].IsCounterclockwise(xyz_Normal))
                {
                    curveLoops[i].Flip();
                }
            }

            List <Curve> curves = new List <Curve>();


            //According to https://forums.autodesk.com/t5/revit-api-forum/wall-create-by-profile/td-p/8961085
            //CurveLoops have to be organised in correct order. Hypothesis :
            //If the curveLoop contains 1 (or more) vertical Line(s), the vertical line should be the first to add to the List.
            foreach (CurveLoop curveLoop in curveLoops)
            {
                List <Curve> curves_Temp = curveLoop?.ToList();
                if (curveLoop == null)
                {
                    continue;
                }

                List <Curve> curves_Postponed = new List <Curve>();

                int startindex = 0;
                while (startindex < curves_Temp.Count)
                {
                    Curve curve = curves_Temp[startindex];
                    if (!(curve is Line))
                    {
                        curves_Postponed.Add(curve);
                        startindex++;
                        continue;
                    }
                    XYZ dir = curve.GetEndPoint(1).Subtract(curve.GetEndPoint(0)).Normalize();
                    if (!dir.IsAlmostEqualTo(XYZ.BasisZ) && !dir.IsAlmostEqualTo(XYZ.BasisZ.Negate()))
                    {
                        curves_Postponed.Add(curve);
                        startindex++;
                    }
                    else
                    {
                        break;
                    }
                }

                for (int i = startindex; i < curves_Temp.Count; i++)
                {
                    Curve curve = curves_Temp[i];
                    curves.Add(curve);
                }

                if (curves_Postponed.Count > 0)
                {
                    curves.AddRange(curves_Postponed);
                }
            }

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

            return(Autodesk.Revit.DB.Wall.Create(document, curves, wallType.Id, level.Id, false, xyz_Normal));
        }
コード例 #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
            });
        }
    }