Mesh Inclusion Error

script
grasshopper
mesh
unhandled

#1

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.

inclusion_test2.gh (233.9 KB)


(Pfotiad0) #2

For a workaround see attached

Mesh_inclusion_V1.gh (18.0 KB)


(Pfotiad0) #3

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?

Mesh_inclusion_V1A.gh (19.5 KB)


(Pfotiad0) #4

And this … er… hmm … is freakier:
Mesh_inclusion_V2.gh (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.


(Pfotiad0) #5

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

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


#6

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!


(Pfotiad0) #7

Can you elaborate more ? What exactly are you after?


#8

[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:


(Pfotiad0) #9

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

Or:

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


#10

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);
        if(test){
          b_id[i] = j;
          break;
        }
      }
    }

    id = b_id;

(Pfotiad0) #11

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.


#12

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);
        }
        else{
          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.


(Pfotiad0) #13

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.


(Pfotiad0) #14

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


#15

thanks, peter, looking forward to the file!


(Pfotiad0) #16

Here it is.

Mesh_inclusion_V3.gh (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).


#17

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.
inclusion_test3.gh (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):


(Pfotiad0) #18

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.


A better approach replicating 'Curves in Curves'