// This file is part of libigl, a simple c++ geometry processing library. // // Copyright (C) 2013 Alec Jacobson // // 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/. #include "draw_mesh.h" IGL_INLINE void igl::opengl2::draw_mesh( const Eigen::MatrixXd & V, const Eigen::MatrixXi & F, const Eigen::MatrixXd & N) { using namespace Eigen; MatrixXd _d; MatrixXi _i; return draw_mesh(V,F,N,_i,_d,_d,_i,_d,0,_i,0); } IGL_INLINE void igl::opengl2::draw_mesh( const Eigen::MatrixXd & V, const Eigen::MatrixXi & F, const Eigen::MatrixXd & N, const Eigen::MatrixXd & C) { using namespace Eigen; MatrixXd _d; MatrixXi _i; return draw_mesh(V,F,N,_i,C,_d,_i,_d,0,_i,0); } IGL_INLINE void igl::opengl2::draw_mesh( const Eigen::MatrixXd & V, const Eigen::MatrixXi & F, const Eigen::MatrixXd & N, const Eigen::MatrixXd & C, const Eigen::MatrixXd & TC) { using namespace Eigen; MatrixXd _d; MatrixXi _i; return draw_mesh(V,F,N,_i,C,TC,_i,_d,0,_i,0); } IGL_INLINE void igl::opengl2::draw_mesh( const Eigen::MatrixXd & V, const Eigen::MatrixXi & F, const Eigen::MatrixXd & N, const Eigen::MatrixXd & C, const Eigen::MatrixXd & TC, const Eigen::MatrixXd & W, const GLuint W_index, const Eigen::MatrixXi & WI, const GLuint WI_index) { using namespace Eigen; return draw_mesh(V,F,N,MatrixXi(),C,TC,MatrixXi(),W,W_index,WI,WI_index); } IGL_INLINE void igl::opengl2::draw_mesh( const Eigen::MatrixXd & V, const Eigen::MatrixXi & F, const Eigen::MatrixXd & N, const Eigen::MatrixXi & NF, const Eigen::MatrixXd & C, const Eigen::MatrixXd & TC, const Eigen::MatrixXi & TF, const Eigen::MatrixXd & W, const GLuint W_index, const Eigen::MatrixXi & WI, const GLuint WI_index) { using namespace std; using namespace Eigen; const int rF = F.rows(); const int cF = F.cols(); const int cC = C.cols(); const int rC = C.rows(); const int cW = W.cols(); const int rW = W.rows(); const int rV = V.rows(); const int rTC = TC.rows(); const int rTF = TF.rows(); const int rNF = NF.rows(); const int rN = N.rows(); if(F.size() > 0) { assert(F.maxCoeff() < V.rows()); assert(V.cols() == 3); assert(rC == rV || rC == rF || rC == rF*3 || rC==1 || C.size() == 0); assert(C.cols() >= 3 || C.size() == 0); assert(N.cols() == 3 || N.size() == 0); assert(TC.cols() == 2 || TC.size() == 0); assert(cF == 3 || cF == 4); assert(TF.size() == 0 || TF.cols() == F.cols()); assert(NF.size() == 0 || NF.cols() == NF.cols()); } if(W.size()>0) { assert(W.rows() == V.rows()); assert(WI.rows() == V.rows()); assert(W.cols() == WI.cols()); } switch(F.cols()) { default: case 3: glBegin(GL_TRIANGLES); break; case 4: glBegin(GL_QUADS); break; } // loop over faces for(int i = 0; i color; if(rC == 1) { color = C.row(0); }else if(rC == rV) { color = C.row(F(i,j)); }else if(rC == rF*cF) { color = C.row(i*cF+j); }else if(rC == rF) { color = C.row(i); }else { assert(C.size() == 0); } int n = -1; if(rNF != 0) { n = NF(i,j); // indexed normals } else if(rN == 1) { n = 0; // uniform normals }else if(rN == rF) { n = i; // face normals }else if(rN == rV) { n = F(i,j); // vertex normals }else if(rN == rF*cF) { n = i*cF + j; // corner normals }else { assert(N.size() == 0); } { if(rW>0 && W_index !=0 && WI_index != 0) { int weights_left = cW; while(weights_left != 0) { int pass_size = std::min(4,weights_left); int weights_already_passed = cW-weights_left; // Get attribute location of next 4 weights int pass_W_index = W_index + weights_already_passed/4; int pass_WI_index = WI_index + weights_already_passed/4; switch(pass_size) { case 1: glVertexAttrib1d( pass_W_index, W(F(i,j),0+weights_already_passed)); glVertexAttrib1d( pass_WI_index, WI(F(i,j),0+weights_already_passed)); break; case 2: glVertexAttrib2d( pass_W_index, W(F(i,j),0+weights_already_passed), W(F(i,j),1+weights_already_passed)); glVertexAttrib2d( pass_WI_index, WI(F(i,j),0+weights_already_passed), WI(F(i,j),1+weights_already_passed)); break; case 3: glVertexAttrib3d( pass_W_index, W(F(i,j),0+weights_already_passed), W(F(i,j),1+weights_already_passed), W(F(i,j),2+weights_already_passed)); glVertexAttrib3d( pass_WI_index, WI(F(i,j),0+weights_already_passed), WI(F(i,j),1+weights_already_passed), WI(F(i,j),2+weights_already_passed)); break; default: glVertexAttrib4d( pass_W_index, W(F(i,j),0+weights_already_passed), W(F(i,j),1+weights_already_passed), W(F(i,j),2+weights_already_passed), W(F(i,j),3+weights_already_passed)); glVertexAttrib4d( pass_WI_index, WI(F(i,j),0+weights_already_passed), WI(F(i,j),1+weights_already_passed), WI(F(i,j),2+weights_already_passed), WI(F(i,j),3+weights_already_passed)); break; } weights_left -= pass_size; } } if(tc != -1) { glTexCoord2d(TC(tc,0),TC(tc,1)); } if(rC>0) { switch(cC) { case 3: glColor3dv(color.data()); break; case 4: glColor4dv(color.data()); break; default: break; } } if(n != -1) { glNormal3d(N(n,0),N(n,1),N(n,2)); } glVertex3d(V(F(i,j),0),V(F(i,j),1),V(F(i,j),2)); } } } glEnd(); } #ifdef IGL_STATIC_LIBRARY // Explicit template instantiation #endif