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); }
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); }