Exemplo n.º 1
0
        public static PlanarSurface PlanarSurface(ICurve externalBoundary, List <ICurve> internalBoundaries = null, double tolerance = Tolerance.Distance)
        {
            if (externalBoundary == null || internalBoundaries == null || internalBoundaries.Where(x => x != null).Count() == 0)
            {
                BH.Engine.Reflection.Compute.RecordError("Cannot create planar surface from null curves.");
                return(null);
            }

            //--------------Planar-External-Boundary-----------------------//
            if (!externalBoundary.IIsPlanar(tolerance))
            {
                Reflection.Compute.RecordError("External edge curve is not planar");
                return(null);
            }

            //---------------Closed-External-Boundary-----------------------//
            if (!externalBoundary.IIsClosed(tolerance))
            {
                Reflection.Compute.RecordError("External edge curve is not closed");
                return(null);
            }

            //--------------SelfIntersecting-External-Boundary--------------//
            if (!externalBoundary.ISubParts().Any(y => y is NurbsCurve) && externalBoundary.IIsSelfIntersecting(tolerance))
            {
                Reflection.Compute.RecordError("The provided external boundary is self-intersecting.");
                return(null);
            }

            internalBoundaries = internalBoundaries ?? new List <ICurve>();

            //----------------Closed-Internal-Boundaries--------------------//
            int count = internalBoundaries.Count;

            internalBoundaries = internalBoundaries.Where(x => x.IIsClosed(tolerance)).ToList();

            if (internalBoundaries.Count != count)
            {
                Reflection.Compute.RecordWarning("At least one of the internal boundaries is not closed and has been ignored on creation of the planar surface.");
            }

            //---------------Coplanar-Internal-Boundaries-------------------//
            count = internalBoundaries.Count;

            Plane p = externalBoundary.IFitPlane(tolerance);

            internalBoundaries = internalBoundaries.Where(x => x.IIsInPlane(p, tolerance)).ToList();

            if (internalBoundaries.Count != count)
            {
                Reflection.Compute.RecordWarning("At least one of the internal boundaries is not coplanar with the external edge curve and has been ignored on creation of the planar surface.");
            }

            //--------------Unsupported-Internal-Boundaries-Warning---------//
            if (internalBoundaries.SelectMany(x => x.ISubParts()).Any(x => x is NurbsCurve || x is Ellipse))
            {
                Reflection.Compute.RecordWarning("At least one of the internal boundaries is a NurbsCurve or Ellipse and has not been checked for validity on creation of the planar surface.");
            }

            //--------------Self-Intersecting-Internal-Boundaries-----------//
            count = internalBoundaries.Count;

            internalBoundaries = internalBoundaries.Where(x => x.ISubParts().Any(y => y is NurbsCurve) || !x.IIsSelfIntersecting(tolerance)).ToList();

            if (internalBoundaries.Count != count)
            {
                Reflection.Compute.RecordWarning("At least one of the internal boundaries is self-intersecting and has been ignored on creation of the planar surface.");
            }

            //--------------Overlapping-Internal-Boundaries-----------------//
            count = internalBoundaries.Count;

            internalBoundaries = internalBoundaries.Where(x => x.ISubParts().Any(y => y is NurbsCurve || y is Ellipse))
                                 .Concat(internalBoundaries.Where(x => x.ISubParts().All(y => !(y is NurbsCurve) && !(y is Ellipse))).BooleanUnion()).ToList();

            if (internalBoundaries.Count != count)
            {
                Reflection.Compute.RecordWarning("At least one of the internalBoundaries was overlapping another one. BooleanUnion was used to resolve it.");
            }

            //--------------Unsupported-External-Boundary-------------------//
            if (externalBoundary.ISubParts().Any(x => x is NurbsCurve || x is Ellipse))
            {
                Reflection.Compute.RecordWarning("External boundary is a nurbs curve or Ellipse. Necessary checks to ensure validity of a planar surface based on nurbs curve cannot be run, therefore correctness of the surface boundaries is not guaranteed.");
                // External done
                return(new PlanarSurface(externalBoundary, internalBoundaries));
            }

            //-------------------Internal-Boundary-Curves-------------------//
            //--------------Overlapping-External-Boundary-Curve-------------//
            for (int i = 0; i < internalBoundaries.Count; i++)
            {
                ICurve intCurve = internalBoundaries[i];
                if (intCurve.ISubParts().Any(x => x is NurbsCurve || x is Ellipse))
                {
                    continue;
                }

                if (externalBoundary.ICurveIntersections(intCurve, tolerance).Count != 0)
                {
                    externalBoundary = externalBoundary.BooleanDifference(new List <ICurve>()
                    {
                        intCurve
                    }).Single();
                    internalBoundaries.RemoveAt(i);
                    i--;
                    Reflection.Compute.RecordWarning("At least one of the internalBoundaries is intersecting the externalBoundary. BooleanDifference was used to resolve the issue.");
                }
            }

            //--------------------Internal-Boundaries-----------------------//
            //---------------Contained-By-External-Boundary-----------------//
            count = internalBoundaries.Count;

            internalBoundaries = internalBoundaries.Where(x => x.ISubParts().Any(y => y is NurbsCurve || y is Ellipse) || externalBoundary.IIsContaining(x, true, tolerance)).ToList();

            if (internalBoundaries.Count != count)
            {
                Reflection.Compute.RecordWarning("At least one of the internalBoundaries is not contained by the externalBoundary. And have been disregarded.");
            }

            //------------------Return-Valid-Surface------------------------//
            return(new PlanarSurface(externalBoundary, internalBoundaries));
        }