Ejemplo n.º 1
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            System.Reflection.Assembly         assembly = System.Reflection.Assembly.GetExecutingAssembly();
            System.Diagnostics.FileVersionInfo fvi      = System.Diagnostics.FileVersionInfo.GetVersionInfo(assembly.Location);
            string version = fvi.FileVersion;

            Rhino.RhinoApp.WriteLine("Minimal surface component, version " + version);
            Rhino.RhinoApp.WriteLine("GPLv3 licensed, source: https://github.com/Mathias-Fuchs/MinimalSurface");
            Rhino.RhinoApp.WriteLine("Copyright Mathias Fuchs 2020 - 2021, https://mathiasfuchs.com");


            // the input curve
            Curve  tc       = null;
            Curve  tc2      = null;
            int    vertical = 0;
            int    around   = 0;
            int    degree   = 0;
            double angle    = 0;
            bool   flip     = false;

            DA.GetData(0, ref tc);
            DA.GetData(1, ref tc2);
            DA.GetData(2, ref vertical);
            DA.GetData(3, ref around);
            DA.GetData(4, ref degree);
            DA.GetData(5, ref angle);
            DA.GetData(6, ref flip);

            if (tc == null || !tc.IsValid || !tc.IsClosed)
            {
                this.AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "First input curve is either unvalid or not closed!"); return;
            }
            if (tc2 == null || !tc2.IsValid || !tc2.IsClosed)
            {
                this.AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Second input curve is either unvalid or not closed!"); return;
            }

            Curve _targetCurve  = tc;
            Curve _targetCurve2 = tc2;

            // number of control points, tells about the complexity of the curve
            int nrCont = _targetCurve.ToNurbsCurve().Points.Count;
            int crDeg  = _targetCurve.Degree;

            int idealDegree = nrCont * crDeg;
            int _degree     = Math.Min(Math.Max(10, idealDegree), 50);

            //  number of boundary subdivisions
            int _n      = 23 * _degree;
            int nrCont2 = _targetCurve2.ToNurbsCurve().Points.Count;
            int crDeg2  = _targetCurve2.Degree;

            int idealDegree2 = nrCont2 * crDeg2;
            int _degree2     = Math.Min(Math.Max(10, idealDegree2), 50);
            int _n2          = 23 * _degree2;

            int deg;

            if (degree == 0)
            {
                deg = Math.Max(_degree, _degree2);
            }
            else
            {
                deg = degree;
            }

            double[] t             = _targetCurve.DivideByCount(_n, true);
            var      _targetPoints = Enumerable.Range(0, _n).Select(i => _targetCurve.PointAt(flip ? 1 - t[i] : t[i])).ToList();

            double[] t2             = _targetCurve2.DivideByCount(_n2, true);
            var      _targetPoints2 = Enumerable.Range(0, _n2).Select(i => _targetCurve2.PointAt(t2[(i + (int)((double)_n2 * (angle / 2 * Math.PI))) % _n2])).ToList();

            double R1 = 0.5;
            double R2 = 1.5;

            // now, do the actual work and compute the three complex polynomials
            // ok, let's get the coefficients
            List <double> xs1 = _targetPoints.Select(o => o.X).ToList();  // 1 ms
            List <double> xs2 = _targetPoints2.Select(o => o.X).ToList(); // 1 ms
                                                                          //        LaplaceData kx = new LaplaceData(xs1, deg); <-- if it's just one curve
            AnnularLaplaceData akx = new AnnularLaplaceData(xs1, R1, xs2, R2, deg);

            List <double> ys1 = _targetPoints.Select(o => o.Y).ToList();  // 1 ms
            List <double> ys2 = _targetPoints2.Select(o => o.Y).ToList(); // 1 ms
                                                                          //       LaplaceData ky = new LaplaceData(ys1, deg);
            AnnularLaplaceData aky = new AnnularLaplaceData(ys1, R1, ys2, R2, deg);

            List <double> zs1 = _targetPoints.Select(o => o.Z).ToList();  // 1 ms
            List <double> zs2 = _targetPoints2.Select(o => o.Z).ToList(); // 1 ms
                                                                          //       LaplaceData kkz = new LaplaceData(zs1, deg);
            AnnularLaplaceData akkz = new AnnularLaplaceData(zs1, R1, zs2, R2, deg);

            var MM = UncappedCylinder(around, vertical);


            var mvl = MM.Vertices.Select(pp =>
            {
                var x = pp.X;
                var y = pp.Y;
                var z = pp.Z;
                var f = (R1 + z * (R2 - R1)) / Math.Sqrt(x * x + y * y);
                var p = new Point2d(f * x, f * y);
                return(new Point3d(akx.eval(p), aky.eval(p), akkz.eval(p)));
            });

            var MMM = new Mesh();

            MMM.Vertices.Capacity = MM.Vertices.Count;

            // bottleneck ... so here, parallelization would be nice but the .AddVertices method can not deal with a parallel queryable, so it is not clear how to parallelize this.
            MMM.Vertices.AddVertices(mvl);

            // also bottleneck
            MMM.Faces.Capacity = MM.Faces.Count;
            MMM.Faces.AddFaces(MM.Faces);

            if (MMM.Faces.GetClashingFacePairs(1).Any())
            {
                this.AddRuntimeMessage(
                    GH_RuntimeMessageLevel.Warning,
                    "The resulting mesh has self-intersections. Modifying the rotation angle and flip switch input parameters can solve this.");
            }

            DA.SetData(0, MMM);
        }
