Browse Source

better mem management in embreeintersector and corerct unporject in mesh

Former-commit-id: 2123af384c6bd2a2872bbf8a0e365ce54d584efa
Alec Jacobson (jalec 11 years ago
parent
commit
07fb81e068

+ 3 - 0
include/igl/Viewport.h

@@ -36,6 +36,9 @@ namespace igl
       this->width = width;
       this->height = height;
     };
+    // Given mouse_x,mouse_y on the entire window return mouse_x, mouse_y in
+    // this viewport.
+    //
     // Inputs:
     //   my  mouse y-coordinate
     //   wh  window weight

+ 13 - 0
include/igl/draw_point.cpp

@@ -74,4 +74,17 @@ IGL_INLINE void igl::draw_point(
   //if(old_depth_test) glEnable(GL_DEPTH_TEST);
 }
 
+template <typename DerivedP>
+IGL_INLINE void igl::draw_point(
+  const Eigen::PlainObjectBase<DerivedP> & P,
+  const double requested_r,
+  const bool selected)
+{
+  return draw_point(P(0),P(1),P(2),requested_r,selected);
+}
+
+#ifndef IGL_HEADER_ONLY
+template void igl::draw_point<Eigen::Matrix<double, 3, 1, 0, 3, 1> >(Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> > const&, double, bool);
+#endif
+
 #endif

+ 6 - 0
include/igl/draw_point.h

@@ -2,6 +2,7 @@
 #define IGL_DRAW_POINT_H
 #ifndef IGL_NO_OPENGL
 #include "igl_inline.h"
+#include <Eigen/Core>
 namespace igl
 {
   //double POINT_COLOR[3] = {239./255.,213./255.,46./255.};
@@ -22,6 +23,11 @@ namespace igl
     const double z,
     const double requested_r = 7,
     const bool selected = false);
+  template <typename DerivedP>
+  IGL_INLINE void draw_point(
+    const Eigen::PlainObjectBase<DerivedP> & P,
+    const double requested_r = 7,
+    const bool selected = false);
 }
 
 #ifdef IGL_HEADER_ONLY

+ 36 - 45
include/igl/embree/EmbreeIntersector.h

@@ -1,31 +1,6 @@
 #ifndef IGL_EMBREE_INTERSECTOR_H
 #define IGL_EMBREE_INTERSECTOR_H
-
-#undef interface
-#undef near
-#undef far
-
-// Why are these in quotes? isn't that a bad idea?
-#ifdef __GNUC__
-// This is how it should be done
-#  if __GNUC__ >= 4
-#    if __GNUC_MINOR__ >= 6
-#      pragma GCC diagnostic push
-#      pragma GCC diagnostic ignored "-Weffc++"
-#    endif
-#  endif
-// This is a hack
-#  pragma GCC system_header
-#endif
-#include "common/intersector.h"
-#include "common/accel.h"
-#ifdef __GNUC__
-#  if __GNUC__ >= 4
-#    if __GNUC_MINOR__ >= 6
-#      pragma GCC diagnostic pop
-#    endif
-#  endif
-#endif
+#include "Embree_convenience.h"
 
 #include <vector>
 //#include "types.h"
@@ -44,8 +19,7 @@ namespace igl
     //
     // Note: this will only find front-facing hits. To consider all hits then
     // pass [F;fliplr(F)]
-    EmbreeIntersector();
-    EmbreeIntersector(const PointMatrixType & V, const FaceMatrixType & F);
+    EmbreeIntersector(const PointMatrixType & V = PointMatrixType(), const FaceMatrixType &  F = FaceMatrixType());
     virtual ~EmbreeIntersector();
   
     // Given a ray find the first *front-facing* hit
@@ -84,10 +58,9 @@ namespace igl
     //   hit  embree information about hit
     // Returns true if and only if there was a hit
     bool intersectSegment(const RowVector3& a, const RowVector3& ab, embree::Hit &hit) const;
+    //RowVector3 hit_position(const embree::Hit & hit) const;
     
   private:
-    embree::BuildTriangle *triangles;
-    embree::BuildVertex *vertices;
     embree::Ref<embree::Accel> _accel;
     embree::Ref<embree::Intersector> _intersector;
   };
