|
@@ -1,10 +1,10 @@
|
|
|
// This file is part of libigl, a simple c++ geometry processing library.
|
|
|
-//
|
|
|
+//
|
|
|
// Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
|
|
|
// 2014 Christian Schüller <schuellchr@gmail.com>
|
|
|
-//
|
|
|
-// This Source Code Form is subject to the terms of the Mozilla Public License
|
|
|
-// v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
|
|
+//
|
|
|
+// This Source Code Form is subject to the terms of the Mozilla Public License
|
|
|
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can
|
|
|
// obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
// igl function interface for Embree2.2
|
|
|
//
|
|
@@ -43,7 +43,7 @@ namespace igl
|
|
|
public:
|
|
|
typedef Eigen::Matrix<float,Eigen::Dynamic,3> PointMatrixType;
|
|
|
typedef Eigen::Matrix<int,Eigen::Dynamic,3> FaceMatrixType;
|
|
|
- public:
|
|
|
+ public:
|
|
|
inline EmbreeIntersector();
|
|
|
private:
|
|
|
// Copying and assignment are not allowed.
|
|
@@ -51,7 +51,7 @@ namespace igl
|
|
|
inline EmbreeIntersector & operator=(const EmbreeIntersector &);
|
|
|
public:
|
|
|
virtual inline ~EmbreeIntersector();
|
|
|
-
|
|
|
+
|
|
|
// Initialize with a given mesh.
|
|
|
//
|
|
|
// Inputs:
|
|
@@ -62,7 +62,7 @@ namespace igl
|
|
|
inline void init(
|
|
|
const PointMatrixType& V,
|
|
|
const FaceMatrixType& F);
|
|
|
-
|
|
|
+
|
|
|
// Initialize with a given mesh.
|
|
|
//
|
|
|
// Inputs:
|
|
@@ -75,14 +75,14 @@ namespace igl
|
|
|
const std::vector<const PointMatrixType*>& V,
|
|
|
const std::vector<const FaceMatrixType*>& F,
|
|
|
const std::vector<int>& masks);
|
|
|
-
|
|
|
+
|
|
|
// Deinitialize embree datasctructures for current mesh. Also called on
|
|
|
// destruction: no need to call if you just want to init() once and
|
|
|
// destroy.
|
|
|
inline void deinit();
|
|
|
-
|
|
|
+
|
|
|
// Given a ray find the first hit
|
|
|
- //
|
|
|
+ //
|
|
|
// Inputs:
|
|
|
// origin 3d origin point of ray
|
|
|
// direction 3d (not necessarily normalized) direction vector of ray
|
|
@@ -93,17 +93,17 @@ namespace igl
|
|
|
// hit information about hit
|
|
|
// Returns true if and only if there was a hit
|
|
|
inline bool intersectRay(
|
|
|
- const Eigen::RowVector3f& origin,
|
|
|
+ const Eigen::RowVector3f& origin,
|
|
|
const Eigen::RowVector3f& direction,
|
|
|
Hit& hit,
|
|
|
float tnear = 0,
|
|
|
float tfar = std::numeric_limits<float>::infinity(),
|
|
|
int mask = 0xFFFFFFFF) const;
|
|
|
-
|
|
|
+
|
|
|
// Given a ray find the first hit
|
|
|
// This is a conservative hit test where multiple rays within a small radius
|
|
|
// will be tested and only the closesest hit is returned.
|
|
|
- //
|
|
|
+ //
|
|
|
// Inputs:
|
|
|
// origin 3d origin point of ray
|
|
|
// direction 3d (not necessarily normalized) direction vector of ray
|
|
@@ -123,10 +123,11 @@ namespace igl
|
|
|
float tfar = std::numeric_limits<float>::infinity(),
|
|
|
int mask = 0xFFFFFFFF,
|
|
|
int geoId = -1,
|
|
|
- bool closestHit = true) const;
|
|
|
-
|
|
|
+ bool closestHit = true,
|
|
|
+ unsigned int samples = 4) const;
|
|
|
+
|
|
|
// Given a ray find all hits in order
|
|
|
- //
|
|
|
+ //
|
|
|
// Inputs:
|
|
|
// origin 3d origin point of ray
|
|
|
// direction 3d (not necessarily normalized) direction vector of ray
|
|
@@ -145,9 +146,9 @@ namespace igl
|
|
|
float tnear = 0,
|
|
|
float tfar = std::numeric_limits<float>::infinity(),
|
|
|
int mask = 0xFFFFFFFF) const;
|
|
|
-
|
|
|
+
|
|
|
// Given a ray find the first hit
|
|
|
- //
|
|
|
+ //
|
|
|
// Inputs:
|
|
|
// a 3d first end point of segment
|
|
|
// ab 3d vector from a to other endpoint b
|
|
@@ -159,18 +160,18 @@ namespace igl
|
|
|
const Eigen::RowVector3f& ab,
|
|
|
Hit &hit,
|
|
|
int mask = 0xFFFFFFFF) const;
|
|
|
-
|
|
|
+
|
|
|
private:
|
|
|
-
|
|
|
+
|
|
|
struct Vertex {float x,y,z,a;};
|
|
|
struct Triangle {int v0, v1, v2;};
|
|
|
-
|
|
|
+
|
|
|
RTCScene scene;
|
|
|
unsigned geomID;
|
|
|
Vertex* vertices;
|
|
|
Triangle* triangles;
|
|
|
bool initialized;
|
|
|
-
|
|
|
+
|
|
|
inline void createRay(
|
|
|
RTCRay& ray,
|
|
|
const Eigen::RowVector3f& origin,
|
|
@@ -267,10 +268,10 @@ inline void igl::embree::EmbreeIntersector::init(
|
|
|
const std::vector<const FaceMatrixType*>& F,
|
|
|
const std::vector<int>& masks)
|
|
|
{
|
|
|
-
|
|
|
+
|
|
|
if(initialized)
|
|
|
deinit();
|
|
|
-
|
|
|
+
|
|
|
using namespace std;
|
|
|
global_init();
|
|
|
|
|
@@ -279,7 +280,7 @@ inline void igl::embree::EmbreeIntersector::init(
|
|
|
std::cerr << "Embree: No geometry specified!";
|
|
|
return;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// create a scene
|
|
|
scene = rtcNewScene(RTC_SCENE_ROBUST | RTC_SCENE_HIGH_QUALITY,RTC_INTERSECT1);
|
|
|
|
|
@@ -312,7 +313,7 @@ inline void igl::embree::EmbreeIntersector::init(
|
|
|
}
|
|
|
|
|
|
rtcCommit(scene);
|
|
|
-
|
|
|
+
|
|
|
if(rtcGetError() != RTC_NO_ERROR)
|
|
|
std::cerr << "Embree: An error occured while initializing the provided geometry!" << endl;
|
|
|
#ifdef IGL_VERBOSE
|
|
@@ -359,14 +360,14 @@ inline bool igl::embree::EmbreeIntersector::intersectRay(
|
|
|
{
|
|
|
RTCRay ray;
|
|
|
createRay(ray, origin,direction,tnear,tfar,mask);
|
|
|
-
|
|
|
+
|
|
|
// shot ray
|
|
|
rtcIntersect(scene,ray);
|
|
|
#ifdef IGL_VERBOSE
|
|
|
if(rtcGetError() != RTC_NO_ERROR)
|
|
|
std::cerr << "Embree: An error occured while resetting!" << std::endl;
|
|
|
#endif
|
|
|
-
|
|
|
+
|
|
|
if((unsigned)ray.geomID != RTC_INVALID_GEOMETRY_ID)
|
|
|
{
|
|
|
hit.id = ray.primID;
|
|
@@ -381,7 +382,7 @@ inline bool igl::embree::EmbreeIntersector::intersectRay(
|
|
|
}
|
|
|
|
|
|
inline bool igl::embree::EmbreeIntersector::intersectBeam(
|
|
|
- const Eigen::RowVector3f& origin,
|
|
|
+ const Eigen::RowVector3f& origin,
|
|
|
const Eigen::RowVector3f& direction,
|
|
|
Hit& hit,
|
|
|
float tnear,
|
|
@@ -401,15 +402,15 @@ inline bool igl::embree::EmbreeIntersector::intersectBeam(
|
|
|
|
|
|
if(hasHit = (intersectRay(origin,direction,hit,tnear,tfar,mask) && (hit.gid == geoId || geoId == -1)))
|
|
|
bestHit = hit;
|
|
|
-
|
|
|
+
|
|
|
// sample points around actual ray (conservative hitcheck)
|
|
|
const float eps= 1e-5;
|
|
|
-
|
|
|
+
|
|
|
Eigen::RowVector3f up(0,1,0);
|
|
|
Eigen::RowVector3f offset = direction.cross(up).normalized();
|
|
|
|
|
|
Eigen::Matrix3f rot = Eigen::AngleAxis<float>(2*3.14159265358979/samples,direction).toRotationMatrix();
|
|
|
-
|
|
|
+
|
|
|
for(int r=0;r<samples;r++)
|
|
|
{
|
|
|
if(intersectRay(origin+offset*eps,direction,hit,tnear,tfar,mask) && ((closestHit && (hit.t < bestHit.t)) || (!closestHit && (hit.t > bestHit.t))) && (hit.gid == geoId || geoId == -1))
|
|
@@ -424,10 +425,10 @@ inline bool igl::embree::EmbreeIntersector::intersectBeam(
|
|
|
return hasHit;
|
|
|
}
|
|
|
|
|
|
-inline bool
|
|
|
+inline bool
|
|
|
igl::embree::EmbreeIntersector
|
|
|
::intersectRay(
|
|
|
- const Eigen::RowVector3f& origin,
|
|
|
+ const Eigen::RowVector3f& origin,
|
|
|
const Eigen::RowVector3f& direction,
|
|
|
std::vector<Hit > &hits,
|
|
|
int& num_rays,
|
|
@@ -496,7 +497,7 @@ igl::embree::EmbreeIntersector
|
|
|
}
|
|
|
else
|
|
|
break; // no more hits
|
|
|
-
|
|
|
+
|
|
|
if(hits.size()>1000 && !large_hits_warned)
|
|
|
{
|
|
|
std::cout<<"Warning: Large number of hits..."<<endl;
|
|
@@ -505,10 +506,10 @@ igl::embree::EmbreeIntersector
|
|
|
{
|
|
|
std::cout<<(hit->id+1)<<" ";
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
std::cout.precision(std::numeric_limits< double >::digits10);
|
|
|
std::cout<<"[ ";
|
|
|
-
|
|
|
+
|
|
|
for(vector<Hit>::iterator hit = hits.begin(); hit != hits.end(); hit++)
|
|
|
{
|
|
|
std::cout<<(hit->t)<<endl;;
|
|
@@ -524,13 +525,13 @@ igl::embree::EmbreeIntersector
|
|
|
return hits.empty();
|
|
|
}
|
|
|
|
|
|
-inline bool
|
|
|
+inline bool
|
|
|
igl::embree::EmbreeIntersector
|
|
|
::intersectSegment(const Eigen::RowVector3f& a, const Eigen::RowVector3f& ab, Hit &hit, int mask) const
|
|
|
{
|
|
|
RTCRay ray;
|
|
|
createRay(ray,a,ab,0,1.0,mask);
|
|
|
-
|
|
|
+
|
|
|
rtcIntersect(scene,ray);
|
|
|
|
|
|
if((unsigned)ray.geomID != RTC_INVALID_GEOMETRY_ID)
|
|
@@ -565,4 +566,4 @@ igl::embree::EmbreeIntersector
|
|
|
ray.time = 0.0f;
|
|
|
}
|
|
|
|
|
|
-#endif //EMBREE_INTERSECTOR_H
|
|
|
+#endif //EMBREE_INTERSECTOR_H
|