public GeometryConverter() { var ptConv = AddConverter(new PointConverter(_pt3dConv)); var curveConv = new CurveConverter(_pt3dConv, _arcConv, _lineConv); AddConverter(curveConv); var meshConv = AddConverter(new MeshConverter(_pt3fConv)); var surfaceConverter = new SurfaceConverter(curveConv, _vec3DConv, _pt3dConv); AddConverter(surfaceConverter); var brepConv = new BrepConverter(surfaceConverter, curveConv, _pt3dConv); AddConverter(brepConv); }
public static bool TryCreateBrepWithBuiltInMethods(pps.PolySurface pb, out Brep brep, SurfaceConverter surfConv, CurveConverter curveConv) { if (pb.Surfaces.Count <= 0) { brep = null; return(true); } brep = null; try { int attempts = 0; while (attempts < 15) { if (pb.Surfaces.Count == 1) { var surf = pb.Surfaces.FirstOrDefault(); brep = GetTrimmedBrep(surf, surfConv, curveConv); } else { for (int i = 0; i < pb.Surfaces.Count; i++) { pps.Surface s = pb.Surfaces[i]; var subrep = GetTrimmedBrep(s, surfConv, curveConv); if (!subrep.IsValid) { subrep.Repair(Rhino.RhinoMath.ZeroTolerance); } if (i == 0) { brep = subrep; } else { //brep = Brep.MergeSurfaces(brep, subrep, Rhino.RhinoMath.ZeroTolerance, // Rhino.RhinoMath.ZeroTolerance, Point2d.Unset, Point2d.Unset, 0.0, true) ?? // Brep.MergeSurfaces(brep, subrep, Rhino.RhinoMath.ZeroTolerance, Rhino.RhinoMath.ZeroTolerance) ?? // Brep.JoinBreps(new List<Brep>() { brep, subrep }, Rhino.RhinoMath.ZeroTolerance).First(); brep = Brep.MergeBreps(new List <Brep>() { brep, subrep }, Rhino.RhinoMath.ZeroTolerance); } } } attempts += 1; //not doing anymore attempts if this time was successful if (!brep.IsValid) { brep.Repair(Rhino.RhinoMath.ZeroTolerance); } if (brep.IsValid) { break; } } if (!brep.IsValid) { brep.Repair(Rhino.RhinoMath.ZeroTolerance); } return(brep.IsValid); } catch (Exception e) { brep = null; return(false); } }
public static Brep GetTrimmedBrep(pps.Surface surface, SurfaceConverter surfConv, CurveConverter curveConv) { var rhSurf = surfConv.FromPipe <Surface, pps.Surface>(surface); var brep = Brep.CreateFromSurface(rhSurf); if (!brep.IsValid) { brep.Repair(Rhino.RhinoMath.ZeroTolerance); } if (typeof(pps.NurbsSurface).IsAssignableFrom(surface.GetType()) && ((pps.NurbsSurface)surface).TrimCurves.Count > 0) { List <ppc.Curve> trims = ((pps.NurbsSurface)surface).TrimCurves; List <ppc.Curve> loops = brep.Faces.First().Loops.Select((l) => curveConv.ToPipe <Curve, ppc.Curve>(l.To3dCurve())).ToList(); if (!PipeDataUtil.EqualIgnoreOrder(loops, trims)) { var rhTrims = trims.Select((c) => { var cur = curveConv.FromPipe <Curve, ppc.Curve>(c); var cur2d = rhSurf.Pullback(cur, Rhino.RhinoMath.ZeroTolerance); return(rhSurf.Pushup(cur2d, Rhino.RhinoMath.ZeroTolerance)); }).ToList(); var faceToSplit = brep.Faces.First(); var brep2 = faceToSplit.Split(rhTrims, Rhino.RhinoMath.ZeroTolerance); if (brep2 != null && !brep2.IsValid) { brep2.Repair(Rhino.RhinoMath.ZeroTolerance); } if (brep2 != null && brep2.IsValid) { brep = GetEnclosedFacesAsBrep(brep2, rhTrims) ?? brep2; } } } return(brep); }
public SurfaceConverter(CurveConverter curveConv, Vector3DConverter vecConv, Point3dConverter ptConv) { //extrusion surfaces AddConverter(new PipeConverter <rh.Extrusion, pps.Extrusion>( (rhE) => { ppc.Line path = (ppc.Line)curveConv.ConvertToPipe <rh.Curve, ppc.Curve>(rhE.PathLineCurve()); pps.Extrusion extr = new pps.Extrusion(curveConv.ConvertToPipe <rh.Curve, ppc.Curve>(rhE.Profile3d(0, 0)), vecConv.ConvertToPipe <rh.Vector3d, pp.Vec>(rhE.PathTangent), path.Length); for (int i = 1; i < rhE.ProfileCount; i++) { extr.Holes.Add(curveConv.ConvertToPipe <rh.Curve, ppc.Curve>(rhE.Profile3d(i, 0))); } extr.CappedAtStart = rhE.IsCappedAtBottom; extr.CappedAtEnd = rhE.IsCappedAtTop; extr.SurfaceNormal = vecConv.ToPipe <rh.Vector3d, pp.Vec>(rhE.NormalAt(rhE.Domain(0).Mid, rhE.Domain(1).Mid)); return(extr); }, (ppE) => { if (1 - ppE.Direction.Dot(new pp.Vec(0, 0, 1)) > 1e-3) { //the extrusion is not vertical throw new InvalidOperationException("Cannot create this extrusion. " + "Try converting it into a polysurface and pushing it again"); } var profile = curveConv.FromPipe <rh.Curve, ppc.Curve>(ppE.ProfileCurve); rh.Extrusion extr = rh.Extrusion.Create(profile, ppE.Height, ppE.CappedAtEnd || ppE.CappedAtStart); ppE.Holes.ForEach((h) => extr.AddInnerProfile(curveConv.FromPipe <rh.Curve, ppc.Curve>(h))); //extr.SetOuterProfile(profile, false); //extr.SetPathAndUp(profile.PointAtStart, profile.PointAtStart + pathVec, pathVec); string msg; if (!extr.IsValidWithLog(out msg)) { System.Diagnostics.Debug.WriteLine(msg); throw new InvalidOperationException("Cannot create a valid extrusion from the received data: \n" + msg); } var rhNorm = extr.NormalAt(extr.Domain(0).Mid, extr.Domain(1).Mid); if (rh.Vector3d.Multiply(rhNorm, vecConv.FromPipe <rh.Vector3d, pp.Vec>(ppE.SurfaceNormal)) < 0) { //extrusions don't need to be flipped; } return(extr); } )); //NurbsSurfaces AddConverter(new PipeConverter <rh.NurbsSurface, pps.NurbsSurface>( (rns) => { pps.NurbsSurface nurbs = new pps.NurbsSurface(rns.Points.CountU, rns.Points.CountV, rns.Degree(0), rns.Degree(1)); for (int u = 0; u < rns.Points.CountU; u++) { for (int v = 0; v < rns.Points.CountV; v++) { nurbs.SetControlPoint(ptConv.ToPipe <rh.Point3d, pp.Vec>(rns.Points.GetControlPoint(u, v).Location), u, v); nurbs.SetWeight(rns.Points.GetControlPoint(u, v).Weight, u, v); } } rh.Interval uDomain = rns.Domain(0); rh.Interval vDomain = rns.Domain(1); Func <double, rh.Interval, double> scaleKnot = (k, domain) => (k - domain.Min) / (domain.Length); nurbs.UKnots = rns.KnotsU.Select((k) => scaleKnot.Invoke(k, uDomain)).ToList(); nurbs.VKnots = rns.KnotsV.Select((k) => scaleKnot.Invoke(k, vDomain)).ToList(); nurbs.IsClosedInU = rns.IsClosed(0); nurbs.IsClosedInV = rns.IsClosed(1); nurbs.SurfaceNormal = vecConv.ToPipe <rh.Vector3d, pp.Vec>(rns.NormalAt(rns.Domain(0).Mid, rns.Domain(1).Mid)); return(nurbs); }, (pns) => { if (pns.IsClosedInU) { pns.WrapPointsToCloseSurface(0); } if (pns.IsClosedInV) { pns.WrapPointsToCloseSurface(1); } var nurbs = rh.NurbsSurface.Create(3, true, pns.UDegree + 1, pns.VDegree + 1, pns.UCount, pns.VCount); for (int u = 0; u < pns.UCount; u++) { for (int v = 0; v < pns.VCount; v++) { var cp = new rh.ControlPoint(ptConv.FromPipe <rh.Point3d, pp.Vec>(pns.GetControlPointAt(u, v)), pns.GetWeightAt(u, v)); nurbs.Points.SetControlPoint(u, v, cp); } } rh.Interval uDomain = nurbs.Domain(0); rh.Interval vDomain = nurbs.Domain(1); Func <double, rh.Interval, double> scaleKnot = (k, domain) => k * (domain.Length) + domain.Min; if (nurbs.KnotsU.Count == pns.UKnots.Count) { for (int i = 0; i < nurbs.KnotsU.Count; i++) { nurbs.KnotsU[i] = scaleKnot.Invoke(pns.UKnots[i], uDomain); } } if (nurbs.KnotsV.Count == pns.VKnots.Count) { for (int i = 0; i < nurbs.KnotsV.Count; i++) { nurbs.KnotsV[i] = scaleKnot.Invoke(pns.VKnots[i], vDomain); } } string msg; if (!nurbs.IsValidWithLog(out msg)) { System.Diagnostics.Debug.WriteLine(msg); if (!nurbs.IsPeriodic(0)) { nurbs.KnotsU.CreateUniformKnots(1.0 / (nurbs.Points.CountU)); } else { nurbs.KnotsU.CreatePeriodicKnots(1.0 / (nurbs.Points.CountU)); } if (!nurbs.IsPeriodic(1)) { nurbs.KnotsV.CreateUniformKnots(1.0 / (nurbs.Points.CountV)); } else { nurbs.KnotsV.CreatePeriodicKnots(1.0 / (nurbs.Points.CountV)); } if (!nurbs.IsValid) { throw new InvalidOperationException("Cannot create a valid NURBS surface: \n" + msg); } } var rhNorm = nurbs.NormalAt(nurbs.Domain(0).Mid, nurbs.Domain(1).Mid); if (rh.Vector3d.Multiply(rhNorm, vecConv.FromPipe <rh.Vector3d, pp.Vec>(pns.SurfaceNormal)) < 0) { //need not flip rhino surfaces } return(nurbs); } )); }
public BrepConverter(SurfaceConverter surfConv, CurveConverter curveConv, Point3dConverter ptConv) : base( (rb) => { List <pps.Surface> faces = new List <pps.Surface>(); List <List <int> > adjacency = new List <List <int> >(); for (int i = 0; i < rb.Faces.Count; i++) { var surf = (pps.NurbsSurface)surfConv.ToPipe <rh.Surface, pps.Surface>(rb.Faces[i].ToNurbsSurface()); surf.OuterTrims.Clear(); surf.OuterTrims.AddRange(rb.Faces[i].Loops.Where((l) => l.LoopType == rh.BrepLoopType.Outer).Select((l) => curveConv.ToPipe <rh.Curve, ppc.Curve>(l.To3dCurve()))); surf.InnerTrims.Clear(); surf.InnerTrims.AddRange(rb.Faces[i].Loops.Where((l) => l.LoopType == rh.BrepLoopType.Inner).Select((l) => curveConv.ToPipe <rh.Curve, ppc.Curve>(l.To3dCurve()))); faces.Add(surf); adjacency.Add(rb.Faces[i].AdjacentFaces().ToList()); } var polySurf = new pps.PolySurface(faces, adjacency); polySurf.IsSolid = rb.IsSolid; return(polySurf); }, (pb) => { if (pb.Surfaces.Count <= 0) { return(null); } rh.Brep brep = null; //trying to create a trimmed brep with built in methods if (Util.TryCreateBrepWithBuiltInMethods(pb, out brep, surfConv, curveConv)) { return(brep); } //attemping to build it from scratch - 15 attempts int attempts = 0; while (attempts < 15) { brep = new rh.Brep(); var ptCloud = new rh.PointCloud(pb.Vertices().Select((p) => ptConv.FromPipe <rh.Point3d, pp.Vec>(p))); var ptList = ptCloud.GetPoints().ToList(); ptList.ForEach((p) => brep.Vertices.Add(p, Rhino.RhinoMath.ZeroTolerance)); var ppEdges = pb.Edges(); foreach (var ppCur in ppEdges) { var rhCurve = curveConv.FromPipe <rh.Curve, ppc.Curve>(ppCur); int curveIndex = brep.Curves3D.Add(rhCurve); int startIndex = ptCloud.ClosestPoint(rhCurve.PointAtStart); int endIndex = ptCloud.ClosestPoint(rhCurve.PointAtEnd); var edge = brep.Edges.Add(startIndex, endIndex, curveIndex, Rhino.RhinoMath.ZeroTolerance); } foreach (var ppSurf in pb.Surfaces) { var rhSurf = surfConv.FromPipe <rh.Surface, pps.Surface>(ppSurf); var surfIndex = brep.AddSurface(rhSurf); var face = brep.Faces.Add(surfIndex); var loop = brep.Loops.Add(rh.BrepLoopType.Outer, face); var surfEdges = ppSurf.Edges(); int loopCount = 0; foreach (var ppLoop in surfEdges) { var rhCurve = curveConv.FromPipe <rh.Curve, ppc.Curve>(ppLoop); var curve2d = rhSurf.Pullback(rhCurve, Rhino.RhinoMath.ZeroTolerance); if (curve2d == null) { continue; } loopCount += 1; int c2i = brep.Curves2D.Add(curve2d); int c3i = ppEdges.IndexOf(ppLoop); if (c3i == -1) { c3i = brep.Curves3D.Add(rhCurve); } int startIndex = ptCloud.ClosestPoint(rhCurve.PointAtStart); int endIndex = ptCloud.ClosestPoint(rhCurve.PointAtEnd); var trim = brep.Trims.Add(brep.Edges[c3i], false, loop, c2i); trim.IsoStatus = rh.IsoStatus.None; trim.TrimType = rh.BrepTrimType.Boundary; trim.SetTolerances(0.0, 0.0); } if (loopCount == 0) { var curve2d = Util.Get2dEdgeLoop(rhSurf); int c2i = brep.Curves2D.Add(curve2d); var curve3d = rhSurf.Pushup(curve2d, Rhino.RhinoMath.ZeroTolerance); int c3i = brep.Curves3D.Add(curve3d); int startIndex = ptCloud.ClosestPoint(curve3d.PointAtStart); int endIndex = ptCloud.ClosestPoint(curve3d.PointAtEnd); var edge = brep.Edges.Add(startIndex, endIndex, c3i, Rhino.RhinoMath.ZeroTolerance); var trim = brep.Trims.Add(brep.Edges[c3i], false, loop, c2i); trim.IsoStatus = rh.IsoStatus.None; trim.TrimType = rh.BrepTrimType.Boundary; trim.SetTolerances(0.0, 0.0); } //var uSurfDom = rhSurf.Domain(0); //var vSurfDom = rhSurf.Domain(1); //var ufaceDom = face.Domain(0); //var vfaceDom = face.Domain(1); //var surfNorm = rhSurf.NormalAt(uSurfDom.Mid, vSurfDom.Mid); //var faceNorm = face.NormalAt(ufaceDom.Mid, vfaceDom.Mid); //face.OrientationIsReversed = rh.Vector3d.Multiply(surfNorm, faceNorm) < 0; face.OrientationIsReversed = false; } //updating attempts and breaking if succeeded attempts += 1; if (brep.IsValid) { break; } } string msg; if (!brep.IsValidWithLog(out msg)) { System.Diagnostics.Debug.WriteLine(msg); brep.Repair(Rhino.RhinoMath.ZeroTolerance); if (brep.IsValid) { return(brep); } //finally attemping to create an untrimmed brep int attempt = 0; while (!brep.IsValid && attempt < 15) { brep = rh.Brep.MergeBreps(pb.Surfaces.Select((s) => rh.Brep.CreateFromSurface(surfConv.FromPipe <rh.Surface, pps.Surface>(s))), Rhino.RhinoMath.ZeroTolerance); attempt += 1; } if (!brep.IsValid) { throw new InvalidOperationException("Failed to create a valid brep from " + "received data because: \n" + msg); } } return(brep); } ) { }