diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..cbfe9b7b0 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,17 @@ +Before opening an issue on creating a pull request, please check the following: + +## Compilation Issues + +- If you are on Windows, did you select the **x64** version of the Visual Studio compiler? + +- If you have a **CMake issue**, make sure you follow the same approach as the [libigl-example-project](https://github.com/libigl/libigl-example-project) to build libigl with your project, and make sure that you can compile the example project. + +- If you have an issue with a **submodule**, check if your submodules are up to date. If you have a doubt about a submodule, delete its folder and run `git submodule update --init --recursive` in the libigl directory. + +- If you have an issue with a missing **template issue**, check if your code compile with the *header-only* option of libigl activated. Turn **`OFF`** the CMake option `LIBIGL_USE_STATIC_LIBRARY`: either modify your `CMakeCache.txt` via CMake GUI or ccmake, or delete your `CMakeCache.txt` and re-run `cmake -DLIBIGL_USE_STATIC_LIBRARY=OFF ..` in your build folder. + +- Make sure your read the [**FAQ**](https://github.com/libigl/libigl/wiki/FAQ) before asking a new question, and search [**existing issues**](https://github.com/libigl/libigl/issues?q=is%3Aissue+is%3Aclosed) for a problem similar to yours. + +- Make sure you read the informations contained in the libigl [homepage](https://github.com/libigl/libigl) as well as the [tutorials](http://libigl.github.io/libigl/tutorial/tutorial.html). + +- If none of these solve your problem, then please report your issue in the bug tracker! diff --git a/include/igl/grad.cpp b/include/igl/grad.cpp index 93d9ef939..9089e52c8 100644 --- a/include/igl/grad.cpp +++ b/include/igl/grad.cpp @@ -36,10 +36,11 @@ IGL_INLINE void grad_tet(const Eigen::PlainObjectBase&V, F.row(3*m + i) << T(i,1), T(i,3), T(i,2); } // compute volume of each tet - VectorXd vol; igl::volume(V,T,vol); + Eigen::Matrix vol; + igl::volume(V,T,vol); - VectorXd A(F.rows()); - MatrixXd N(F.rows(),3); + Eigen::Matrix A(F.rows()); + Eigen::Matrix N(F.rows(),3); if (!uniform) { // compute tetrahedron face normals igl::per_face_normals(V,F,N); int norm_rows = N.rows(); @@ -149,7 +150,7 @@ IGL_INLINE void grad_tri(const Eigen::PlainObjectBase&V, // get h (by the area of the triangle) double h = sqrt( (dblA)/sin(M_PI / 3.0)); // (h^2*sin(60))/2. = Area => h = sqrt(2*Area/sin_60) - Eigen::Vector3d v1,v2,v3; + Eigen::Matrix v1,v2,v3; v1 << 0,0,0; v2 << h,0,0; v3 << h/2.,(sqrt(3)/2.)*h,0; diff --git a/include/igl/matlab/mexErrMsgTxt.cpp b/include/igl/matlab/mexErrMsgTxt.cpp index bd405faa9..89dda1fa3 100644 --- a/include/igl/matlab/mexErrMsgTxt.cpp +++ b/include/igl/matlab/mexErrMsgTxt.cpp @@ -7,9 +7,6 @@ // obtain one at http://mozilla.org/MPL/2.0/. #include "mexErrMsgTxt.h" -// Overload mexErrMsgTxt to check an assertion then print text only if -// assertion fails -#include "mex.h" IGL_INLINE void igl::matlab::mexErrMsgTxt(bool assertion, const char * text) { if(!assertion) diff --git a/include/igl/matlab/mexErrMsgTxt.h b/include/igl/matlab/mexErrMsgTxt.h index bdd76e75b..61b838e6e 100644 --- a/include/igl/matlab/mexErrMsgTxt.h +++ b/include/igl/matlab/mexErrMsgTxt.h @@ -8,6 +8,9 @@ #ifndef IGL_MATLAB_MEXERRMSGTXT_H #define IGL_MATLAB_MEXERRMSGTXT_H #include "../igl_inline.h" +// Overload mexErrMsgTxt to check an assertion then print text only if +// assertion fails +#include "mex.h" namespace igl { namespace matlab diff --git a/include/igl/opengl/MeshGL.cpp b/include/igl/opengl/MeshGL.cpp index 9736d9a77..e4ccabc98 100644 --- a/include/igl/opengl/MeshGL.cpp +++ b/include/igl/opengl/MeshGL.cpp @@ -165,109 +165,114 @@ IGL_INLINE void igl::opengl::MeshGL::init() } is_initialized = true; std::string mesh_vertex_shader_string = - "#version 150\n" - "uniform mat4 view;" - "uniform mat4 proj;" - "uniform mat4 normal_matrix;" - "in vec3 position;" - "in vec3 normal;" - "out vec3 position_eye;" - "out vec3 normal_eye;" - "in vec4 Ka;" - "in vec4 Kd;" - "in vec4 Ks;" - "in vec2 texcoord;" - "out vec2 texcoordi;" - "out vec4 Kai;" - "out vec4 Kdi;" - "out vec4 Ksi;" +R"(#version 150 + uniform mat4 view; + uniform mat4 proj; + uniform mat4 normal_matrix; + in vec3 position; + in vec3 normal; + out vec3 position_eye; + out vec3 normal_eye; + in vec4 Ka; + in vec4 Kd; + in vec4 Ks; + in vec2 texcoord; + out vec2 texcoordi; + out vec4 Kai; + out vec4 Kdi; + out vec4 Ksi; - "void main()" - "{" - " position_eye = vec3 (view * vec4 (position, 1.0));" - " normal_eye = vec3 (normal_matrix * vec4 (normal, 0.0));" - " normal_eye = normalize(normal_eye);" - " gl_Position = proj * vec4 (position_eye, 1.0);" //proj * view * vec4(position, 1.0);" - " Kai = Ka;" - " Kdi = Kd;" - " Ksi = Ks;" - " texcoordi = texcoord;" - "}"; + void main() + { + position_eye = vec3 (view * vec4 (position, 1.0)); + normal_eye = vec3 (normal_matrix * vec4 (normal, 0.0)); + normal_eye = normalize(normal_eye); + gl_Position = proj * vec4 (position_eye, 1.0); //proj * view * vec4(position, 1.0);" + Kai = Ka; + Kdi = Kd; + Ksi = Ks; + texcoordi = texcoord; + } +)"; std::string mesh_fragment_shader_string = - "#version 150\n" - "uniform mat4 view;" - "uniform mat4 proj;" - "uniform vec4 fixed_color;" - "in vec3 position_eye;" - "in vec3 normal_eye;" - "uniform vec3 light_position_eye;" - "vec3 Ls = vec3 (1, 1, 1);" - "vec3 Ld = vec3 (1, 1, 1);" - "vec3 La = vec3 (1, 1, 1);" - "in vec4 Ksi;" - "in vec4 Kdi;" - "in vec4 Kai;" - "in vec2 texcoordi;" - "uniform sampler2D tex;" - "uniform float specular_exponent;" - "uniform float lighting_factor;" - "uniform float texture_factor;" - "out vec4 outColor;" - "void main()" - "{" - "vec3 Ia = La * vec3(Kai);" // ambient intensity +R"(#version 150 + uniform mat4 view; + uniform mat4 proj; + uniform vec4 fixed_color; + in vec3 position_eye; + in vec3 normal_eye; + uniform vec3 light_position_eye; + vec3 Ls = vec3 (1, 1, 1); + vec3 Ld = vec3 (1, 1, 1); + vec3 La = vec3 (1, 1, 1); + in vec4 Ksi; + in vec4 Kdi; + in vec4 Kai; + in vec2 texcoordi; + uniform sampler2D tex; + uniform float specular_exponent; + uniform float lighting_factor; + uniform float texture_factor; + out vec4 outColor; + void main() + { + vec3 Ia = La * vec3(Kai); // ambient intensity - "vec3 vector_to_light_eye = light_position_eye - position_eye;" - "vec3 direction_to_light_eye = normalize (vector_to_light_eye);" - "float dot_prod = dot (direction_to_light_eye, normalize(normal_eye));" - "float clamped_dot_prod = max (dot_prod, 0.0);" - "vec3 Id = Ld * vec3(Kdi) * clamped_dot_prod;" // Diffuse intensity + vec3 vector_to_light_eye = light_position_eye - position_eye; + vec3 direction_to_light_eye = normalize (vector_to_light_eye); + float dot_prod = dot (direction_to_light_eye, normalize(normal_eye)); + float clamped_dot_prod = max (dot_prod, 0.0); + vec3 Id = Ld * vec3(Kdi) * clamped_dot_prod; // Diffuse intensity - "vec3 reflection_eye = reflect (-direction_to_light_eye, normalize(normal_eye));" - "vec3 surface_to_viewer_eye = normalize (-position_eye);" - "float dot_prod_specular = dot (reflection_eye, surface_to_viewer_eye);" - "dot_prod_specular = float(abs(dot_prod)==dot_prod) * max (dot_prod_specular, 0.0);" - "float specular_factor = pow (dot_prod_specular, specular_exponent);" - "vec3 Is = Ls * vec3(Ksi) * specular_factor;" // specular intensity - "vec4 color = vec4(lighting_factor * (Is + Id) + Ia + (1.0-lighting_factor) * vec3(Kdi),(Kai.a+Ksi.a+Kdi.a)/3);" - "outColor = mix(vec4(1,1,1,1), texture(tex, texcoordi), texture_factor) * color;" - "if (fixed_color != vec4(0.0)) outColor = fixed_color;" - "}"; + vec3 reflection_eye = reflect (-direction_to_light_eye, normalize(normal_eye)); + vec3 surface_to_viewer_eye = normalize (-position_eye); + float dot_prod_specular = dot (reflection_eye, surface_to_viewer_eye); + dot_prod_specular = float(abs(dot_prod)==dot_prod) * max (dot_prod_specular, 0.0); + float specular_factor = pow (dot_prod_specular, specular_exponent); + vec3 Is = Ls * vec3(Ksi) * specular_factor; // specular intensity + vec4 color = vec4(lighting_factor * (Is + Id) + Ia + (1.0-lighting_factor) * vec3(Kdi),(Kai.a+Ksi.a+Kdi.a)/3); + outColor = mix(vec4(1,1,1,1), texture(tex, texcoordi), texture_factor) * color; + if (fixed_color != vec4(0.0)) outColor = fixed_color; + } +)"; std::string overlay_vertex_shader_string = - "#version 150\n" - "uniform mat4 view;" - "uniform mat4 proj;" - "in vec3 position;" - "in vec3 color;" - "out vec3 color_frag;" +R"(#version 150 + uniform mat4 view; + uniform mat4 proj; + in vec3 position; + in vec3 color; + out vec3 color_frag; - "void main()" - "{" - " gl_Position = proj * view * vec4 (position, 1.0);" - " color_frag = color;" - "}"; + void main() + { + gl_Position = proj * view * vec4 (position, 1.0); + color_frag = color; + }; +)"; std::string overlay_fragment_shader_string = - "#version 150\n" - "in vec3 color_frag;" - "out vec4 outColor;" - "void main()" - "{" - " outColor = vec4(color_frag, 1.0);" - "}"; +R"(#version 150 + in vec3 color_frag; + out vec4 outColor; + void main() + { + outColor = vec4(color_frag, 1.0); + } +)"; std::string overlay_point_fragment_shader_string = - "#version 150\n" - "in vec3 color_frag;" - "out vec4 outColor;" - "void main()" - "{" - " if (length(gl_PointCoord - vec2(0.5)) > 0.5)" - " discard;" - " outColor = vec4(color_frag, 1.0);" - "}"; +R"(#version 150 + in vec3 color_frag; + out vec4 outColor; + void main() + { + if (length(gl_PointCoord - vec2(0.5)) > 0.5) + discard; + outColor = vec4(color_frag, 1.0); + } +)"; init_buffers(); create_shader_program( diff --git a/include/igl/opengl/ViewerData.cpp b/include/igl/opengl/ViewerData.cpp index f1c730bb2..9cec330b4 100644 --- a/include/igl/opengl/ViewerData.cpp +++ b/include/igl/opengl/ViewerData.cpp @@ -528,7 +528,9 @@ IGL_INLINE void igl::opengl::ViewerData::updateGL( // Texture coordinates if (meshgl.dirty & MeshGL::DIRTY_UV) + { meshgl.V_uv_vbo = data.V_uv.cast(); + } } else { @@ -541,36 +543,35 @@ IGL_INLINE void igl::opengl::ViewerData::updateGL( if (meshgl.dirty & MeshGL::DIRTY_AMBIENT) { - meshgl.V_ambient_vbo.resize(4,data.F.rows()*3); + meshgl.V_ambient_vbo.resize(data.F.rows()*3,4); for (unsigned i=0; i(); + meshgl.V_ambient_vbo.row(i*3+j) = data.V_material_ambient.row(data.F(i,j)).cast(); } if (meshgl.dirty & MeshGL::DIRTY_DIFFUSE) { - meshgl.V_diffuse_vbo.resize(4,data.F.rows()*3); + meshgl.V_diffuse_vbo.resize(data.F.rows()*3,4); for (unsigned i=0; i(); + meshgl.V_diffuse_vbo.row(i*3+j) = data.V_material_diffuse.row(data.F(i,j)).cast(); } if (meshgl.dirty & MeshGL::DIRTY_SPECULAR) { - meshgl.V_specular_vbo.resize(4,data.F.rows()*3); + meshgl.V_specular_vbo.resize(data.F.rows()*3,4); for (unsigned i=0; i(); + meshgl.V_specular_vbo.row(i*3+j) = data.V_material_specular.row(data.F(i,j)).cast(); } if (meshgl.dirty & MeshGL::DIRTY_NORMAL) { - meshgl.V_normals_vbo.resize(3,data.F.rows()*3); + meshgl.V_normals_vbo.resize(data.F.rows()*3,3); for (unsigned i=0; i() : - data.V_normals.row(data.F(i,j)).transpose().cast(); + data.F_normals.row(i*3+j).cast() : + data.V_normals.row(data.F(i,j)).cast(); if (invert_normals) diff --git a/include/igl/opengl/glfw/Viewer.cpp b/include/igl/opengl/glfw/Viewer.cpp index 911142002..66f90205c 100644 --- a/include/igl/opengl/glfw/Viewer.cpp +++ b/include/igl/opengl/glfw/Viewer.cpp @@ -172,8 +172,8 @@ namespace glfw printf("Failed to load OpenGL and its extensions\n"); return(-1); } - printf("OpenGL Version %d.%d loaded\n", GLVersion.major, GLVersion.minor); #if defined(DEBUG) || defined(_DEBUG) + printf("OpenGL Version %d.%d loaded\n", GLVersion.major, GLVersion.minor); int major, minor, rev; major = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MAJOR); minor = glfwGetWindowAttrib(window, GLFW_CONTEXT_VERSION_MINOR); @@ -413,6 +413,8 @@ namespace glfw data().uniform_colors(Eigen::Vector3d(51.0/255.0,43.0/255.0,33.3/255.0), Eigen::Vector3d(255.0/255.0,228.0/255.0,58.0/255.0), Eigen::Vector3d(255.0/255.0,235.0/255.0,80.0/255.0)); + + // Alec: why? if (data().V_uv.rows() == 0) { data().grid_texture(); diff --git a/include/igl/opengl/glfw/Viewer.h b/include/igl/opengl/glfw/Viewer.h index 16e77acbd..55e5c3349 100644 --- a/include/igl/opengl/glfw/Viewer.h +++ b/include/igl/opengl/glfw/Viewer.h @@ -142,8 +142,8 @@ namespace glfw std::function callback_mouse_scroll; std::function callback_key_pressed; // THESE SHOULD BE DEPRECATED: - std::function callback_key_down; - std::function callback_key_up; + std::function callback_key_down; + std::function callback_key_up; // Pointers to per-callback data void* callback_init_data; void* callback_pre_draw_data; diff --git a/include/igl/principal_curvature.cpp b/include/igl/principal_curvature.cpp index 5054cccac..5712130a0 100644 --- a/include/igl/principal_curvature.cpp +++ b/include/igl/principal_curvature.cpp @@ -105,13 +105,12 @@ public: } - IGL_INLINE static Quadric fit(std::vector &VV, bool zeroDetCheck, bool svd) + IGL_INLINE static Quadric fit(const std::vector &VV) { - using namespace std; assert(VV.size() >= 5); if (VV.size() < 5) { - cerr << "ASSERT FAILED!" << endl; + std::cerr << "ASSERT FAILED! fit function requires at least 5 points: Only " << VV.size() << " were given." << std::endl; exit(0); } @@ -160,8 +159,6 @@ public: bool localMode; /* Use local mode */ bool projectionPlaneCheck; /* Check collected vertices on tangent plane */ bool montecarlo; - bool svd; /* Use svd calculation instead of pseudoinverse */ - bool zeroDetCheck; /* Check if the determinant is close to zero */ unsigned int montecarloN; searchType st; /* Use either a sphere search or a k-ring search */ @@ -179,23 +176,23 @@ public: IGL_INLINE CurvatureCalculator(); IGL_INLINE void init(const Eigen::MatrixXd& V, const Eigen::MatrixXi& F); - IGL_INLINE void finalEigenStuff (int, std::vector, Quadric ); - IGL_INLINE void fitQuadric (Eigen::Vector3d, std::vector ref, const std::vector& , Quadric *); - IGL_INLINE void applyProjOnPlane(Eigen::Vector3d, std::vector, std::vector&); + IGL_INLINE void finalEigenStuff(int, const std::vector&, Quadric&); + IGL_INLINE void fitQuadric(const Eigen::Vector3d&, const std::vector& ref, const std::vector& , Quadric *); + IGL_INLINE void applyProjOnPlane(const Eigen::Vector3d&, const std::vector&, std::vector&); IGL_INLINE void getSphere(const int, const double, std::vector&, int min); IGL_INLINE void getKRing(const int, const double,std::vector&); - IGL_INLINE Eigen::Vector3d project(Eigen::Vector3d, Eigen::Vector3d, Eigen::Vector3d); - IGL_INLINE void computeReferenceFrame(int, Eigen::Vector3d, std::vector&); - IGL_INLINE void getAverageNormal(int, std::vector, Eigen::Vector3d&); - IGL_INLINE void getProjPlane(int, std::vector, Eigen::Vector3d&); - IGL_INLINE void applyMontecarlo(std::vector&,std::vector*); + IGL_INLINE Eigen::Vector3d project(const Eigen::Vector3d&, const Eigen::Vector3d&, const Eigen::Vector3d&); + IGL_INLINE void computeReferenceFrame(int, const Eigen::Vector3d&, std::vector&); + IGL_INLINE void getAverageNormal(int, const std::vector&, Eigen::Vector3d&); + IGL_INLINE void getProjPlane(int, const std::vector&, Eigen::Vector3d&); + IGL_INLINE void applyMontecarlo(const std::vector&,std::vector*); IGL_INLINE void computeCurvature(); - IGL_INLINE void printCurvature(std::string outpath); + IGL_INLINE void printCurvature(const std::string& outpath); IGL_INLINE double getAverageEdge(); - IGL_INLINE static int rotateForward (float *v0, float *v1, float *v2) + IGL_INLINE static int rotateForward (double *v0, double *v1, double *v2) { - float t; + double t; if (std::abs(*v2) >= std::abs(*v1) && std::abs(*v2) >= std::abs(*v0)) return 0; @@ -208,9 +205,9 @@ public: return 1 + rotateForward (v0, v1, v2); } - IGL_INLINE static void rotateBackward (int nr, float *v0, float *v1, float *v2) + IGL_INLINE static void rotateBackward (int nr, double *v0, double *v1, double *v2) { - float t; + double t; if (nr == 0) return; @@ -223,18 +220,18 @@ public: rotateBackward (nr - 1, v0, v1, v2); } - IGL_INLINE static Eigen::Vector3d chooseMax (Eigen::Vector3d n, Eigen::Vector3d abc, float ab) + IGL_INLINE static Eigen::Vector3d chooseMax (Eigen::Vector3d n, Eigen::Vector3d abc, double ab) { - int i, max_i; - float max_sp; + int max_i; + double max_sp; Eigen::Vector3d nt[8]; n.normalize (); abc.normalize (); - max_sp = - std::numeric_limits::max(); + max_sp = - std::numeric_limits::max(); - for (i = 0; i < 4; i++) + for (int i = 0; i < 4; ++i) { nt[i] = n; if (ab > 0) @@ -290,7 +287,6 @@ public: max_i = i; } } - return nt[max_i]; } @@ -315,8 +311,6 @@ IGL_INLINE CurvatureCalculator::CurvatureCalculator() this->montecarlo=false; this->montecarloN=0; this->kRing=3; - this->svd=true; - this->zeroDetCheck=true; this->curvatureComputed=false; this->expStep=true; } @@ -337,7 +331,7 @@ IGL_INLINE void CurvatureCalculator::init(const Eigen::MatrixXd& V, const Eigen: igl::per_vertex_normals(V, F, face_normals, vertex_normals); } -IGL_INLINE void CurvatureCalculator::fitQuadric (Eigen::Vector3d v, std::vector ref, const std::vector& vv, Quadric *q) +IGL_INLINE void CurvatureCalculator::fitQuadric(const Eigen::Vector3d& v, const std::vector& ref, const std::vector& vv, Quadric *q) { std::vector points; points.reserve (vv.size()); @@ -354,17 +348,25 @@ IGL_INLINE void CurvatureCalculator::fitQuadric (Eigen::Vector3d v, std::vector< double z = vTang.dot(ref[2]); points.push_back(Eigen::Vector3d (x,y,z)); } - *q = Quadric::fit (points, zeroDetCheck, svd); + if (points.size() < 5) + { + std::cerr << "ASSERT FAILED! fit function requires at least 5 points: Only " << points.size() << " were given." << std::endl; + *q = Quadric(0,0,0,0,0); + } + else + { + *q = Quadric::fit (points); + } } -IGL_INLINE void CurvatureCalculator::finalEigenStuff (int i, std::vector ref, Quadric q) +IGL_INLINE void CurvatureCalculator::finalEigenStuff(int i, const std::vector& ref, Quadric& q) { - double a = q.a(); - double b = q.b(); - double c = q.c(); - double d = q.d(); - double e = q.e(); + const double a = q.a(); + const double b = q.b(); + const double c = q.c(); + const double d = q.d(); + const double e = q.e(); // if (fabs(a) < 10e-8 || fabs(b) < 10e-8) // { @@ -457,7 +459,7 @@ IGL_INLINE void CurvatureCalculator::getKRing(const int start, const double r, s vv.push_back(toVisit); if (distance<(int)r) { - for (unsigned int i=0; ifront(); queue->pop_front(); vv.push_back(toVisit); - for (unsigned int i=0; ipush_back(neighbor); else if ((int)vv.size() cand=extra_candidates->top(); extra_candidates->pop(); vv.push_back(cand.first); - for (unsigned int i=0; ipush(std::pair(neighbor,distance)); visited[neighbor]=true; } @@ -525,16 +527,15 @@ IGL_INLINE void CurvatureCalculator::getSphere(const int start, const double r, free(visited); } -IGL_INLINE Eigen::Vector3d CurvatureCalculator::project(Eigen::Vector3d v, Eigen::Vector3d vp, Eigen::Vector3d ppn) +IGL_INLINE Eigen::Vector3d CurvatureCalculator::project(const Eigen::Vector3d& v, const Eigen::Vector3d& vp, const Eigen::Vector3d& ppn) { return (vp - (ppn * ((vp - v).dot(ppn)))); } -IGL_INLINE void CurvatureCalculator::computeReferenceFrame(int i, Eigen::Vector3d normal, std::vector& ref ) +IGL_INLINE void CurvatureCalculator::computeReferenceFrame(int i, const Eigen::Vector3d& normal, std::vector& ref ) { - Eigen::Vector3d longest_v=Eigen::Vector3d::Zero(); - longest_v=Eigen::Vector3d(vertices.row(vertex_to_vertices[i][0])); + Eigen::Vector3d longest_v=Eigen::Vector3d(vertices.row(vertex_to_vertices[i][0])); longest_v=(project(vertices.row(i),longest_v,normal)-Eigen::Vector3d(vertices.row(i))).normalized(); @@ -546,25 +547,25 @@ IGL_INLINE void CurvatureCalculator::computeReferenceFrame(int i, Eigen::Vector3 ref[2]=normal; } -IGL_INLINE void CurvatureCalculator::getAverageNormal(int j, std::vector vv, Eigen::Vector3d& normal) +IGL_INLINE void CurvatureCalculator::getAverageNormal(int j, const std::vector& vv, Eigen::Vector3d& normal) { normal=(vertex_normals.row(j)).normalized(); if (localMode) return; - for (unsigned int i=0; i vv, Eigen::Vector3d& ppn) +IGL_INLINE void CurvatureCalculator::getProjPlane(int j, const std::vector& vv, Eigen::Vector3d& ppn) { int nr; - float a, b, c; - float nx, ny, nz; - float abcq; + double a, b, c; + double nx, ny, nz; + double abcq; a = b = c = 0; @@ -605,9 +606,9 @@ IGL_INLINE double CurvatureCalculator::getAverageEdge() double sum = 0; int count = 0; - for (int i = 0; i vin, std::vector &vout) +IGL_INLINE void CurvatureCalculator::applyProjOnPlane(const Eigen::Vector3d& ppn, const std::vector& vin, std::vector &vout) { - for (std::vector::iterator vpi = vin.begin(); vpi != vin.end(); ++vpi) - if (vertex_normals.row(*vpi) * ppn > 0.0f) - vout.push_back (*vpi); + for (std::vector::const_iterator vpi = vin.begin(); vpi != vin.end(); ++vpi) + if (vertex_normals.row(*vpi) * ppn > 0.0) + vout.push_back(*vpi); } -IGL_INLINE void CurvatureCalculator::applyMontecarlo(std::vector& vin, std::vector *vout) +IGL_INLINE void CurvatureCalculator::applyMontecarlo(const std::vector& vin, std::vector *vout) { if (montecarloN >= vin.size ()) { @@ -639,24 +640,22 @@ IGL_INLINE void CurvatureCalculator::applyMontecarlo(std::vector& vin, std: } float p = ((float) montecarloN) / (float) vin.size(); - for (std::vector::iterator vpi = vin.begin(); vpi != vin.end(); ++vpi) + for (std::vector::const_iterator vpi = vin.begin(); vpi != vin.end(); ++vpi) { float r; if ((r = ((float)rand () / RAND_MAX)) < p) { - vout->push_back (*vpi); + vout->push_back(*vpi); } } } IGL_INLINE void CurvatureCalculator::computeCurvature() { - using namespace std; - //CHECK che esista la mesh - size_t vertices_count=vertices.rows() ; + const size_t vertices_count=vertices.rows(); - if (vertices_count <=0) + if (vertices_count ==0) return; curvDir=std::vector< std::vector >(vertices_count); @@ -691,10 +690,9 @@ IGL_INLINE void CurvatureCalculator::computeCurvature() return; } - std::vector ref(3); if (vv.size()<6) { - std::cerr << "Could not compute curvature of radius " << scaledRadius << endl; + std::cerr << "Could not compute curvature of radius " << scaledRadius << std::endl; return; } @@ -704,8 +702,7 @@ IGL_INLINE void CurvatureCalculator::computeCurvature() vvtmp.reserve (vv.size ()); applyProjOnPlane (vertex_normals.row(i), vv, vvtmp); if (vvtmp.size() >= 6 && vvtmp.size() ref(3); computeReferenceFrame(i,normal,ref); Quadric q; @@ -748,7 +746,7 @@ IGL_INLINE void CurvatureCalculator::computeCurvature() curvatureComputed=true; } -IGL_INLINE void CurvatureCalculator::printCurvature(std::string outpath) +IGL_INLINE void CurvatureCalculator::printCurvature(const std::string& outpath) { using namespace std; if (!curvatureComputed) @@ -765,7 +763,7 @@ IGL_INLINE void CurvatureCalculator::printCurvature(std::string outpath) int vertices_count=vertices.rows(); of << vertices_count << endl; - for (int i=0; i= 2, fixing it to 2." << endl; + std::cout << "WARNING: igl::principal_curvature needs a radius >= 2, fixing it to 2." << std::endl; } // Preallocate memory @@ -823,10 +819,8 @@ IGL_INLINE void igl::principal_curvature( cc.computeCurvature(); // Copy it back - for (unsigned i=0; i 10e-6) { - cerr << "PRINCIPAL_CURVATURE: Something is wrong with vertex: i" << endl; + std::cerr << "PRINCIPAL_CURVATURE: Something is wrong with vertex: " << i << std::endl; PD1.row(i) *= 0; PD2.row(i) *= 0; } diff --git a/include/igl/slice_cached.h b/include/igl/slice_cached.h index d9496131e..84ced8dc9 100644 --- a/include/igl/slice_cached.h +++ b/include/igl/slice_cached.h @@ -14,9 +14,11 @@ namespace igl { - // Act like the matlab X(row_indices,col_indices) operator, where - // row_indices, col_indices are non-negative integer indices. This is a fast version - // of igl::slice that can analyze and store the sparsity structure. It is slower at the // first evaluation (slice_cached_precompute), but faster on the subsequent ones. + // Act like the matlab X(row_indices,col_indices) operator, where row_indices, + // col_indices are non-negative integer indices. This is a fast version of + // igl::slice that can analyze and store the sparsity structure. It is slower + // at the irst evaluation (slice_cached_precompute), but faster on the + // subsequent ones. // // Inputs: // X m by n matrix diff --git a/shared/cmake/libigl.cmake b/shared/cmake/libigl.cmake index 5ddca0eac..ceaf1195b 100644 --- a/shared/cmake/libigl.cmake +++ b/shared/cmake/libigl.cmake @@ -1,24 +1,42 @@ cmake_minimum_required(VERSION 3.1) +### Find packages to populate default options ### +# +# COMPONENTS should match subsequent calls +find_package(CGAL COMPONENTS Core) # --> CGAL_FOUND +find_package(Boost 1.48 COMPONENTS thread system) # --> BOOST_FOUND +if(CGAL_FOUND AND BOOST_FOUND) + set(CGAL_AND_BOOST_FOUND TRUE) +endif() +find_package(Matlab COMPONENTS MEX_COMPILER MX_LIBRARY ENG_LIBRARY) # --> Matlab_FOUND +find_package(MOSEK) # --> MOSEK_FOUND +find_package(OpenGL) # --> OPENGL_FOUND + ### Available options ### option(LIBIGL_USE_STATIC_LIBRARY "Use libigl as static library" OFF) option(LIBIGL_WITH_ANTTWEAKBAR "Use AntTweakBar" OFF) -option(LIBIGL_WITH_CGAL "Use CGAL" ON) +option(LIBIGL_WITH_CGAL "Use CGAL" "${CGAL_AND_BOOST_FOUND}") option(LIBIGL_WITH_COMISO "Use CoMiso" ON) option(LIBIGL_WITH_CORK "Use Cork" OFF) option(LIBIGL_WITH_EMBREE "Use Embree" OFF) option(LIBIGL_WITH_LIM "Use LIM" ON) -option(LIBIGL_WITH_MATLAB "Use Matlab" ON) -option(LIBIGL_WITH_MOSEK "Use MOSEK" ON) -option(LIBIGL_WITH_OPENGL "Use OpenGL" ON) -option(LIBIGL_WITH_OPENGL_GLFW "Use GLFW" ON) -option(LIBIGL_WITH_OPENGL_GLFW_IMGUI "Use ImGui" ON) +option(LIBIGL_WITH_MATLAB "Use Matlab" "${Matlab_FOUND}") +option(LIBIGL_WITH_MOSEK "Use MOSEK" "${MOSEK_FOUND}") +option(LIBIGL_WITH_NANOGUI "Use Nanogui menu" OFF) +option(LIBIGL_WITH_OPENGL "Use OpenGL" "${OPENGL_FOUND}") +option(LIBIGL_WITH_OPENGL_GLFW "Use GLFW" "${OPENGL_FOUND}") +option(LIBIGL_WITH_OPENGL_GLFW_IMGUI "Use IMGUI" OFF) option(LIBIGL_WITH_PNG "Use PNG" ON) option(LIBIGL_WITH_TETGEN "Use Tetgen" ON) option(LIBIGL_WITH_TRIANGLE "Use Triangle" ON) +option(LIBIGL_WITH_VIEWER "Use OpenGL viewer" "${OPENGL_FOUND}") option(LIBIGL_WITH_XML "Use XML" ON) option(LIBIGL_WITH_PYTHON "Use Python" OFF) +if(LIBIGL_WITH_VIEWER AND (NOT LIBIGL_WITH_OPENGL_GLFW OR NOT LIBIGL_WITH_OPENGL) ) + message(FATAL_ERROR "LIBIGL_WITH_VIEWER=ON requires LIBIGL_WITH_OPENGL_GLFW=ON and LIBIGL_WITH_OPENGL=ON") +endif() + ################################################################################ ### Configuration @@ -128,19 +146,15 @@ endif() if(LIBIGL_WITH_CGAL) # CGAL Core is needed for # `Exact_predicates_exact_constructions_kernel_with_sqrt` - find_package(CGAL COMPONENTS Core) - if(CGAL_FOUND) - compile_igl_module("cgal") - if(WIN32) - set(Boost_USE_STATIC_LIBS ON) # Favor static Boost libs on Windows - endif() - target_include_directories(igl_cgal ${IGL_SCOPE} "${GMP_INCLUDE_DIR}" "${MPFR_INCLUDE_DIR}") - find_package(Boost 1.48 REQUIRED thread system) - target_include_directories(igl_cgal ${IGL_SCOPE} ${CGAL_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}) - target_link_libraries(igl_cgal ${IGL_SCOPE} CGAL::CGAL CGAL::CGAL_Core ${Boost_LIBRARIES}) - else() - set(LIBIGL_WITH_CGAL OFF CACHE BOOL "" FORCE) + find_package(CGAL REQUIRED COMPONENTS Core) + compile_igl_module("cgal") + if(WIN32) + set(Boost_USE_STATIC_LIBS ON) # Favor static Boost libs on Windows endif() + target_include_directories(igl_cgal ${IGL_SCOPE} "${GMP_INCLUDE_DIR}" "${MPFR_INCLUDE_DIR}") + find_package(Boost 1.48 REQUIRED thread system) + target_include_directories(igl_cgal ${IGL_SCOPE} ${CGAL_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}) + target_link_libraries(igl_cgal ${IGL_SCOPE} CGAL::CGAL CGAL::CGAL_Core ${Boost_LIBRARIES}) endif() # Helper function for `igl_copy_cgal_dll()` @@ -241,28 +255,20 @@ endif() ################################################################################ ### Compile the matlab part ### if(LIBIGL_WITH_MATLAB) - find_package(Matlab) - if(MATLAB_FOUND) - compile_igl_module("matlab") - target_link_libraries(igl_matlab ${IGL_SCOPE} ${MATLAB_LIBRARIES}) - target_include_directories(igl_matlab ${IGL_SCOPE} ${MATLAB_INCLUDE_DIR}) - else() - set(LIBIGL_WITH_MATLAB OFF CACHE BOOL "" FORCE) - endif() + find_package(Matlab REQUIRED COMPONENTS MEX_COMPILER MX_LIBRARY ENG_LIBRARY) + compile_igl_module("matlab") + target_link_libraries(igl_matlab ${IGL_SCOPE} ${Matlab_LIBRARIES}) + target_include_directories(igl_matlab ${IGL_SCOPE} ${Matlab_INCLUDE_DIRS}) endif() ################################################################################ ### Compile the mosek part ### if(LIBIGL_WITH_MOSEK) - find_package(MOSEK) - if(MOSEK_FOUND) - compile_igl_module("mosek") - target_link_libraries(igl_mosek ${IGL_SCOPE} ${MOSEK_LIBRARIES}) - target_include_directories(igl_mosek ${IGL_SCOPE} ${MOSEK_INCLUDE_DIRS}) - target_compile_definitions(igl_mosek ${IGL_SCOPE} -DLIBIGL_WITH_MOSEK) - else() - set(LIBIGL_WITH_MOSEK OFF CACHE BOOL "" FORCE) - endif() + find_package(MOSEK REQUIRED) + compile_igl_module("mosek") + target_link_libraries(igl_mosek ${IGL_SCOPE} ${MOSEK_LIBRARIES}) + target_include_directories(igl_mosek ${IGL_SCOPE} ${MOSEK_INCLUDE_DIRS}) + target_compile_definitions(igl_mosek ${IGL_SCOPE} -DLIBIGL_WITH_MOSEK) endif() ################################################################################ @@ -297,9 +303,6 @@ if(LIBIGL_WITH_OPENGL_GLFW) add_subdirectory(${LIBIGL_EXTERNAL}/glfw glfw) endif() target_link_libraries(igl_opengl_glfw ${IGL_SCOPE} igl_opengl glfw) - else() - message(WARNING "GLFW module could not be compiled") - set(LIBIGL_WITH_OPENGL_GLFW OFF CACHE BOOL "" FORCE) endif() endif() @@ -314,9 +317,6 @@ if(LIBIGL_WITH_OPENGL_GLFW_IMGUI) add_subdirectory(${LIBIGL_EXTERNAL}/imgui imgui) endif() target_link_libraries(igl_opengl_glfw_imgui ${IGL_SCOPE} igl_opengl_glfw imgui) - else() - message(WARNING "ImGui module could not be compiled") - set(LIBIGL_WITH_OPENGL_GLFW_IMGUI OFF CACHE BOOL "" FORCE) endif() endif() @@ -332,8 +332,6 @@ if(LIBIGL_WITH_PNG) endif() compile_igl_module("png" "") target_link_libraries(igl_png ${IGL_SCOPE} igl_stb_image igl_opengl) - else() - set(LIBIGL_WITH_PNG OFF CACHE BOOL "" FORCE) endif() endif() diff --git a/tutorial/107_MultipleMeshes/CMakeLists.txt b/tutorial/107_MultipleMeshes/CMakeLists.txt index 6db43c41a..f1e58934f 100644 --- a/tutorial/107_MultipleMeshes/CMakeLists.txt +++ b/tutorial/107_MultipleMeshes/CMakeLists.txt @@ -2,4 +2,4 @@ cmake_minimum_required(VERSION 2.8.12) project(107_MultipleMeshes) add_executable(${PROJECT_NAME}_bin main.cpp) -target_link_libraries(${PROJECT_NAME}_bin igl::core igl::opengl igl::opengl_glfw igl::opengl_glfw_imgui tutorials) +target_link_libraries(${PROJECT_NAME}_bin igl::core igl::opengl igl::opengl_glfw tutorials) diff --git a/tutorial/107_MultipleMeshes/main.cpp b/tutorial/107_MultipleMeshes/main.cpp index 864af23a8..dd4615796 100755 --- a/tutorial/107_MultipleMeshes/main.cpp +++ b/tutorial/107_MultipleMeshes/main.cpp @@ -1,68 +1,35 @@ #include "tutorial_shared_path.h" #include -#include -#include +#include #include -#include #include -// Add custom data to a viewer mesh -struct MeshData -{ - std::string name; - Eigen::RowVector3d color; -}; -int last_colored_index = -1; - -// Set colors of each mesh -void update_colors(igl::opengl::glfw::Viewer &viewer) -{ - for (auto &data : viewer.data_list) - { - data.set_colors(data.attr().color); - } - viewer.data_list[viewer.selected_data_index].set_colors(Eigen::RowVector3d(0.9,0.1,0.1)); - last_colored_index = viewer.selected_data_index; -} - int main(int argc, char * argv[]) { igl::opengl::glfw::Viewer viewer; - auto names = {"cube.obj","sphere.obj","xcylinder.obj","ycylinder.obj","zcylinder.obj"}; + const auto names = + {"cube.obj","sphere.obj","xcylinder.obj","ycylinder.obj","zcylinder.obj"}; for(const auto & name : names) { viewer.load_mesh_from_file(std::string(TUTORIAL_SHARED_PATH) + "/" + name); - viewer.data().attr().name = name; - viewer.data().attr().color = Eigen::RowVector3d::Random(); } - // Attach a custom menu - igl::opengl::glfw::imgui::ImGuiMenu menu; - viewer.plugins.push_back(&menu); + // Set colors of each mesh by selecting its index first + viewer.selected_data_index = 0; + viewer.data().set_colors(Eigen::RowVector3d(0.8,0.47,0.22)); + viewer.selected_data_index = 1; + viewer.data().set_colors(Eigen::RowVector3d(0.6,0.01,0.11)); + viewer.selected_data_index = 2; + viewer.data().set_colors(Eigen::RowVector3d(0.37,0.06,0.25)); + viewer.selected_data_index = 3; + viewer.data().set_colors(Eigen::RowVector3d(1,1,1)); - // Customize default menu - menu.draw_viewer_menu_func = [&]() - { - if (ImGui::Combo("Selected Mesh", (int *) &viewer.selected_data_index, - [&](int i) { return viewer.data_list[i].attr().name.c_str(); }, - viewer.data_list.size()) - || last_colored_index != viewer.selected_data_index) - { - update_colors(viewer); - } - }; - - // Color each mesh differently - update_colors(viewer); - - viewer.callback_key_down = + viewer.callback_key_down = [&](igl::opengl::glfw::Viewer &, unsigned int key, int mod) { - // Delete - if(key == '3') + if(key == GLFW_KEY_BACKSPACE) { viewer.erase_mesh(viewer.selected_data_index); - update_colors(viewer); return true; } return false; diff --git a/tutorial/206_GeodesicDistance/main.cpp b/tutorial/206_GeodesicDistance/main.cpp index e1f337a86..1f384e952 100755 --- a/tutorial/206_GeodesicDistance/main.cpp +++ b/tutorial/206_GeodesicDistance/main.cpp @@ -3,71 +3,72 @@ #include #include #include - #include #include "tutorial_shared_path.h" -Eigen::MatrixXd V; -Eigen::MatrixXi F; - -void plotMeshDistance(igl::opengl::glfw::Viewer& viewer, const Eigen::MatrixXd& V, const Eigen::MatrixXi& F, const Eigen::VectorXd& d, const double strip_size ) -{ - // Rescale the function depending on the strip size - Eigen::VectorXd f = (d/strip_size); - - // The function should be 1 on each integer coordinate - f = (f*M_PI).array().sin().abs(); - - // Compute per-vertex colors - Eigen::MatrixXd C; - igl::colormap(igl::COLOR_MAP_TYPE_INFERNO,f,false,C); - - // Plot the mesh - viewer.data().set_mesh(V, F); - viewer.data().set_colors(C); -} int main(int argc, char *argv[]) { using namespace Eigen; using namespace std; - + Eigen::MatrixXd V; + Eigen::MatrixXi F; + igl::opengl::glfw::Viewer viewer; // Load a mesh in OFF format igl::readOBJ(TUTORIAL_SHARED_PATH "/armadillo.obj", V, F); + const auto update_distance = [&](const int vid) + { + Eigen::VectorXi VS,FS,VT,FT; + // The selected vertex is the source + VS.resize(1); + VS << vid; + // All vertices are the targets + VT.setLinSpaced(V.rows(),0,V.rows()-1); + Eigen::VectorXd d; + std::cout<<"Computing geodesic distance to vertex "<bool { - int fid; - Eigen::Vector3f bc; - // Cast a ray in the view direction starting from the mouse position - double x = viewer.current_mouse_x; - double y = viewer.core.viewport(3) - viewer.current_mouse_y; - if(igl::unproject_onto_mesh(Eigen::Vector2f(x,y), viewer.core.view, - viewer.core.proj, viewer.core.viewport, V, F, fid, bc)) - { - int max; - bc.maxCoeff(&max); - int vid = F(fid,max); - Eigen::VectorXi VS,FS,VT,FT; - // The selected vertex is the source - VS.resize(1); - VS << vid; - // All vertices are the targets - VT.setLinSpaced(V.rows(),0,V.rows()-1); - Eigen::VectorXd d; - igl::exact_geodesic(V,F,VS,FS,VT,FT,d); - - plotMeshDistance(viewer,V,F,d,0.05); - } - return false; + int fid; + Eigen::Vector3f bc; + // Cast a ray in the view direction starting from the mouse position + double x = viewer.current_mouse_x; + double y = viewer.core.viewport(3) - viewer.current_mouse_y; + if(igl::unproject_onto_mesh( + Eigen::Vector2f(x,y), + viewer.core.view, + viewer.core.proj, + viewer.core.viewport, + V, + F, + fid, + bc)) + { + int max; + bc.maxCoeff(&max); + int vid = F(fid,max); + update_distance(vid); + return true; + } + return false; }; viewer.data().set_mesh(V,F); - cout << "Press [space] to smooth." << endl;; - cout << "Press [r] to reset." << endl;; + cout << "Click on mesh to define new source.\n" << std::endl; + update_distance(0); return viewer.launch(); } diff --git a/tutorial/306_EigenDecomposition/main.cpp b/tutorial/306_EigenDecomposition/main.cpp index 842d001d4..a2ad06f96 100644 --- a/tutorial/306_EigenDecomposition/main.cpp +++ b/tutorial/306_EigenDecomposition/main.cpp @@ -36,6 +36,7 @@ int main(int argc, char * argv[]) { cout<<"failed."<