コード例 #1
0
ファイル: SurfaceConverter.cs プロジェクト: yasenRK/ThePipe
        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);
            }
                             ));
        }
コード例 #2
0
ファイル: SurfaceConverter.cs プロジェクト: yasenRK/ThePipe
        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;
                })));
            }
                             ));
        }