Example #1
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            Curve  tc = null;
            int    nrBoundaryVertices = 0;
            int    degree             = 0;
            double angle = 0;

            DA.GetData(0, ref tc);
            DA.GetData(1, ref nrBoundaryVertices);
            DA.GetData(2, ref degree);
            DA.GetData(3, ref angle);

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

            Curve _targetCurve = tc;

            // 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 deg         = Math.Min(Math.Max(25, idealDegree), 50);

            //  number of boundary subdivisions
            int _n = 23 * deg;

            double[] t             = _targetCurve.DivideByCount(_n, true);
            var      _targetPoints = Enumerable.Range(0, _n).Select(i => _targetCurve.PointAt(t[(i + (int)(angle / Math.PI / 2.0 * _n)) % _n])).ToList();

            // 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
            LaplaceData   kx  = new LaplaceData(xs1, deg);

            List <double> ys1 = _targetPoints.Select(o => o.Y).ToList(); // 1 ms
            LaplaceData   ky  = new LaplaceData(ys1, deg);

            List <double> zs1 = _targetPoints.Select(o => o.Z).ToList(); // 1 ms
            LaplaceData   kkz = new LaplaceData(zs1, deg);

            var c  = new Circle(1.0);
            var kk = MeshingParameters.Default;

            kk.GridAmplification = (double)nrBoundaryVertices / 10.0;
            var MM = Mesh.CreateFromPlanarBoundary(c.ToNurbsCurve(), kk, DocumentTolerance());

            // bottleneck
            for (int ii = 0; ii < MM.Vertices.Count; ii++)
            {
                var x = MM.Vertices[ii].X;
                var y = MM.Vertices[ii].Y;

                var p = new Point2d(x, y);
                MM.Vertices.SetVertex(ii, kx.eval(p), ky.eval(p), kkz.eval(p));
            }

            DA.SetData(0, MM);
        }
Example #2
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");

            Curve  tc = null;
            int    nrBoundaryVertices = 0;
            int    degree             = 0;
            double angle = 0;

            DA.GetData(0, ref tc);
            DA.GetData(1, ref nrBoundaryVertices);
            DA.GetData(2, ref degree);
            DA.GetData(3, ref angle);

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

            Curve _targetCurve = tc;

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

            // if degree isn't specified, use this heuristic
            // computationally, 25 is always doable, and more than 300 doesn't usually make sense
            if (degree == 0)
            {
                degree = Math.Min(Math.Max(25, nrCont * crDeg), 300);
            }

            //  number of boundary subdivisions for computation of the polynomials
            int _n = 23 * degree;

            double[] t             = _targetCurve.DivideByCount(_n, true);
            var      _targetPoints = Enumerable.Range(0, _n).Select(i => _targetCurve.PointAt(t[(i + (int)(angle / Math.PI / 2.0 * _n)) % _n])).ToList();

            // 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
            LaplaceData   kx  = new LaplaceData(xs1, degree);

            List <double> ys1 = _targetPoints.Select(o => o.Y).ToList(); // 1 ms
            LaplaceData   ky  = new LaplaceData(ys1, degree);

            List <double> zs1 = _targetPoints.Select(o => o.Z).ToList(); // 1 ms
            LaplaceData   kkz = new LaplaceData(zs1, degree);

            var c  = new Circle(1.0);
            var kk = MeshingParameters.Default;

            kk.MinimumEdgeLength = 2 * Math.PI / (double)nrBoundaryVertices;
            kk.MaximumEdgeLength = 2 * Math.PI / (double)nrBoundaryVertices * 2;
            var MM = Mesh.CreateFromPlanarBoundary(c.ToNurbsCurve(), kk, DocumentTolerance());

            var MMM = new Mesh();
            var mvl = MM.Vertices.Select(pp =>
            {
                var p = new Point2d(pp.X, pp.Y);
                return(new Point3d(kx.eval(p), ky.eval(p), kkz.eval(p)));
            }
                                         );

            // bottleneck
            MMM.Vertices.Capacity = MM.Vertices.Count;
            MMM.Vertices.AddVertices(mvl);
            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 input parameter can solve this.");
            }
            DA.SetData(0, MMM);
        }