public static GameObject TileShow(List <Rhino.Geometry.Point3d> grid, int gridSize, Color color, bool convertM = true, string name = "TileGrid") { var gridObj = new GameObject(name); Brep[] breps = new Brep[grid.Count]; // List<Brep> breps = new List<Brep>(); for (int i = 0; i < grid.Count; i++) { var pt = grid[i]; if (convertM) { var mPt = pt * (0.001); var plane = new Rhino.Geometry.Plane(mPt, Vector3d.ZAxis); var interval = new Interval((-gridSize / 2) * (0.001), (gridSize / 2) * (0.001)); var srf = new Rhino.Geometry.PlaneSurface(plane, interval, interval); var brep = srf.ToBrep(); // breps.Add(brep); breps[i] = brep; } else { var plane = new Rhino.Geometry.Plane(pt, Vector3d.ZAxis); var interval = new Interval(-gridSize / 2, gridSize / 2); var srf = new Rhino.Geometry.PlaneSurface(plane, interval, interval); var brep = srf.ToBrep(); //breps.Add(brep); breps[i] = brep; } } var joinedBrep = Rhino.Geometry.Brep.CreateBooleanUnion(breps, 0.1); var meshParam = MeshingParameters.FastRenderMesh; var meshs = Rhino.Geometry.Mesh.CreateFromBrep(joinedBrep[0], meshParam); var joinedMesh = new Rhino.Geometry.Mesh(); foreach (var m in meshs) { joinedMesh.Append(m); } joinedMesh.Weld(180); //attatch Mesh var UnityMesh = joinedMesh.ToHost(); var meshRender = gridObj.AddComponent <MeshRenderer>(); meshRender.material.color = color; meshRender.material.shader = Shader.Find("UI/Default"); var meshFilter = gridObj.AddComponent <MeshFilter>(); meshFilter.mesh = UnityMesh; return(gridObj); }
/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param> protected override void SolveInstance(IGH_DataAccess DA) { Surface S = null; if (!DA.GetData(0, ref S)) { return; } Point3d P = Point3d.Unset; if (!DA.GetData(1, ref P)) { P = S.PointAt(S.Domain(0).Mid, S.Domain(1).Mid); } double R = Rhino.RhinoMath.UnsetValue; if (!DA.GetData(2, ref R)) { return; } double A = Rhino.RhinoMath.UnsetValue; if (!DA.GetData(3, ref A)) { return; } int max = 0; if (!DA.GetData(4, ref max)) { return; } Boolean extend = false; if (!DA.GetData(5, ref extend)) { return; } if (R <= 0) { this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Mesh edge length must be a positive, non-zero number."); return; } // Extend surface beyond boundaries to get a better coverage from the net if (extend) { S = S.Extend(IsoStatus.North, R, true); S = S.Extend(IsoStatus.East, R, true); S = S.Extend(IsoStatus.South, R, true); S = S.Extend(IsoStatus.West, R, true); } // starting point double u0, v0; S.ClosestPoint(P, out u0, out v0); // get two (four) orthogonal directions (in plane of surface at starting point) Plane plane = new Plane(S.PointAt(u0, v0), S.NormalAt(u0, v0)); plane.Rotate(Rhino.RhinoMath.ToRadians(A), S.NormalAt(u0, v0)); Vector3d[] dir = new Vector3d[] { plane.XAxis * R, plane.YAxis * R, plane.XAxis * -R, plane.YAxis * -R }; // for each direction, walk out (and store list of points) double u, v; List <Point3d>[] axis = new List <Point3d> [4]; for (int i = 0; i < 4; i++) { // set u and v to starting point u = u0; v = v0; List <Point3d> pts = new List <Point3d>(); for (int j = 0; j < max + 1; j++) { // get point and normal for uv Point3d pt = S.PointAt(u, v); Vector3d n = S.NormalAt(u, v); n *= R; // add point to list pts.Add(pt); // create forward facing arc and find intersection point with surface (as uv) Arc arc = new Arc(pt + n, pt + dir[i], pt - n); CurveIntersections isct = Intersection.CurveSurface(arc.ToNurbsCurve(), S, 0.01, 0.01); if (isct.Count > 0) { isct[0].SurfacePointParameter(out u, out v); } else { break; } // adjust direction vector (new position - old position) dir[i] = S.PointAt(u, v) - pt; } axis[i] = pts; } // now that we have the axes, start to build up the mesh quads in between GH_PreviewUtil preview = new GH_PreviewUtil(GetValue("Animate", false)); Rhino.Geometry.Mesh mesh = new Rhino.Geometry.Mesh(); // target mesh for (int k = 0; k < 4; k++) { int k0 = (k + 1) % 4; int padding = 10; Rhino.Geometry.Mesh qmesh = new Rhino.Geometry.Mesh(); // local mesh for quadrant Point3d[,] quad = new Point3d[axis[k].Count + padding, axis[k0].Count + padding]; // 2d array of points int[,] qindex = new int[axis[k].Count + padding, axis[k0].Count + padding]; // 2d array of points' indices in local mesh int count = 0; for (int i = 0; i < axis[k0].Count; i++) { // add axis vertex to mesh and store point and index in corresponding 2d arrays quad[0, i] = axis[k0][i]; qmesh.Vertices.Add(axis[k0][i]); qindex[0, i] = count++; } for (int i = 1; i < quad.GetLength(0); i++) { if (i < axis[k].Count) { // add axis vertex quad[i, 0] = axis[k][i]; qmesh.Vertices.Add(axis[k][i]); qindex[i, 0] = count++; } // for each column attempt to locate a new vertex in the grid for (int j = 1; j < quad.GetLength(1); j++) { // if quad[i - 1, j] doesn't exist, try to add it and continue (or else break the current row) if (quad[i - 1, j] == new Point3d()) { if (j < 2) { break; } CurveIntersections isct = this.ArcIntersect(S, quad[i - 1, j - 1], quad[i - 1, j - 2], R); if (isct.Count > 0) { quad[i - 1, j] = isct[0].PointB; qmesh.Vertices.Add(quad[i - 1, j]); qindex[i - 1, j] = count++; } else { break; } } // if quad[i, j - 1] doesn't exist, try to create quad[i, j] by projection and skip mesh face creation if (quad[i, j - 1] == new Point3d()) { if (i < 2) { break; } CurveIntersections isct = this.ArcIntersect(S, quad[i - 1, j], quad[i - 2, j], R); if (isct.Count > 0) { quad[i, j] = isct[0].PointB; qmesh.Vertices.Add(quad[i, j]); qindex[i, j] = count++; continue; } } // construct a sphere at each neighbouring vertex ([i,j-1] and [i-1,j]) and intersect Sphere sph1 = new Sphere(quad[i, j - 1], R); Sphere sph2 = new Sphere(quad[i - 1, j], R); Circle cir; if (Intersection.SphereSphere(sph1, sph2, out cir) == SphereSphereIntersection.Circle) { // intersect circle with surface CurveIntersections cin = Intersection.CurveSurface(NurbsCurve.CreateFromCircle(cir), S, 0.01, 0.01); // attempt to find the new vertex (i.e not [i-1,j-1]) foreach (IntersectionEvent ie in cin) { if ((ie.PointA - quad[i - 1, j - 1]).Length > 0.2 * R) // compare with a tolerance, rather than exact comparison { quad[i, j] = ie.PointA; qmesh.Vertices.Add(quad[i, j]); qindex[i, j] = count++; // create quad-face qmesh.Faces.AddFace(qindex[i, j], qindex[i - 1, j], qindex[i - 1, j - 1], qindex[i, j - 1]); break; } } if (preview.Enabled) { preview.Clear(); preview.AddMesh(mesh); preview.AddMesh(qmesh); preview.Redraw(); } } } } // add local mesh to target mesh.Append(qmesh); } // weld mesh to remove duplicate vertices along axes mesh.Weld(Math.PI); mesh.Compact(); mesh.Normals.ComputeNormals(); DA.SetData(0, mesh); preview.Clear(); }