Mesh Inclusion Error

Hi all,

It seems like the MeshInclusion component is not returning expected results in Grasshopper, and nor is calling it in a C# component with tolerance set to relatively high. Whereas the BrepInclusion seems to be returning the correct result. Strict inclusion booleans are both set to false.
I am hoping to get the former working and avoiding using the Brep option since a huge array of meshes will be constructed and undergo the process eventually.

Please find attached the file and below a screenshot (notice item 14 in the panels), thank you. (233.9 KB)

For a workaround see attached (18.0 KB)

In fact forget that (BTW: Internalize failed [very common situation] and GH crashes on opening).

See attached - using as test a thingy from Lunchbox - were really freaky things happen: Karma, what else? (19.5 KB)

1 Like

And this … er… hmm … is freakier: (123.3 KB)

Test points deploy “along” a random Mesh face (if userM is not null and is closed and is valid then this is on duty). That said and since we test pts VS the Mesh skin … the isClosed is not required … but who cares?

Without changing anything else play with the rollTheBones thingy:

Now you see it:

Now you don’t:

A clear proof that you can’t beat Karma.

And some times some points are found (on the same face):

Enabling the closestDistance “override” mode 3 returns all the right points:

thanks peter!

i’d just like to ping this because it would still be nice if the bug/issue of the mesh inclusion component could be addressed. or if anyone might be able to point to a good 3d point in polygon algorithm/library, thanks!

Can you elaborate more ? What exactly are you after?

[EDIT]: should be ‘point in polyhedron’ instead of ‘point in polygon,’ sorry!

basically what the brep inclusion / mesh inclusion of this thread is opened for:

Pardon me but what about the good old thingy?

Curve crv = polyline.ToNurbsCurve();
PointContainment pc = crv.Contains (pt,plane); (or skip plane if you want)

That yields: Unset, Inside, Outside, Coincident


Brep brep = Brep.CreatePlanarBreps(crv)[0];
BrepFace face = brep.Faces[0];
double u,v; face.ClosestPoint(pt,out u, out v);
PointFaceRelation pfr = face.IsPointOnFace(u,v);

That yields: Exterior, Interior, Boundary

hi peter, thanks, and yes i already implemented it in the file included in the original post.
because the mesh inclusion test (or mesh.IsPointInside) doesn’t seem to return the correct results,
i converted the meshes to breps and did the below, but am just wondering if there is any other way to do it faster because for example, with a 50x50x50 point grid to test against 10 breps take quite a while:

