/// <summary> /// Convert a planar Rhino surface to a Nucleus planar region /// </summary> /// <param name="brep"></param> /// <returns></returns> public static PlanarRegion ConvertToPlanarRegion(RC.Brep brep, RC.BrepFace face) { //if (face.IsPlanar()) //{ int[] iEdges = face.AdjacentEdges(); RC.Curve[] curves = new RC.Curve[iEdges.Length]; for (int i = 0; i < iEdges.Length; i++) { RC.BrepEdge bEdge = brep.Edges[i]; curves[i] = bEdge; } var joined = RC.Curve.JoinCurves(curves); if (joined.Length > 0) { RC.Curve outer = outerCurve(joined); if (outer != null) { Curve boundary = Convert(outer); var result = new PlanarRegion(boundary); for (int i = 0; i < joined.Length; i++) { if (joined[i] != outer) { Curve voidCrv = Convert(joined[i]); result.Voids.Add(voidCrv); } } return(result); } } //} return(null); }
/***************************************************/ private static bool IsSameEdge(this RHG.Curve curve, RHG.BrepEdge edge) { double tolerance = BHG.Tolerance.Distance; RHG.Curve edgeCurve = edge.DuplicateCurve(); edgeCurve.Reverse(); RHG.BoundingBox bb1 = curve.GetBoundingBox(false); RHG.BoundingBox bb2 = edgeCurve.GetBoundingBox(false); if (bb1.Min.DistanceTo(bb2.Min) > tolerance || bb1.Max.DistanceTo(bb2.Max) > tolerance) { return(false); } int frameCount = 100; RHG.Point3d[] frames1, frames2; curve.DivideByCount(frameCount, false, out frames1); edgeCurve.DivideByCount(frameCount, false, out frames2); return(Enumerable.Range(0, frameCount - 1).All(i => frames1[i].DistanceTo(frames2[i]) <= tolerance)); }
/***************************************************/ /**** Private methods ****/ /***************************************************/ private static void AddBrepTrim(this RHG.Brep brep, RHG.BrepFace face, BHG.SurfaceTrim trim, RHG.BrepLoopType loopType) { RHG.BrepLoop loop = brep.Loops.Add(loopType, face); List <BHG.ICurve> subParts3d = trim.Curve3d.ISubParts().ToList(); List <BHG.ICurve> subParts2d = trim.Curve2d.ISubParts().ToList(); double rhinoTolerance = Query.DocumentTolerance(); for (int i = 0; i < subParts3d.Count; i++) { BHG.ICurve bhc = subParts3d[i]; RHG.Curve rhc = bhc.IToRhino(); int startId = brep.AddVertex(rhc.PointAtStart); int endId = brep.AddVertex(rhc.PointAtEnd); RHG.BrepTrim rhTrim; RHG.Curve rhc2d = subParts2d[i].IToRhino(); rhc2d.ChangeDimension(2); int crv2d = brep.Curves2D.Add(rhc2d); if (rhc.IsValid) { bool rev3d = true; RHG.BrepEdge edge = null; foreach (RHG.BrepEdge e in brep.Edges) { if (e.StartVertex.VertexIndex == endId && e.EndVertex.VertexIndex == startId && rhc.IsSameEdge(e)) { edge = e; break; } } if (edge == null) { int crv = brep.Curves3D.Add(rhc); edge = brep.Edges.Add(startId, endId, crv, rhinoTolerance); rev3d = false; } rhTrim = brep.Trims.Add(edge, rev3d, loop, crv2d); } else { rhTrim = brep.Trims.AddSingularTrim(brep.Vertices[startId], loop, RHG.IsoStatus.None, crv2d); } rhTrim.SetTolerances(rhinoTolerance, rhinoTolerance); //TODO: In Rhino 6 this could be replaced with Surface.IsIsoParametric(Curve) RHG.Point3d start = rhc2d.PointAtStart; RHG.Point3d end = rhc2d.PointAtEnd; if (rhc2d.IsLinear()) { if (Math.Abs(start.X - end.X) <= rhinoTolerance) { RHG.Interval domainU = brep.Surfaces[face.SurfaceIndex].Domain(0); if (Math.Abs(start.X - domainU.Min) <= rhinoTolerance) { rhTrim.IsoStatus = RHG.IsoStatus.West; } else if (Math.Abs(start.X - domainU.Max) <= rhinoTolerance) { rhTrim.IsoStatus = RHG.IsoStatus.East; } else { rhTrim.IsoStatus = RHG.IsoStatus.X; } } else if (Math.Abs(start.Y - end.Y) <= rhinoTolerance) { RHG.Interval domainV = brep.Surfaces[face.SurfaceIndex].Domain(1); if (Math.Abs(start.Y - domainV.Min) <= rhinoTolerance) { rhTrim.IsoStatus = RHG.IsoStatus.South; } else if (Math.Abs(start.Y - domainV.Max) <= rhinoTolerance) { rhTrim.IsoStatus = RHG.IsoStatus.North; } else { rhTrim.IsoStatus = RHG.IsoStatus.Y; } } } } }