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)); }