diff --git a/examples/embree/Makefile b/examples/embree/Makefile new file mode 100644 index 000000000..e81f4318c --- /dev/null +++ b/examples/embree/Makefile @@ -0,0 +1,33 @@ + +.PHONY: all + +# Shared flags etc. +include ../../Makefile.conf + +all: example + +.PHONY: example + +LIBIGL=../../ +LIBIGL_INC=-I$(LIBIGL)/include +LIBIGL_LIB=-L$(LIBIGL)/lib -ligl -liglembree + +EIGEN3_INC=-I/opt/local/include/eigen3 -I/opt/local/include/eigen3/unsupported + +EMBREE=$(LIBIGL)/external/embree +EMBREE_INC=-I$(EMBREE)/rtcore -I$(EMBREE)/common +EMBREE_LIB=-L$(EMBREE)/bin -lrtcore -lsys + +ANTTWEAKBAR_INC=-I$(LIBIGL)/external/AntTweakBar/include +ANTTWEAKBAR_LIB=-L$(LIBIGL)/external/AntTweakBar/lib -lAntTweakBar -framework AppKit +INC=$(LIBIGL_INC) $(ANTTWEAKBAR_INC) $(EIGEN3_INC) $(EMBREE_INC) +LIB=$(OPENGL_LIB) $(GLUT_LIB) $(ANTTWEAKBAR_LIB) $(LIBIGL_LIB) $(EMBREE_LIB) + +example: example.o + g++ $(OPENMP) $(AFLAGS) $(CFLAGS) -o example example.o $(LIB) + +example.o: example.cpp + g++ $(OPENMP) $(AFLAGS) $(CFLAGS) -c example.cpp -o example.o $(INC) +clean: + rm -f example.o + rm -f example diff --git a/examples/embree/example.cpp b/examples/embree/example.cpp new file mode 100644 index 000000000..f2c04cf5d --- /dev/null +++ b/examples/embree/example.cpp @@ -0,0 +1,236 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __APPLE__ +# include +#else +# include +#endif +#include + +#include + +int width,height; +float scene_rot[4] = {0,0,0,1}; +float light_pos[4] = {0.1,0.1,-0.9,0}; +Eigen::MatrixXd V,N,C,mean; +double bbd; +Eigen::MatrixXi F; +igl::EmbreeIntersector ei; +// Ray +Eigen::Vector3d s,d,dir; + +void reshape(int width,int height) +{ + using namespace std; + ::width = width; + ::height = height; + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glViewport(0,0,width,height); +} + +void lights() +{ + using namespace std; + glEnable(GL_LIGHTING); + glLightModelf(GL_LIGHT_MODEL_TWO_SIDE,GL_TRUE); + glEnable(GL_LIGHT0); + glEnable(GL_LIGHT1); + float ones[4] = {1.0,1.0,1.0,1.0}; + float zeros[4] = {0.0,0.0,0.0,0.0}; + float pos[4]; + copy(light_pos,light_pos+4,pos); + glLightfv(GL_LIGHT0,GL_AMBIENT,zeros); + glLightfv(GL_LIGHT0,GL_DIFFUSE,ones); + glLightfv(GL_LIGHT0,GL_SPECULAR,zeros); + glLightfv(GL_LIGHT0,GL_POSITION,pos); + pos[0] *= -1; + pos[1] *= -1; + pos[2] *= -1; + glLightfv(GL_LIGHT1,GL_AMBIENT,zeros); + glLightfv(GL_LIGHT1,GL_DIFFUSE,ones); + glLightfv(GL_LIGHT1,GL_SPECULAR,zeros); + glLightfv(GL_LIGHT1,GL_POSITION,pos); +} + +void push_scene() +{ + using namespace igl; + //gluOrtho2D(0,width,0,height); + gluPerspective(45,(double)width/(double)height,1e-2,100); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + gluLookAt(0,0,3,0,0,0,0,1,0); + glPushMatrix(); + float mat[4*4]; + quat_to_mat(scene_rot,mat); + glMultMatrixf(mat); +} + +void push_object() +{ + glPushMatrix(); + glScaled(2./bbd,2./bbd,2./bbd); + glTranslated(-mean(0,0),-mean(0,1),-mean(0,2)); +} + +void pop_scene() +{ + glPopMatrix(); +} + +void pop_object() +{ + glPopMatrix(); +} + +const float back[4] = {190.0/255.0,190.0/255.0,190.0/255.0,0}; +void display() +{ + using namespace Eigen; + using namespace igl; + glClearColor(back[0],back[1],back[2],0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + lights(); + push_scene(); + + glEnable(GL_DEPTH_TEST); + glEnable(GL_NORMALIZE); + glEnable(GL_COLOR_MATERIAL); + glColorMaterial(GL_FRONT_AND_BACK,GL_AMBIENT_AND_DIFFUSE); + //glColorMaterial(GL_FRONT, GL_DIFFUSE); + //glColorMaterial(GL_FRONT, GL_AMBIENT); + //glColorMaterial(GL_FRONT, GL_SPECULAR); + + + push_object(); + draw_mesh(V,F,N,C); + + glDisable(GL_COLOR_MATERIAL); + glDisable(GL_LIGHTING); + glBegin(GL_POINTS); + glColor3f(1,0,0); + glVertex3dv(s.data()); + glColor3f(0,0,1); + glVertex3dv(d.data()); + glEnd(); + Vector3d n,f; + n = s+1000.0*dir; + f = d-1000.0*dir; + glBegin(GL_LINE); + glColor3f(1,0,0); + glVertex3dv(n.data()); + glColor3f(1,0,0); + glVertex3dv(f.data()); + glEnd(); + + pop_object(); + + glPushMatrix(); + glEnable(GL_LIGHTING); + glTranslated(0,-1,0); + draw_floor(); + glPopMatrix(); + + pop_scene(); + + glutSwapBuffers(); + glutPostRedisplay(); +} + +void init_C() +{ + C.col(0).setConstant(0.4); + C.col(1).setConstant(0.8); + C.col(2).setConstant(0.3); +} + +void mouse_move(int mouse_x, int mouse_y) +{ + using namespace std; + using namespace Eigen; + using namespace igl; + init_C(); + push_scene(); + push_object(); + Vector3d win_s(mouse_x,height-mouse_y,0); + Vector3d win_d(mouse_x,height-mouse_y,1); + unproject(win_s,s); + unproject(win_d,d); + dir = d-s; + embree::Hit hit; + if(ei.intersectRay(s,d,hit)) + { + cout<<"hit!"<(V,FF); + + // Init glut + glutInit(&argc,argv); + glutInitDisplayString( "rgba depth double samples>=8 "); + glutInitWindowSize(glutGet(GLUT_SCREEN_WIDTH),glutGet(GLUT_SCREEN_HEIGHT)); + glutInitWindowSize(450,300); + glutCreateWindow("embree"); + glutDisplayFunc(display); + glutReshapeFunc(reshape); + glutKeyboardFunc(key); + glutPassiveMotionFunc(mouse_move); + glutMainLoop(); + return 0; +} diff --git a/examples/shared/cheburashka.obj.REMOVED.git-id b/examples/shared/cheburashka.obj.REMOVED.git-id new file mode 100644 index 000000000..a750675ec --- /dev/null +++ b/examples/shared/cheburashka.obj.REMOVED.git-id @@ -0,0 +1 @@ +b8f4b722b5901bcb2a17dbc6f9b89eaa14bc8243 \ No newline at end of file diff --git a/include/igl/cat.cpp b/include/igl/cat.cpp index d2fae22e1..1be5576d8 100644 --- a/include/igl/cat.cpp +++ b/include/igl/cat.cpp @@ -144,4 +144,5 @@ template Eigen::Matrix igl::cat igl::cat >(int, Eigen::SparseMatrix const&, Eigen::SparseMatrix const&); // generated by autoexplicit.sh template Eigen::Matrix igl::cat >(int, Eigen::Matrix const&, Eigen::Matrix const&); +template void igl::cat, Eigen::Matrix >(int, Eigen::MatrixBase > const&, Eigen::MatrixBase > const&, Eigen::Matrix&); #endif diff --git a/include/igl/embree/EmbreeIntersector.cpp b/include/igl/embree/EmbreeIntersector.cpp deleted file mode 100755 index a494aa76d..000000000 --- a/include/igl/embree/EmbreeIntersector.cpp +++ /dev/null @@ -1,180 +0,0 @@ -#include "EmbreeIntersector.h" -#include - -template -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(const PointMatrixType & V, const FaceMatrixType & F) -{ - static bool inited = false; - if(!inited) - { - //embree::TaskScheduler::start();//init(); - inited = true; - } - - size_t numVertices = 0; - size_t numTriangles = 0; - - triangles = (embree::BuildTriangle*) embree::rtcMalloc(sizeof(embree::BuildTriangle) * F.rows()); - vertices = (embree::BuildVertex*) embree::rtcMalloc(sizeof(embree::BuildVertex) * V.rows()); - - for(int i = 0; i < (int)V.rows(); ++i) - { - vertices[numVertices++] = embree::BuildVertex((float)V(i,0),(float)V(i,1),(float)V(i,2)); - } - - for(int i = 0; i < (int)F.rows(); ++i) - { - triangles[numTriangles++] = embree::BuildTriangle((int)F(i,0),(int)F(i,1),(int)F(i,2),i); - } - - _accel = embree::rtcCreateAccel("default", "default", triangles, numTriangles, vertices, numVertices); - _intersector = _accel->queryInterface(); -} - -template < -typename PointMatrixType, -typename FaceMatrixType, -typename RowVector3> -igl::EmbreeIntersector < PointMatrixType, FaceMatrixType, RowVector3> -::~EmbreeIntersector() -{ - embree::rtcFreeMemory(); -} - -template < -typename PointMatrixType, -typename FaceMatrixType, -typename RowVector3> -bool -igl::EmbreeIntersector < PointMatrixType, FaceMatrixType, RowVector3> -::intersectRay(const RowVector3& origin, const RowVector3& direction, embree::Hit &hit) const -{ - embree::Ray ray(toVec3f(origin), toVec3f(direction), 1e-4f); - _intersector->intersect(ray, hit); - return hit ; -} - -template < -typename PointMatrixType, -typename FaceMatrixType, -typename RowVector3> -bool -igl::EmbreeIntersector < PointMatrixType, FaceMatrixType, RowVector3> -::intersectRay( - const RowVector3& origin, - const RowVector3& direction, - std::vector &hits, - int & num_rays) const -{ - using namespace std; - num_rays = 0; - hits.clear(); - embree::Vec3f o = toVec3f(origin); - embree::Vec3f d = toVec3f(direction); - int last_id0 = -1; - double self_hits = 0; - // This epsilon is directly correleated to the number of missed hits, smaller - // means more accurate and slower - //const double eps = DOUBLE_EPS; - const double eps = FLOAT_EPS; - double min_t = embree::zero; - bool large_hits_warned = false; - while(true) - { -#ifdef VERBOSE - cout<< - o[0]<<" "< "<< - endl; -#endif - embree::Hit hit; - embree::Ray ray(o,d,min_t); - num_rays++; - _intersector->intersect(ray, hit); - if(hit) - { - // Hit self again, progressively advance - if(hit.id0 == last_id0 || hit.t <= min_t) - { - // sanity check - assert(hit.t<1); - // push min_t a bit more - //double t_push = pow(2.0,self_hits-4)*(hit.t1000 && !large_hits_warned) - { - cerr<<"Warning: Large number of hits..."<::iterator hit = hits.begin(); - hit != hits.end(); - hit++) - { - cerr<<(hit->id0+1)<<" "; - } - cerr.precision(std::numeric_limits< double >::digits10); - cerr<<"[ "; - for(vector::iterator hit = hits.begin(); - hit != hits.end(); - hit++) - { - cerr<<(hit->t)< -bool -igl::EmbreeIntersector < PointMatrixType, FaceMatrixType, RowVector3> -::intersectSegment(const RowVector3& a, const RowVector3& ab, embree::Hit &hit) const -{ - embree::Ray ray(toVec3f(a), toVec3f(ab), embree::zero, embree::one); - _intersector->intersect(ray, hit); - return hit ; -} - -#ifndef IGL_HEADER_ONLY -// Explicit template instanciation -#include -template class igl::EmbreeIntersector, Eigen::Matrix, Eigen::Matrix >; -#endif diff --git a/include/igl/embree/EmbreeIntersector.h b/include/igl/embree/EmbreeIntersector.h index 265dfb714..962ccafcc 100755 --- a/include/igl/embree/EmbreeIntersector.h +++ b/include/igl/embree/EmbreeIntersector.h @@ -24,6 +24,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); virtual ~EmbreeIntersector(); @@ -71,8 +72,195 @@ namespace igl embree::Ref _intersector; }; } -#ifdef IGL_HEADER_ONLY -# include "EmbreeIntersector.cpp" + +// Implementation +#include + +template +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) +{ + static bool inited = false; + if(!inited) + { + //embree::TaskScheduler::start();//init(); + inited = true; + } + + size_t numVertices = 0; + size_t numTriangles = 0; + + triangles = (embree::BuildTriangle*) embree::rtcMalloc(sizeof(embree::BuildTriangle) * F.rows()); + vertices = (embree::BuildVertex*) embree::rtcMalloc(sizeof(embree::BuildVertex) * V.rows()); + + for(int i = 0; i < (int)V.rows(); ++i) + { + vertices[numVertices++] = embree::BuildVertex((float)V(i,0),(float)V(i,1),(float)V(i,2)); + } + + for(int i = 0; i < (int)F.rows(); ++i) + { + triangles[numTriangles++] = embree::BuildTriangle((int)F(i,0),(int)F(i,1),(int)F(i,2),i); + } + + _accel = embree::rtcCreateAccel("default", "default", triangles, numTriangles, vertices, numVertices); + _intersector = _accel->queryInterface(); +} + +template < +typename PointMatrixType, +typename FaceMatrixType, +typename RowVector3> +igl::EmbreeIntersector < PointMatrixType, FaceMatrixType, RowVector3> +::~EmbreeIntersector() +{ + embree::rtcFreeMemory(); +} + +template < +typename PointMatrixType, +typename FaceMatrixType, +typename RowVector3> +bool +igl::EmbreeIntersector < PointMatrixType, FaceMatrixType, RowVector3> +::intersectRay(const RowVector3& origin, const RowVector3& direction, embree::Hit &hit) const +{ + embree::Ray ray(toVec3f(origin), toVec3f(direction), 1e-4f); + _intersector->intersect(ray, hit); + return hit ; +} + +template < +typename PointMatrixType, +typename FaceMatrixType, +typename RowVector3> +bool +igl::EmbreeIntersector < PointMatrixType, FaceMatrixType, RowVector3> +::intersectRay( + const RowVector3& origin, + const RowVector3& direction, + std::vector &hits, + int & num_rays) const +{ + using namespace std; + num_rays = 0; + hits.clear(); + embree::Vec3f o = toVec3f(origin); + embree::Vec3f d = toVec3f(direction); + int last_id0 = -1; + double self_hits = 0; + // This epsilon is directly correleated to the number of missed hits, smaller + // means more accurate and slower + //const double eps = DOUBLE_EPS; + const double eps = FLOAT_EPS; + double min_t = embree::zero; + bool large_hits_warned = false; + while(true) + { +#ifdef VERBOSE + cout<< + o[0]<<" "< "<< + endl; #endif + embree::Hit hit; + embree::Ray ray(o,d,min_t); + num_rays++; + _intersector->intersect(ray, hit); + if(hit) + { + // Hit self again, progressively advance + if(hit.id0 == last_id0 || hit.t <= min_t) + { + // sanity check + assert(hit.t<1); + // push min_t a bit more + //double t_push = pow(2.0,self_hits-4)*(hit.t1000 && !large_hits_warned) + { + cerr<<"Warning: Large number of hits..."<::iterator hit = hits.begin(); + hit != hits.end(); + hit++) + { + cerr<<(hit->id0+1)<<" "; + } + cerr.precision(std::numeric_limits< double >::digits10); + cerr<<"[ "; + for(vector::iterator hit = hits.begin(); + hit != hits.end(); + hit++) + { + cerr<<(hit->t)< +bool +igl::EmbreeIntersector < PointMatrixType, FaceMatrixType, RowVector3> +::intersectSegment(const RowVector3& a, const RowVector3& ab, embree::Hit &hit) const +{ + embree::Ray ray(toVec3f(a), toVec3f(ab), embree::zero, embree::one); + _intersector->intersect(ray, hit); + return hit ; +} #endif //EMBREE_INTERSECTOR_H diff --git a/include/igl/mosek/mosek_quadprog.cpp b/include/igl/mosek/mosek_quadprog.cpp index bc6feae9b..1bd74fbad 100644 --- a/include/igl/mosek/mosek_quadprog.cpp +++ b/include/igl/mosek/mosek_quadprog.cpp @@ -91,15 +91,15 @@ IGL_INLINE bool igl::mosek_quadprog( // Create the MOSEK environment mosek_guarded(MSK_makeenv(&env,NULL,NULL,NULL,NULL)); - /* Directs the log stream to the 'printstr' function. */ - mosek_guarded(MSK_linkfunctoenvstream(env,MSK_STREAM_LOG,NULL,printstr)); + ///* Directs the log stream to the 'printstr' function. */ + //mosek_guarded(MSK_linkfunctoenvstream(env,MSK_STREAM_LOG,NULL,printstr)); // initialize mosek environment mosek_guarded(MSK_initenv(env)); // Create the optimization task mosek_guarded(MSK_maketask(env,m,n,&task)); verbose("Creating task with %ld linear constraints and %ld variables...\n",m,n); - // Tell mosek how to print to std out - mosek_guarded(MSK_linkfunctotaskstream(task,MSK_STREAM_LOG,NULL,printstr)); + //// Tell mosek how to print to std out + //mosek_guarded(MSK_linkfunctotaskstream(task,MSK_STREAM_LOG,NULL,printstr)); // Give estimate of number of variables mosek_guarded(MSK_putmaxnumvar(task,n)); if(m>0) @@ -171,8 +171,7 @@ IGL_INLINE bool igl::mosek_quadprog( pit != mosek_data.intparam.end(); pit++) { - const MSKrescodee r = MSK_putintparam(task,pit->first,pit->second); - mosek_guarded(r); + mosek_guarded(MSK_putintparam(task,pit->first,pit->second)); } for( std::map::iterator pit = mosek_data.douparam.begin(); @@ -187,9 +186,9 @@ IGL_INLINE bool igl::mosek_quadprog( // run the optimizer mosek_guarded(MSK_optimizetrm(task,&trmcode)); - // Print a summary containing information about the solution for debugging - // purposes - MSK_solutionsummary(task,MSK_STREAM_LOG); + //// Print a summary containing information about the solution for debugging + //// purposes + //MSK_solutionsummary(task,MSK_STREAM_LOG); // Get status of solution MSKsolstae solsta;