(note: i’m interested in getting the brep id that the point is in, on “first hit”)

    int[] b_id = new int[p.Count];
    double tol = RhinoDocument.ModelAbsoluteTolerance;
    for(int i = 0; i < p.Count; ++i){
      b_id[i] = -1;
      for(int j = 0; j < b.Count; ++j){
        bool test = b[j].IsPointInside(p[i], tol, false);
          b_id[i] = j;

    id = b_id;

Mesh faces to Breps is not the fastest way to skin the cat. Not to mention Meshes to Breps (THAT is slow for obvious reasons)

So …you are after “MeshFace contains pt” filtering … so to speak? (BTW quad or tri meshes? or whatever ?).

BTW: given a List or meshes (meaning a Tree of faces) you’ll need trees to manage what face contains what point. Or maybe you need stuff as GH neutral as possible for code portability to/from other apps?

Anyway I’ll test some stuff using 150/200K points and some random meshes.

thanks, peter,
the meshes to breps part actually isn’t that slow comparing to the inclusion part:
(and works for both tri and quad faces)

    Brep[] b_all = new Brep[m.Count];
    for(int i = 0; i < m.Count; ++i){
      var mfl = m[i].Faces;
      var mvl = m[i].Vertices;
      Brep[] bl = new Brep[mfl.Count];
      double tol = RhinoDocument.ModelAbsoluteTolerance;
      for(int j = 0; j < mfl.Count; ++j){
        Brep bp = new Brep();
        if(mfl[j].IsTriangle) {
          bp = Brep.CreateFromCornerPoints(mvl[mfl[j].A], mvl[mfl[j].B], mvl[mfl[j].C], tol);
          bp = Brep.CreateFromCornerPoints(mvl[mfl[j].A], mvl[mfl[j].B], mvl[mfl[j].C], mvl[mfl[j].D], tol);
        bl[j] = bp;
      b_all[i] = Brep.JoinBreps(bl, tol)[0];
    b = b_all;

and i’m not looking for MeshFace containment but (closed) Mesh containment, in other words, i’m not testing for whether a point is on a face, but whether a point is in a closed polyhedron.

Well … since the mesh inclusion Method fails (for pts coincident with faces) … or at least is unpredictable as proved already … THIS is also what are you looking for.

So the 1M question is: If the pt-Mesh min distance < tol (bypass the inclusion) OR mesh contains the point > …

Personally I have a max limit for waiting the stupid part (the computer): around 500 milliseconds no matter the goal.

The following does the 150K pts grid (and places N random (radii, plane, trunc) meshes for inclusion tests) in ~ 50 - 70 milliseconds max (Coffee Lake i7).

Thus the 1Z question is: in the remaining 450 milliseconds can we cut the mustard? I’m thinking to cheat a bit as well (no pain no gain).

More soon.

64K points, 10 random Meshes, one i7, one C# expert Siamese cat (has the gift I confess), no parallel(yet), 3 alternative methods … PLUS the ultra secret thingy useBox (©, TM, US Patent pending).

Thingy enabled (47 milliseconds - more or less “real-time”):

Thingy disabled (40 times slower):

More soon

thanks, peter, looking forward to the file!

Here it is. (130.9 KB)

It’s one of these cases where the proper trick (see the pTree structure and the BIG question that slashes time by a huge factor) equals (kinda) any // (implemented in a hurry) stuff. This is not to say that // is not a good thing … it just requires a certain attention (and in real-life cases where things are quite complex … a lot of attention) .

PS: all the above IF we accept that a box out of a mesh works OK (cross fingers).

PS: the approach is fast because it discards a zillion of checks by asking a very cheap question (and then and only then asks the 2 expensive ones). Notice that the time (~50-70 milliseconds) is not proportional to the N of points.

That said I haven’t found time to implement the 2 MIA // ways: PLINQ and MT (more on these soon).

thanks! works pretty well for single items, but when I feed a series (for instance values from 0 to 10) of meshes, it becomes much slower.

check the attached out if you are interested. (665.3 KB)

since i’m only after tetrahedra for containment test now, i came across this, and slightly modified it to avoid strict testing (for when points are on faces or edges):

Er … my dear Watson the thing in order to work properly requires a pTree structure (3 path dim etc etc) EXACTLY as is made inside the first C#. Why? because the questions with regard the 3 box domains (second C#).

Your test (A pts List, not Tree not to mention x,y, z values) if feeded > all king’s horses and all king’s men … blah, blah.

Since V3 requires 60 milliseconds to handle 10 rather complex random meshes … imagine using your very simple stuff.

I know this is an old thread, but it seems like the solution has not been found.

Today I encountered the same error while working with huge point cloud / mesh data sets. Actually this bug is hardly noticeable, because it’s rather random. I found out that rounding the coordinates of points helps and makes the results reliable.

I noticed that if points’ coordinates look like
new Point3d(1.237928032875061, 0.762071967124939, 1.237928032875061)
then the Mesh.IsPointInside() will give unpredictable results (I tested on simple mesh boxes). Rounding to numbers with six or less fractional digits like
new Point3d(1.237928, 0.762071, 1.237928)
makes the results reliable. Try this on your test definitions. It works for me and I think it’s fine since the guaranteed double precision is 6 fractional digits.

Btw writing own mesh inclusion (i.e. shooting semi-infinite rays from point and checking if the number of intersections is even or not) works fine, but is slower because Mesh.IsPointInside() uses fast unmanaged C++ libraries.

I guess the bug might have its roots in converting numerical types between managed and unmanaged code, but McNeel developers could probably elaborate a bit more about that.

I attach a test definition with internalized / hard-coded values to recreate the bug. (14.5 KB)


Indeed the Mesh Inclusion native component in Grasshopper is still throwing wrong results when mesh is complex. Issue/Bug still not addressed.