@@ -99,27 +72,15 @@ namespace igl
 template <typename RowVector3>
 inline embree::Vec3f toVec3f(const RowVector3 &p) { return embree::Vec3f((float)p[0], (float)p[1], (float)p[2]); }
 
-template <
-typename PointMatrixType,
-typename FaceMatrixType,
-typename RowVector3>
-igl::EmbreeIntersector < PointMatrixType, FaceMatrixType, RowVector3>
-::EmbreeIntersector()
-{
-  static bool inited = false;
-  if(!inited)
-  {
-	//embree::TaskScheduler::start();//init();
-    inited = true;
-  }
-}
-
 template <
 typename PointMatrixType,
 typename FaceMatrixType,
 typename RowVector3>
 igl::EmbreeIntersector < PointMatrixType, FaceMatrixType, RowVector3>
 ::EmbreeIntersector(const PointMatrixType & V, const FaceMatrixType & F)
+  :
+    _accel(),
+    _intersector()
 {
   static bool inited = false;
   if(!inited)
@@ -128,9 +89,15 @@ igl::EmbreeIntersector < PointMatrixType, FaceMatrixType, RowVector3>
     inited = true;
   }
   
+  if(V.size() == 0 || F.size() == 0)
+  {
+    return;
+  }
   size_t numVertices = 0;
   size_t numTriangles = 0;
   
+  embree::BuildTriangle *triangles;
+  embree::BuildVertex *vertices;
   triangles = (embree::BuildTriangle*) embree::rtcMalloc(sizeof(embree::BuildTriangle) * F.rows());
   vertices = (embree::BuildVertex*) embree::rtcMalloc(sizeof(embree::BuildVertex) * V.rows());
 
@@ -283,4 +250,28 @@ igl::EmbreeIntersector < PointMatrixType, FaceMatrixType, RowVector3>
   return hit ; 
 }
 
+//template <
+//typename PointMatrixType,
+//typename FaceMatrixType,
+//typename RowVector3>
+//RowVector3 
+//igl::EmbreeIntersector < PointMatrixType, FaceMatrixType, RowVector3>
+//::hit_position(const embree::Hit & hit) const
+//{
+//  // Barycenteric coordinates
+//  const double w0 = (1.0-hit.u-hit.v);
+//  const double w1 = hit.u;
+//  const double w2 = hit.v;
+//  RowVector3 hitP;
+//  hitP.resize(3);
+//  for(int d = 0;d<3;d++)
+//  {
+//    hitP(d) = 
+//    w0 * vertices[triangles[hit.id0](0)](d) + 
+//    w1 * vertices[triangles[hit.id0](1)](d) + 
+//    w2 * vertices[triangles[hit.id0](2)](d);
+//  }
+//  return hitP;
+//}
+
 #endif //EMBREE_INTERSECTOR_H

+ 29 - 0
include/igl/embree/Embree_convenience.h

@@ -0,0 +1,29 @@
+#ifndef IGL_EMBREE_CONVENIENCE_H
+#define IGL_EMBREE_CONVENIENCE_H
+
+#undef interface
+#undef near
+#undef far
+// Why are these in quotes? isn't that a bad idea?
+#ifdef __GNUC__
+// This is how it should be done
+#  if __GNUC__ >= 4
+#    if __GNUC_MINOR__ >= 6
+#      pragma GCC diagnostic push
+#      pragma GCC diagnostic ignored "-Weffc++"
+#    endif
+#  endif
+// This is a hack
+#  pragma GCC system_header
+#endif
+#include <common/intersector.h>
+#include <common/accel.h>
+#ifdef __GNUC__
+#  if __GNUC__ >= 4
+#    if __GNUC_MINOR__ >= 6
+#      pragma GCC diagnostic pop
+#    endif
+#  endif
+#endif
+
+#endif

+ 22 - 6
include/igl/embree/unproject_in_mesh.cpp

@@ -8,11 +8,27 @@ template <
   typename FaceMatrixType,
   typename RowVector3,
   typename Derivedobj>
