/// <summary> /// Solves the instance. /// </summary> /// <param name="DA">Da.</param> protected override void SolveInstance(IGH_DataAccess DA) { // Properties Mesh mesh = null; Curve initialCurve = null; double specifiedDistance = 0.0; int maxCount = 0; double threshold = 0.0; double perpStepSize = 0.0; bool bothDir = false; double minThreshold = 0.0; // Set the input data if (!DA.GetData(0, ref mesh)) { return; } if (!DA.GetData(1, ref initialCurve)) { return; } if (!DA.GetData(2, ref bothDir)) { return; } if (!DA.GetData(3, ref maxCount)) { return; } if (!DA.GetData(4, ref threshold)) { return; } if (!DA.GetData(5, ref specifiedDistance)) { return; } if (!DA.GetData(6, ref perpStepSize)) { return; } if (!DA.GetData(7, ref minThreshold)) { return; } // Data validation if (maxCount == 0) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Count cannot be 0"); } if (!mesh.IsValid) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Mesh is invalid"); } // Placeholder properties DataTree <Curve> pattern = new DataTree <Curve>(); Curve previousCurve = initialCurve; List <Curve> perpGeods = new List <Curve>(); List <double> perpParams = new List <double>(); // Start piecewise evolution process for (int i = 0; i < maxCount; i++) { Debug.WriteLine("Iter " + i); // Create placeholder lists perpGeods = new List <Curve>(); perpParams = new List <double>(); // Divide curve double[] geodParams = previousCurve.DivideByLength(perpStepSize, true); if (geodParams == null) { AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "No points found on iter" + i); break; } if (geodParams.Length <= 2) { AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Not enough points found on iter" + i); break; } // Generate perp geodesics for measurement foreach (double t in geodParams) { // Get curve tangent vector and mesh normal Point3d point = previousCurve.PointAt(t); Vector3d tangent = previousCurve.TangentAt(t); Vector3d normal = mesh.NormalAt(mesh.ClosestMeshPoint(point, 0.0)); // Rotate vector against normals 90 degrees tangent.Rotate(0.5 * Math.PI, normal); // Generate perp geodesic Curve perpGeodesic = MeshGeodesicMethods.getGeodesicCurveOnMesh(mesh, point, tangent, 100).ToNurbsCurve(); // Check for success if (perpGeodesic != null && perpGeodesic.GetLength() > specifiedDistance) { // Divide by specified length double perpT = 0.0; perpGeodesic.LengthParameter(specifiedDistance, out perpT); // Add data to lists perpGeods.Add(perpGeodesic); perpParams.Add(perpT); } } // Clean perp geods of intersections ocurring BEFORE the specified distance var result = CleanPerpGeodesics(perpGeods, perpParams, specifiedDistance); // Assign clean lists perpGeods = result.perpGeodesics; perpParams = result.perpParams; // Break if not enough perpGeods remain if (perpGeods.Count < 6) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Not enough perp geodesics where found for iter " + i); break; } //Generate the next piecewise geodesic List <Curve> iterCurves = GeneratePiecewiseGeodesicCurve(mesh, perpParams, perpGeods, 1000, bothDir, 0, threshold, Vector3d.Unset); // Add it to the pattern pattern.AddRange(iterCurves, new GH_Path(i)); // Assign as previous for the next round Curve[] joinedResult = Curve.JoinCurves(iterCurves); // Error check if (joinedResult.Length > 1) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "More than 1 curve after Join in iter " + i); break; } //Create points and bisectrix vectors for next round of perp geodesics Point3dList ptList = new Point3dList(); foreach (Curve c in iterCurves) { if (!ptList.Contains(c.PointAtStart)) { ptList.Add(c.PointAtStart); } if (!ptList.Contains(c.PointAtEnd)) { ptList.Add(c.PointAtEnd); } } Debug.WriteLine("ptList Count: " + ptList.Count); // Assign new curve to previous curve Curve joinedCurve = joinedResult[0]; previousCurve = joinedCurve; } // Assign data to output DA.SetDataTree(0, pattern); DA.SetDataList(2, perpGeods); }