public static GH_Mesh ProjectMeshToTopoFast(Mesh topoMesh, Mesh featureMesh) { GH_Mesh ghMesh = new GH_Mesh(); Mesh mesh = featureMesh.DuplicateMesh(); ///Move patch verts to topo for (int i = 0; i < mesh.Vertices.Count; i++) { Ray3d ray = new Ray3d((Point3d)mesh.Vertices[i], moveDir); double t = Rhino.Geometry.Intersect.Intersection.MeshRay(topoMesh, ray); if (t >= 0.0) { mesh.Vertices.SetVertex(i, (Point3f)ray.PointAt(t)); } else { Ray3d rayOpp = new Ray3d((Point3d)mesh.Vertices[i], -moveDir); double tOpp = Rhino.Geometry.Intersect.Intersection.MeshRay(topoMesh, rayOpp); if (tOpp >= 0.0) { mesh.Vertices.SetVertex(i, (Point3f)rayOpp.PointAt(tOpp)); } else { //mesh.Vertices.SetVertex(i, new Point3f(0, 0, 0)); //return null; } } } GH_Convert.ToGHMesh(mesh, GH_Conversion.Primary, ref ghMesh); return(ghMesh); }
/// <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) { this.Message = Constants.Constants.PARALLEL_MESSAGE; this.AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, Constants.Constants.PARALLEL_WARNING); int processorCount = Environment.ProcessorCount - 1; double docTollerance = DocumentTolerance(); GH_Structure <GH_Mesh> ghPatches = new GH_Structure <GH_Mesh>(); GH_Structure <GH_Curve> inGhCurves = new GH_Structure <GH_Curve>(); bool areCurvesOK = DA.GetDataTree(0, out inGhCurves); CheckGetDataConversion(areCurvesOK); ConcurrentDictionary <GH_Path, Mesh> patchesPA = new ConcurrentDictionary <GH_Path, Mesh>(); Parallel.ForEach(inGhCurves.Paths, new ParallelOptions { MaxDegreeOfParallelism = processorCount }, path => { Polyline firstPolyline = null; inGhCurves.get_DataItem(path, 0).Value.TryGetPolyline(out firstPolyline); if ((!firstPolyline.IsValid ? true : firstPolyline == null)) { this.AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Impossible convert the first Curve in Polyline"); } List <Curve> otherBranchCurves = new List <Curve>(); for (int i = 0; i < inGhCurves.get_Branch(path).Count; i++) { otherBranchCurves.Add(inGhCurves.get_DataItem(path, i).Value.DuplicateCurve()); } patchesPA[path] = Mesh.CreatePatch(firstPolyline, docTollerance, null, otherBranchCurves, null, null, true, 1); }); foreach (KeyValuePair <GH_Path, Mesh> patch in patchesPA) { GH_Mesh ghPatchMesh = null; if (GH_Convert.ToGHMesh(patch.Value, GH_Conversion.Both, ref ghPatchMesh)) { ghPatches.Append(ghPatchMesh, patch.Key); } else { this.AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Conversion Failed"); return; } } DA.SetDataTree(0, ghPatches); }
public static GH_Mesh ProjectSolidMeshToTopo(Mesh topoMesh, Mesh solidMesh) { GH_Mesh ghMesh = new GH_Mesh(); List <Mesh> topoMeshList = new List <Mesh>(); topoMeshList.Add(topoMesh); BoundingBox bb = solidMesh.GetBoundingBox(false); ///get list of verteces from mesh to project Point3d[] originalVerts = solidMesh.Vertices.ToPoint3dArray(); ///create a list of verteces who share the lowest Z value of the bounding box List <Point3d> lowestVerts = originalVerts.Where(lowPoint => lowPoint.Z == bb.Min.Z).ToList(); ///transalte mesh to project up with move vector and save to output array Vector3d moveV = GetMinProjectedPointToMesh(lowestVerts, topoMesh); Vector3d maxV = new Vector3d(0, 0, Double.MaxValue); if (moveV == maxV) { return(null); } ///transalte mesh to project up with move vector and save to output array solidMesh.Translate(moveV); if (solidMesh.IsValid) { GH_Convert.ToGHMesh(solidMesh, GH_Conversion.Primary, ref ghMesh); return(ghMesh); } else { return(null); } }
/*******************************************/ public static bool CastToGoo(object value, ref GH_Mesh target) { return(GH_Convert.ToGHMesh(value, GH_Conversion.Both, ref target)); }
public static GH_Mesh ProjectMeshToTopoSlow(Mesh topoMesh, Mesh topoFlatMesh, Point3d[] topoFlatPoints, RTree rTree, Mesh featureMesh) { ///TODO: Look into using Mesh.SplitWithProjectedPolylines available in RhinoCommon 7.0 GH_Mesh ghMesh = new GH_Mesh(); Mesh[] disjointMeshes = featureMesh.SplitDisjointPieces(); Mesh projectedDisjointMeshes = new Mesh(); foreach (Mesh disjointMesh in disjointMeshes) { ///Flatten disjointMesh first for (int i = 0; i < disjointMesh.Vertices.Count; i++) { Point3f v = disjointMesh.Vertices[i]; v.Z = 0; disjointMesh.Vertices.SetVertex(i, v); } ///Get naked edges and sort list so that outer boundary is first Polyline[] nakedEdges = disjointMesh.GetNakedEdges(); var nakedEdgesCurves = new Dictionary <Curve, double>(); foreach (Polyline p in nakedEdges) { Curve pNurbs = p.ToNurbsCurve(); nakedEdgesCurves.Add(pNurbs, AreaMassProperties.Compute(pNurbs).Area); } var nakedEdgesSorted = from pair in nakedEdgesCurves orderby pair.Value descending select pair.Key; BoundingBox bbox = disjointMesh.GetBoundingBox(false); ///Project naked edges to flat topo to add control points at mesh edge intersections List <Curve> trimCurves = new List <Curve>(); foreach (Curve nakedEdge in nakedEdgesSorted) { Curve[] projectedCurves = Curve.ProjectToMesh(nakedEdge, topoFlatMesh, moveDir, tol); ///If projection of naked edge results in more than one curve, join curves back into one closed curve. ///Approximation at edge of topo is unavoidable if (projectedCurves.Length > 0) { if (projectedCurves.Length > 1) { ///Collector polyline to combine projectedCurves Polyline projBoundary = new Polyline(); ///Add individual curves from Curve.ProjectToMesh together by converting to Polyline and appending the vetexes together foreach (Curve c in projectedCurves) { Polyline tempPolyline = new Polyline(); c.TryGetPolyline(out tempPolyline); projBoundary.AddRange(tempPolyline); } ///Make sure polyine is closed projBoundary.Add(projBoundary[0]); trimCurves.Add(projBoundary.ToNurbsCurve()); } else if (!projectedCurves[0].IsClosed) { Line closer = new Line(projectedCurves[0].PointAtEnd, projectedCurves[0].PointAtStart); Curve closedProjectedCurve = Curve.JoinCurves(new Curve[] { projectedCurves[0], closer.ToNurbsCurve() })[0]; trimCurves.Add(closedProjectedCurve); } else { trimCurves.Add(projectedCurves[0]); } } else { ///Projection missed the topoFlatMesh return(null); } } ///End projected naked edges Polyline pL = new Polyline(); trimCurves[0].TryGetPolyline(out pL); trimCurves.RemoveAt(0); ///Add points from topoMeshFlat to array used for Mesh.CreatePatch List <Point3f> bboxPoints = new List <Point3f>(); ///Try RTree method. RTree of topoFlatPoints ///https://discourse.mcneel.com/t/rtree-bounding-box-search/96282/6 var boxSearchData = new BoxSearchData(); rTree.Search(bbox, BoundingBoxCallback, boxSearchData); foreach (int id in boxSearchData.Ids) { Ray3d ray = new Ray3d((Point3d)topoFlatPoints[id], -moveDir); double t = Rhino.Geometry.Intersect.Intersection.MeshRay(disjointMesh, ray); if (t >= 0.0) { bboxPoints.Add((Point3f)ray.PointAt(t)); } else { Ray3d rayOpp = new Ray3d((Point3d)topoFlatPoints[id], moveDir); double tOpp = Rhino.Geometry.Intersect.Intersection.MeshRay(disjointMesh, rayOpp); if (tOpp >= 0.0) { bboxPoints.Add((Point3f)rayOpp.PointAt(tOpp)); } else { //return null; } } } ///A hack way of adding points to newVerts which is needed in the form of an array for Mesh.CreatePatch disjointMesh.Vertices.AddVertices(bboxPoints); Point3d[] newVerts = disjointMesh.Vertices.ToPoint3dArray(); ///Create patch Mesh mPatch = Mesh.CreatePatch(pL, tol, null, trimCurves, null, newVerts, true, 1); ///Move patch verts to topo for (int i = 0; i < mPatch.Vertices.Count; i++) { Ray3d ray = new Ray3d((Point3d)mPatch.Vertices[i], moveDir); double t = Rhino.Geometry.Intersect.Intersection.MeshRay(topoMesh, ray); if (t >= 0.0) { mPatch.Vertices.SetVertex(i, (Point3f)ray.PointAt(t)); } else { Ray3d rayOpp = new Ray3d((Point3d)mPatch.Vertices[i], -moveDir); double tOpp = Rhino.Geometry.Intersect.Intersection.MeshRay(topoMesh, rayOpp); if (tOpp >= 0.0) { mPatch.Vertices.SetVertex(i, (Point3f)rayOpp.PointAt(tOpp)); } else { return(null); } } } ///Combine disjoint meshes if (mPatch.IsValid) { projectedDisjointMeshes.Append(mPatch); mPatch.Dispose(); } else { return(null); } } projectedDisjointMeshes.Ngons.AddPlanarNgons(tol); projectedDisjointMeshes.Compact(); GH_Convert.ToGHMesh(projectedDisjointMeshes, GH_Conversion.Primary, ref ghMesh); return(ghMesh); }