SOLVED [Toxiclibs] Is there a quicker method to test mesh inclusion

edited October 2016 in Library Questions

Hi

I was looking to see if I could test if a point was inside a mesh. I was looking online and found this article which suggested raytracing as a method and find the number of intersections. Using toxiclibs I could find if a ray intersected a mesh only according to the mesh normals. So I had to check against two meshes, one which is flipped.

It works but it just takes a long time to test and I also have to loop through the function a few times to get rid of all the points( even though I shouldnt need to).

Anyway is there a quicker method to check that, maybe with another library. Here is my code.

import java.util.*;
import peasy.*;
import toxi.geom.*;
import toxi.geom.mesh.*;
import toxi.processing.ToxiclibsSupport;


import wblut.processing.*;
import wblut.hemesh.*;
import wblut.geom.*;



private ToxiclibsSupport gfx;
TriangleMesh cave;
TriangleMesh cave2;




ArrayList<Vec3D> pts = new ArrayList<Vec3D>();


public void settings() {
  size(1400, 800, P3D);
  smooth();
}

public void setup() {


  cave = (TriangleMesh) new STLReader().loadBinary(sketchPath("data/" + "cave.stl"), STLReader.TRIANGLEMESH);
  cave2 = (TriangleMesh) new STLReader().loadBinary(sketchPath("data/" + "cave.stl"), STLReader.TRIANGLEMESH);
  cave2.flipVertexOrder();

  Vec3D a = cave.computeCentroid();
  PeasyCam cam = new PeasyCam(this, a.x, a.y, 0, 2200);

  gfx = new ToxiclibsSupport(this);

  for (int i = 0; i < 20; i++) {
    for (int j = 0; j < 20; j++) {
      for (int k = 0; k < 20; k++) {
        pts.add(new Vec3D(i * 70, j * 70, k * 30));
      }
    }
  }

  //Point in Mesh Function ( a bit slow)

  for (int j = 0; j < 10; j++) {    // Need to run it a few times
    for (int i = 0; i < pts.size(); i++) {
      Vec3D v = pts.get(i);
      Ray3D r = new Ray3D(v, new Vec3D(0, 0, 1));
      if (!cave.intersectsRay(r)) {
        pts.remove(v);
      } else {
        if (cave2.intersectsRay(r)) {
          pts.remove(v);
        }
      }
    }
  }

}


public void draw() {
  background(0);

  for (Vec3D a : pts) {
    stroke(255);
    strokeWeight(2);
    point(a.x, a.y, a.z);
  }

  pushMatrix();
  fill(40, 120);
  noStroke();
  lights();
  gfx.mesh(cave2, false, 0);
  popMatrix();

}

Answers

  • I'm not certain about meshes specifically, but doesn't almost everything in Toxiclibs implement containsPoint?

    If it doesn't, you could find a flat cross-section of the mesh and then run Polygon2D.containsPoint on that. Might be cleaner than an external library.

  • edited October 2016 Answer ✓

    Doing an angle check between the the vector between the point being considered and the closest point on the mesh and the normal at the closest point on the mesh seems to be the quickest way to solve this.

    for (int i = 0; i < pts.size(); i++) {     
            Vec3D v = pts.get(i);
            Vec3D cavept = cave.getClosestVertexToPoint(pt);
    
            Vec3D a1 = cavept.copy().subSelf(v);
            Vec3D a2 = Normal.get(cavept);
    
            float ang = a2.angleBetween(a1,true);
            float ang2 = degrees(ang);
            if (ang2 > 90) {
                pts.remove(v);
            }
    
            if (distpt < 55 * 55) {
                pts.remove(v);
            }
      }
    

    Here Normal is a HashMap containing normals.

Sign In or Register to comment.