-bool igl::unproject_in_mesh(
+int igl::unproject_in_mesh(
   const int x,
   const int y,
   const igl::EmbreeIntersector<PointMatrixType,FaceMatrixType,RowVector3> & ei,
   Eigen::PlainObjectBase<Derivedobj> & obj)
+{
+  std::vector<embree::Hit> hits;
+  return igl::unproject_in_mesh(x,y,ei,obj,hits);
+}
+
+template <
+  typename PointMatrixType,
+  typename FaceMatrixType,
+  typename RowVector3,
+  typename Derivedobj>
+int igl::unproject_in_mesh(
+  const int x,
+  const int y,
+  const igl::EmbreeIntersector<PointMatrixType,FaceMatrixType,RowVector3> & ei,
+  Eigen::PlainObjectBase<Derivedobj> & obj,
+  std::vector<embree::Hit > & hits)
 {
   using namespace igl;
   using namespace std;
@@ -27,12 +43,12 @@ bool igl::unproject_in_mesh(
   dir = d-s;
   // Shoot ray, collect all hits (could just collect first two)
   int num_rays_shot;
-  vector<embree::Hit > hits;
+  hits.clear();
   ei.intersectRay(s,dir,hits,num_rays_shot);
   switch(hits.size())
   {
     case 0:
-      return false;
+      break;
     case 1:
     {
       obj = s + dir*hits[0].t;
@@ -41,13 +57,13 @@ bool igl::unproject_in_mesh(
     case 2:
     default:
     {
-      obj = 0.5*((s + dir*hits[0].t) + (s + dir*hits[hits.size()-1].t));
+      obj = 0.5*((s + dir*hits[0].t) + (s + dir*hits[1].t));
       break;
     }
   }
-  return true;
+  return hits.size();
 }
 
 #ifndef IGL_HEADER_ONLY
-template bool igl::unproject_in_mesh<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, 3, 1, 0, 3, 1>, Eigen::Matrix<double, 3, 1, 0, 3, 1> >(int, int, igl::EmbreeIntersector<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, 3, 1, 0, 3, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> >&);
+template int igl::unproject_in_mesh<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, 3, 1, 0, 3, 1>, Eigen::Matrix<double, 3, 1, 0, 3, 1> >(int, int, igl::EmbreeIntersector<Eigen::Matrix<double, -1, -1, 0, -1, -1>, Eigen::Matrix<int, -1, -1, 0, -1, -1>, Eigen::Matrix<double, 3, 1, 0, 3, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> >&);
 #endif

+ 17 - 4
include/igl/embree/unproject_in_mesh.h

@@ -1,9 +1,11 @@
 #ifndef IGL_UNPROJECT_IN_MESH
 #define IGL_UNPROJECT_IN_MESH
-
 #include <igl/igl_inline.h>
 #include <Eigen/Core>
 
+#include <vector>
+#include "Embree_convenience.h"
+
 namespace igl
 {
   // Forward define
@@ -21,19 +23,30 @@ namespace igl
   //    ei  EmbreeIntersector containing (V,F)
   // Outputs:
   //    obj  3d unprojected mouse point in mesh
-  // Returns true only if ray through (x,y) hits (V,F) at least
-  // once
+  // Returns number of hits
   //
   template <
     typename PointMatrixType,
     typename FaceMatrixType,
     typename RowVector3,
     typename Derivedobj>
-  bool unproject_in_mesh(
+  int unproject_in_mesh(
     const int x,
     const int y,
     const igl::EmbreeIntersector<PointMatrixType,FaceMatrixType,RowVector3> & ei,
     Eigen::PlainObjectBase<Derivedobj> & obj);
+
+  template <
+    typename PointMatrixType,
+    typename FaceMatrixType,
+    typename RowVector3,
+    typename Derivedobj>
+  int unproject_in_mesh(
+    const int x,
+    const int y,
+    const igl::EmbreeIntersector<PointMatrixType,FaceMatrixType,RowVector3> & ei,
+    Eigen::PlainObjectBase<Derivedobj> & obj,
+    std::vector<embree::Hit > & hits);
 }
 #ifdef IGL_HEADER_ONLY
 #  include "unproject_in_mesh.cpp"