Esempio n. 1
0
        public static FreeFormProfile FreeFormProfile(IEnumerable <ICurve> edges)
        {
            IEnumerable <ICurve> result = edges.ToList();

            List <Point> cPoints = edges.SelectMany(x => x.IControlPoints()).ToList();

            // Any Point not on the XY-Plane
            if (cPoints.Any(x => Math.Abs(x.Z) > Tolerance.Distance))
            {
                // Is Planar
                Plane plane         = Compute.FitPlane(cPoints);
                bool  failedProject = false;
                if (cPoints.Any(x => x.Distance(plane) > Tolerance.Distance))
                {
                    Reflection.Compute.RecordWarning("The Profiles curves are not Planar");
                    try
                    {
                        // Get biggest contributing curve and fit a plane to it
                        plane = Compute.IJoin(edges.ToList()).OrderBy(x => x.Area()).Last().ControlPoints().FitPlane();

                        result = edges.Select(x => x.IProject(plane)).ToList();
                        Reflection.Compute.RecordWarning("The Profiles curves have been projected onto a plane fitted through the biggest curve's control points.");
                        cPoints = result.SelectMany(x => x.IControlPoints()).ToList();
                    }
                    catch
                    {
                        failedProject = true;
                    }
                }

                if (!failedProject)
                {
                    // Is Coplanar with XY
                    if (plane.Normal.IsParallel(oM.Geometry.Vector.ZAxis) == 0)
                    {
                        Reflection.Compute.RecordWarning("The Profiles curves are not coplanar with the XY-Plane. Automatic orientation has occured.");

                        plane.Normal = plane.Normal.Z > 0 ? plane.Normal : -plane.Normal;
                        double rad = plane.Normal.Angle(oM.Geometry.Vector.ZAxis);

                        Line axis = plane.PlaneIntersection(oM.Geometry.Plane.XY);
                        result  = result.Select(x => x.IRotate(axis.Start, axis.TangentAtParameter(0), rad)).ToList();
                        cPoints = result.SelectMany(x => x.IControlPoints()).ToList();
                    }

                    // Is on XY
                    if (cPoints.FirstOrDefault().Distance(oM.Geometry.Plane.XY) > Tolerance.Distance)
                    {
                        Reflection.Compute.RecordWarning("The Profiles curves are not on the XY-Plane. Automatic translation has occured.");
                        Point  p = cPoints.FirstOrDefault();
                        Vector v = new oM.Geometry.Vector()
                        {
                            X = p.X, Y = p.Y, Z = p.Z
                        };

                        result = result.Select(x => x.ITranslate(-v)).ToList();
                    }
                }
            }

            if (!result.Any(x => x.ISubParts().Any(y => y is NurbsCurve)))
            {
                // Join the curves
                List <PolyCurve> joinedCurves = Compute.IJoin(result.ToList()).ToList();

                // Is Closed
                if (joinedCurves.Any(x => !x.IsClosed()))
                {
                    Reflection.Compute.RecordWarning("The Profiles curves does not form closed curves");
                }

                // Has non-zero area
                if (joinedCurves.Any(x => x.IArea() < Tolerance.Distance))
                {
                    Reflection.Compute.RecordWarning("One or more of the profile curves have close to zero area.");
                }

                if (!joinedCurves.Any(x => x.ISubParts().Any(y => y is Ellipse)))
                {
                    // Check curve curve Intersections
                    bool intersects = false;
                    for (int i = 0; i < joinedCurves.Count - 1; i++)
                    {
                        for (int j = i + 1; j < joinedCurves.Count; j++)
                        {
                            if (joinedCurves[i].CurveIntersections(joinedCurves[j]).Count > 0)
                            {
                                intersects = true;
                                break;
                            }
                        }
                        if (intersects)
                        {
                            break;
                        }
                    }
                    if (intersects)
                    {
                        Engine.Reflection.Compute.RecordWarning("The Profiles curves are intersecting eachother.");
                    }
                }
                // Is SelfInteersecting
                if (joinedCurves.Any(x => x.IsSelfIntersecting()))
                {
                    Engine.Reflection.Compute.RecordWarning("One or more of the Profiles curves is intersecting itself.");
                }
            }

            return(new FreeFormProfile(result));
        }