Ejemplo n.º 2
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {// the input curve
            Curve  tc       = null;
            Curve  tc2      = null;
            int    vertical = 0;
            int    around   = 0;
            int    degree   = 0;
            double angle    = 0;
            bool   flip     = false;

            DA.GetData(0, ref tc);
            DA.GetData(1, ref tc2);
            DA.GetData(2, ref vertical);
            DA.GetData(3, ref around);
            DA.GetData(4, ref degree);
            DA.GetData(5, ref angle);
            DA.GetData(6, ref flip);

            if (tc == null || !tc.IsValid || !tc.IsClosed)
            {
                this.AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "First input curve is either unvalid or not closed!"); return;
            }
            if (tc2 == null || !tc2.IsValid || !tc2.IsClosed)
            {
                this.AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Second input curve is either unvalid or not closed!"); return;
            }

            Curve _targetCurve  = tc;
            Curve _targetCurve2 = tc2;

            // number of control points, tells about the complexity of the curve
            int nrCont = _targetCurve.ToNurbsCurve().Points.Count;
            int crDeg  = _targetCurve.Degree;

            int idealDegree = nrCont * crDeg;
            int _degree     = Math.Min(Math.Max(10, idealDegree), 50);

            //  number of boundary subdivisions
            int _n      = 23 * _degree;
            int nrCont2 = _targetCurve2.ToNurbsCurve().Points.Count;
            int crDeg2  = _targetCurve2.Degree;

            int idealDegree2 = nrCont2 * crDeg2;
            int _degree2     = Math.Min(Math.Max(10, idealDegree2), 50);
            int _n2          = 23 * _degree2;

            int deg;

            if (degree == 0)
            {
                deg = Math.Max(_degree, _degree2);
            }
            else
            {
                deg = degree;
            }

            double[] t             = _targetCurve.DivideByCount(_n, true);
            var      _targetPoints = Enumerable.Range(0, _n).Select(i => _targetCurve.PointAt(flip ? 1 - t[i] : t[i])).ToList();

            double[] t2             = _targetCurve2.DivideByCount(_n2, true);
            var      _targetPoints2 = Enumerable.Range(0, _n2).Select(i => _targetCurve2.PointAt(t2[(i + (int)((double)_n2 * (angle / 2 * Math.PI))) % _n2])).ToList();

            double R1 = 0.5;
            double R2 = 1.5;

            // now, do the actual work and compute the three complex polynomials
            // ok, let's get the coefficients
            List <double> xs1 = _targetPoints.Select(o => o.X).ToList();  // 1 ms
            List <double> xs2 = _targetPoints2.Select(o => o.X).ToList(); // 1 ms
                                                                          //        LaplaceData kx = new LaplaceData(xs1, deg); <-- if it's just one curve
            AnnularLaplaceData akx = new AnnularLaplaceData(xs1, R1, xs2, R2, deg);

            List <double> ys1 = _targetPoints.Select(o => o.Y).ToList();  // 1 ms
            List <double> ys2 = _targetPoints2.Select(o => o.Y).ToList(); // 1 ms
                                                                          //       LaplaceData ky = new LaplaceData(ys1, deg);
            AnnularLaplaceData aky = new AnnularLaplaceData(ys1, R1, ys2, R2, deg);

            List <double> zs1 = _targetPoints.Select(o => o.Z).ToList();  // 1 ms
            List <double> zs2 = _targetPoints2.Select(o => o.Z).ToList(); // 1 ms
                                                                          //       LaplaceData kkz = new LaplaceData(zs1, deg);
            AnnularLaplaceData akkz = new AnnularLaplaceData(zs1, R1, zs2, R2, deg);

            var MM = UncappedCylinder(around, vertical);

            var Cyl = MM.DuplicateMesh();



            // bottleneck
            // can't be done with MM.Vertices.GetEnumerator() I guess

            for (int ii = 0; ii < MM.Vertices.Count; ii++)
            {
                var x = MM.Vertices[ii].X;
                var y = MM.Vertices[ii].Y;
                var z = MM.Vertices[ii].Z;
                var f = (R1 + z * (R2 - R1)) / Math.Sqrt(x * x + y * y);
                var p = new Point2d(f * x, f * y);
                MM.Vertices.SetVertex(ii, akx.eval(p), aky.eval(p), akkz.eval(p));
            }

            DA.SetData(0, MM);

            DA.SetData(1, Enumerable.Range(0, Cyl.Vertices.Count).Average(
                           ii =>
            {
                var x = Cyl.Vertices[ii].X;
                var y = Cyl.Vertices[ii].Y;
                var z = Cyl.Vertices[ii].Z;
                var f = (R1 + z * (R2 - R1)) / Math.Sqrt(x * x + y * y);
                var p = new Point2d(f * x, f * y);

                var gg = Math.Pow(
                    akx.drtimesdtheta(p) + aky.drtimesdtheta(p) + akkz.drtimesdtheta(p), 2);
                return(gg);
            }
                           )
                       );
        }