Detecting if an area intersects a mesh in CPlane


#1

I have a mesh that represents landscape. I need to work through this mesh from the bottom left to the top right in 50m squares, detecting whether this 50m square intersects with the mesh (z is ignored - only interested in x & y). Currently I do this by created points for the 50m square and ProjectToMesh - if any points hit the mesh - then I know that there is mesh in the area that I am interested in.

There must be a neater way to do this? Can I project the mesh to CPlane in C# (If so, how?) . If I have the mesh in the CPlane - I should be able to create 4 lines for the edges of the 50m square and check intersection with:

Rhino.Geometry.Intersect.Intersection.MeshLine shouldn’t I?

Any thoughts appreciated!?

ETA: Just found this about transforming to construction plane - which might help project the mesh to cplane… off to try it now


(Menno Deij - van Rijswijk) #2

For project-to-CPlane, you can use the Plane.ClosestPoint method of the CPlane. Just modify each mesh vertex using this method.

In this case I would maybe create a small cube mesh of 50x50 that sits on both sides of the CPlane and intersect it with the projected mesh using Intersection.MeshMeshFast. But I guess that Intersection.MeshLine also works. It might even be faster, you only need to have one line with an intersection (not overlap) and you know that the square(s) bounding the intersecting line intersect the mesh.

You might even consider a divide-and-conquer approach by first testing larger lines and only testing smaller lines if the larger line has at least one intersection. I suppose it depends on the structure of the mesh and the number of expected intersections.


#3

Thanks for your suggestions. I think I’m OK with the second half of it but I’m still struggling with the first half - getting the original mesh in the Construction Plane. I tried the suggestion from the link above by doing this:

Rhino.Geometry.Plane worldPlane = Rhino.Geometry.Plane.WorldXY;
Rhino.Geometry.Plane localPlane = doc.Views.ActiveView.ActiveViewport.ConstructionPlane();
Rhino.Geometry.Transform xform = Rhino.Geometry.Transform.ChangeBasis(worldPlane, localPlane);
Rhino.Geometry.Mesh localMesh = inputmesh.DuplicateMesh();
localMesh.Transform(xform);
doc.Objects.AddMesh(localMesh);
doc.Views.Redraw();

I just get a copy of the original mesh with the same Z heights as before. Alternatively I tried to go through all the vertices and change their Z height - but can’t change that because “it’s not a variable”. I also tried the above transform on every vertex of the mesh - but that didn’t do anything either. Am I missing something stupid or is it more complicated than the attempts I’ve made so far!?


(Menno Deij - van Rijswijk) #4

The transformation is only a basis change (think of it like an exchange of axes). It will not flatten your mesh. And if the CPlane is WorldXY the transformation does nothing.

change their Z height - but can’t change that because “it’s not a variable”

Ah, you have run into the niceties of value types (structs)! One of the problems is that you can’t change value type structs in an array. Change like this:

for(int i = 0; i < m.Vertices.Count; ++i)
{
    Point3d v = m.Vertices[i]; // get a copy of the vertex position 
    v.Z = 0; // change it
    m.Vertices[i] = v; // re-assign it
}

#5

Argh. (Hangs head in shame) Thank you!