draw_mesh.cpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2013 Alec Jacobson <alecjacobson@gmail.com>
  4. //
  5. // This Source Code Form is subject to the terms of the Mozilla Public License
  6. // v. 2.0. If a copy of the MPL was not distributed with this file, You can
  7. // obtain one at http://mozilla.org/MPL/2.0/.
  8. #include "draw_mesh.h"
  9. #ifndef IGL_NO_OPENGL
  10. IGL_INLINE void igl::draw_mesh(
  11. const Eigen::MatrixXd & V,
  12. const Eigen::MatrixXi & F,
  13. const Eigen::MatrixXd & N)
  14. {
  15. using namespace Eigen;
  16. MatrixXd _d;
  17. MatrixXi _i;
  18. return draw_mesh(V,F,N,_i,_d,_d,_i,_d,0,_i,0);
  19. }
  20. IGL_INLINE void igl::draw_mesh(
  21. const Eigen::MatrixXd & V,
  22. const Eigen::MatrixXi & F,
  23. const Eigen::MatrixXd & N,
  24. const Eigen::MatrixXd & C)
  25. {
  26. using namespace Eigen;
  27. MatrixXd _d;
  28. MatrixXi _i;
  29. return draw_mesh(V,F,N,_i,C,_d,_i,_d,0,_i,0);
  30. }
  31. IGL_INLINE void igl::draw_mesh(
  32. const Eigen::MatrixXd & V,
  33. const Eigen::MatrixXi & F,
  34. const Eigen::MatrixXd & N,
  35. const Eigen::MatrixXd & C,
  36. const Eigen::MatrixXd & TC)
  37. {
  38. using namespace Eigen;
  39. MatrixXd _d;
  40. MatrixXi _i;
  41. return draw_mesh(V,F,N,_i,C,TC,_i,_d,0,_i,0);
  42. }
  43. IGL_INLINE void igl::draw_mesh(
  44. const Eigen::MatrixXd & V,
  45. const Eigen::MatrixXi & F,
  46. const Eigen::MatrixXd & N,
  47. const Eigen::MatrixXd & C,
  48. const Eigen::MatrixXd & TC,
  49. const Eigen::MatrixXd & W,
  50. const GLuint W_index,
  51. const Eigen::MatrixXi & WI,
  52. const GLuint WI_index)
  53. {
  54. using namespace Eigen;
  55. return draw_mesh(V,F,N,MatrixXi(),C,TC,MatrixXi(),W,W_index,WI,WI_index);
  56. }
  57. IGL_INLINE void igl::draw_mesh(
  58. const Eigen::MatrixXd & V,
  59. const Eigen::MatrixXi & F,
  60. const Eigen::MatrixXd & N,
  61. const Eigen::MatrixXi & NF,
  62. const Eigen::MatrixXd & C,
  63. const Eigen::MatrixXd & TC,
  64. const Eigen::MatrixXi & TF,
  65. const Eigen::MatrixXd & W,
  66. const GLuint W_index,
  67. const Eigen::MatrixXi & WI,
  68. const GLuint WI_index)
  69. {
  70. using namespace std;
  71. using namespace Eigen;
  72. const int rF = F.rows();
  73. const int cC = C.cols();
  74. const int rC = C.rows();
  75. const int cW = W.cols();
  76. const int rW = W.rows();
  77. const int rV = V.rows();
  78. const int rTC = TC.rows();
  79. const int rTF = TF.rows();
  80. const int rNF = NF.rows();
  81. const int rN = N.rows();
  82. if(F.size() > 0)
  83. {
  84. assert(F.maxCoeff() < V.rows());
  85. assert(V.cols() == 3);
  86. assert(rC == rV || rC == rF || rC == rF*3 || C.size() == 0);
  87. assert(C.cols() == 3 || C.size() == 0);
  88. assert(N.cols() == 3 || N.size() == 0);
  89. assert(TC.cols() == 2 || TC.size() == 0);
  90. }
  91. if(W.size()>0)
  92. {
  93. assert(W.rows() == V.rows());
  94. assert(WI.rows() == V.rows());
  95. assert(W.cols() == WI.cols());
  96. }
  97. glBegin(GL_TRIANGLES);
  98. // loop over faces
  99. for(int i = 0; i<rF;i++)
  100. {
  101. // loop over corners of triangle
  102. for(int j = 0;j<3;j++)
  103. {
  104. int tc = -1;
  105. if(rTF != 0)
  106. {
  107. tc = TF(i,j);
  108. } else if(rTC == 1)
  109. {
  110. tc = 0;
  111. }else if(rTC == rV)
  112. {
  113. tc = F(i,j);
  114. }else if(rTC == rF*2)
  115. {
  116. tc = i*2 + j;
  117. }else if(rTC == rF)
  118. {
  119. tc = i;
  120. }else
  121. {
  122. assert(TC.size() == 0);
  123. }
  124. // RGB(A)
  125. Matrix<MatrixXd::Scalar,1,Dynamic> color;
  126. if(rC == 1)
  127. {
  128. color = C.row(0);
  129. }else if(rC == rV)
  130. {
  131. color = C.row(F(i,j));
  132. }else if(rC == rF*3)
  133. {
  134. color = C.row(i*3+j);
  135. }else if(rC == rF)
  136. {
  137. color = C.row(i);
  138. }else
  139. {
  140. assert(C.size() == 0);
  141. }
  142. int n = -1;
  143. if(rNF != 0)
  144. {
  145. n = NF(i,j);
  146. } else if(rN == 1)
  147. {
  148. n = 0;
  149. }else if(rN == rV)
  150. {
  151. n = F(i,j);
  152. }else if(rN == rF*2)
  153. {
  154. n = i*2 + j;
  155. }else if(rN == rF)
  156. {
  157. n = i;
  158. }else
  159. {
  160. assert(N.size() == 0);
  161. }
  162. {
  163. if(rW>0 && W_index !=0 && WI_index != 0)
  164. {
  165. int weights_left = cW;
  166. while(weights_left != 0)
  167. {
  168. int pass_size = std::min(4,weights_left);
  169. int weights_already_passed = cW-weights_left;
  170. // Get attribute location of next 4 weights
  171. int pass_W_index = W_index + weights_already_passed/4;
  172. int pass_WI_index = WI_index + weights_already_passed/4;
  173. switch(pass_size)
  174. {
  175. case 1:
  176. glVertexAttrib1d(
  177. pass_W_index,
  178. W(F(i,j),0+weights_already_passed));
  179. glVertexAttrib1d(
  180. pass_WI_index,
  181. WI(F(i,j),0+weights_already_passed));
  182. break;
  183. case 2:
  184. glVertexAttrib2d(
  185. pass_W_index,
  186. W(F(i,j),0+weights_already_passed),
  187. W(F(i,j),1+weights_already_passed));
  188. glVertexAttrib2d(
  189. pass_WI_index,
  190. WI(F(i,j),0+weights_already_passed),
  191. WI(F(i,j),1+weights_already_passed));
  192. break;
  193. case 3:
  194. glVertexAttrib3d(
  195. pass_W_index,
  196. W(F(i,j),0+weights_already_passed),
  197. W(F(i,j),1+weights_already_passed),
  198. W(F(i,j),2+weights_already_passed));
  199. glVertexAttrib3d(
  200. pass_WI_index,
  201. WI(F(i,j),0+weights_already_passed),
  202. WI(F(i,j),1+weights_already_passed),
  203. WI(F(i,j),2+weights_already_passed));
  204. break;
  205. default:
  206. glVertexAttrib4d(
  207. pass_W_index,
  208. W(F(i,j),0+weights_already_passed),
  209. W(F(i,j),1+weights_already_passed),
  210. W(F(i,j),2+weights_already_passed),
  211. W(F(i,j),3+weights_already_passed));
  212. glVertexAttrib4d(
  213. pass_WI_index,
  214. WI(F(i,j),0+weights_already_passed),
  215. WI(F(i,j),1+weights_already_passed),
  216. WI(F(i,j),2+weights_already_passed),
  217. WI(F(i,j),3+weights_already_passed));
  218. break;
  219. }
  220. weights_left -= pass_size;
  221. }
  222. }
  223. if(tc != -1)
  224. {
  225. glTexCoord2d(TC(tc,0),TC(tc,1));
  226. }
  227. if(rC>0)
  228. {
  229. switch(cC)
  230. {
  231. case 3:
  232. glColor3dv(color.data());
  233. break;
  234. case 4:
  235. glColor4dv(color.data());
  236. break;
  237. default:
  238. break;
  239. }
  240. }
  241. if(n != -1)
  242. {
  243. glNormal3d(N(n,0),N(n,1),N(n,2));
  244. }
  245. glVertex3d(V(F(i,j),0),V(F(i,j),1),V(F(i,j),2));
  246. }
  247. }
  248. }
  249. glEnd();
  250. }
  251. #endif