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); } )); }
internal SurfaceConverter(VectorConverter vecConv, PointConverter ptConv, CurveConverter curveConv) { //NURBS surface /* * Nurbs Surfaces from the pipe cannot be converted to dynamo nurbs because they could have trims. * In Dynamo trimmed surfaces are instances of the Surface class. So it has to be another converter. * This converter has to be a one way mapping, hence one of the conversion delegates is null */ var nurbsConv = new PipeConverter <dg.NurbsSurface, pps.NurbsSurface>( (dns) => { var nurbs = new pps.NurbsSurface(dns.NumControlPointsU, dns.NumControlPointsV, dns.DegreeU, dns.DegreeV); dg.Point[][] pts = dns.ControlPoints(); double[][] weights = dns.Weights(); for (int u = 0; u < dns.NumControlPointsU; u++) { for (int v = 0; v < dns.NumControlPointsV; v++) { nurbs.SetControlPoint(ptConv.ToPipe <dg.Point, pp.Vec>(pts[u][v]), u, v); nurbs.SetWeight(weights[u][v], u, v); } } nurbs.UKnots = dns.UKnots().ToList(); nurbs.VKnots = dns.VKnots().ToList(); nurbs.SurfaceNormal = vecConv.ToPipe <dg.Vector, pp.Vec>(dns.NormalAtParameter(0.5, 0.5)); return(nurbs); }, null ); AddConverter(nurbsConv); /* * ThePipe Extrusions can be mapped to surfaces in dynamo but all surfaces should not be mapped to extrusions. * So this mapping has to be one way, hence the first conversion delegate is null. */ AddConverter(new PipeConverter <dg.Surface, pps.Extrusion>( null, //null because of one way mapping (pe) => { var extrVec = pp.Vec.Multiply(pe.Direction, pe.Height); var path = curveConv.FromPipe <dg.Curve, ppc.Curve>(new ppc.Line(pe.ProfileCurve.StartPoint, pp.Vec.Sum(pe.ProfileCurve.StartPoint, extrVec))); var profile = curveConv.FromPipe <dg.Curve, ppc.Curve>(pe.ProfileCurve); var extr = dg.Surface.BySweep(profile, path); if (!profile.IsClosed) { var cutPt = profile.PointAtSegmentLength(1e-4); profile = profile.TrimByParameter(0, profile.ParameterAtPoint(cutPt)); var profile2 = dg.PolyCurve.ByJoinedCurves(new List <dg.Curve>() { profile }).CloseWithLine(); if (!profile2.IsClosed) { return(extr); } profile = profile2; } try { var cap1 = dg.Surface.ByPatch(profile); var cap2 = dg.Surface.ByPatch((dg.Curve)profile.Translate(vecConv.FromPipe <dg.Vector, pp.Vec>(extrVec))); if (pe.CappedAtStart) { extr = dg.PolySurface.ByJoinedSurfaces(new List <dg.Surface>() { extr, cap1 }); } if (pe.CappedAtEnd) { extr = dg.PolySurface.ByJoinedSurfaces(new List <dg.Surface>() { extr, cap2 }); } } catch (Exception e) { //do nothing } if (extr.NormalAtParameter(0.5, 0.5).Dot(vecConv.FromPipe <dg.Vector, pp.Vec>(pe.SurfaceNormal)) < 0) { extr.FlipNormalDirection(); } return(extr); } )); /* * Surface is not an abstract class in dynamo, so there needs to be concrete conversion logic for them. * They are being mapped to Pipe's NurbsSurface class. */ AddConverter(new PipeConverter <dg.Surface, pps.NurbsSurface>( (ds) => { var nurbs = nurbsConv.ToPipe <dg.NurbsSurface, pps.NurbsSurface>(ds.ToNurbsSurface()); nurbs.OuterTrims.Clear(); try { var closedTrim = dg.PolyCurve.ByJoinedCurves(ds.Edges.Select((e) => e.CurveGeometry)); nurbs.OuterTrims.Add(curveConv.ToPipe <dg.Curve, ppc.Curve>(closedTrim)); } catch (Exception e) { //do nothing //nurbs.OuterTrims.AddRange(ds.Edges.Select((edge) => curveConv.ToPipe<dg.Curve, ppc.Curve>(edge.CurveGeometry))); } nurbs.SurfaceNormal = vecConv.ToPipe <dg.Vector, pp.Vec>(ds.NormalAtParameter(0.5, 0.5)); return(nurbs); }, (pns) => { if (pns.IsClosedInU || pns.IsClosedInV) { throw new PipeDataModel.Exceptions.PipeConversionException(pns.GetType(), typeof(dg.Surface), "Closed Nurbs surfaces are not " + "supported in dynamo, please try converting this geometry to split-open surfaces or meshes before sending it through the pipe."); } List <List <dg.Point> > pts = new List <List <dg.Point> >(); List <List <double> > weights = new List <List <double> >(); for (int u = 0; u < pns.UCount; u++) { List <dg.Point> ptRow = new List <dg.Point>(); List <double> wRow = new List <double>(); for (int v = 0; v < pns.VCount; v++) { ptRow.Add(ptConv.FromPipe <dg.Point, pp.Vec>(pns.GetControlPointAt(u, v))); wRow.Add(pns.GetWeightAt(u, v)); } pts.Add(ptRow); weights.Add(wRow); } dg.Surface nurbs; try { nurbs = dg.NurbsSurface.ByControlPointsWeightsKnots(pts.Select((r) => r.ToArray()).ToArray(), weights.Select((r) => r.ToArray()).ToArray(), pns.UKnots.ToArray(), pns.VKnots.ToArray(), pns.UDegree, pns.VDegree); } catch (Exception e) { nurbs = dg.NurbsSurface.ByControlPoints(pts.Select((r) => r.ToArray()).ToArray(), pns.UDegree, pns.VDegree); } if (pns.OuterTrims.Count > 0) { var trims = pns.OuterTrims.Select((t) => ((dg.PolyCurve)curveConv.FromPipe <dg.Curve, ppc.Curve>(t.AsPolyCurve()))?.CloseWithLine()).ToList(); try { nurbs = nurbs.TrimWithEdgeLoops(trims); } catch (Exception e) { //do nothing } } if (nurbs.NormalAtParameter(0.5, 0.5).Dot(vecConv.FromPipe <dg.Vector, pp.Vec>(pns.SurfaceNormal)) < 0) { nurbs.FlipNormalDirection(); } return(nurbs); } )); //Polysurfaces AddConverter(new PipeConverter <dg.PolySurface, pps.PolySurface>( (dps) => { List <List <int> > adjacency = new List <List <int> >(); var faces = dps.Faces.Select((f) => { var dgSurf = f.SurfaceGeometry().ToNurbsSurface(); var surf = nurbsConv.ToPipe <dg.NurbsSurface, pps.NurbsSurface>(dgSurf); // add edges as trim curves surf.OuterTrims.Clear(); try { var closedTrim = dg.PolyCurve.ByJoinedCurves(f.Edges.Select((e) => e.CurveGeometry)); surf.OuterTrims.Add(curveConv.ToPipe <dg.Curve, ppc.Curve>(closedTrim)); } catch (Exception e) { //do nothing //surf.OuterTrims.AddRange(f.Edges.Select((edge) => curveConv.ToPipe<dg.Curve, ppc.Curve>(edge.CurveGeometry))); } adjacency.Add(f.Edges.SelectMany((e) => e.AdjacentFaces.ToList()).Distinct().Select((af) => dps.Faces.ToList().IndexOf(af)).ToList()); return((pps.Surface)surf); }).ToList(); var polySurf = new pps.PolySurface(faces, adjacency); return(polySurf); }, (ps) => { return(dg.PolySurface.ByJoinedSurfaces(ps.Surfaces.Select((s) => { var surf = FromPipe <dg.Surface, pps.Surface>(s); //if (typeof(pps.NurbsSurface).IsAssignableFrom(s.GetType()) // && ((pps.NurbsSurface)s).OuterTrims.Count > 0) //{ // surf = surf.TrimWithEdgeLoops(((pps.NurbsSurface)s).OuterTrims.Select((c) => // (dg.PolyCurve)curveConv.FromPipe<dg.Curve, ppc.Curve>(c.AsPolyCurve()))); //} return surf; }))); } )); }