50 #define ACG_DRAW_MESH_TCC
54 #include "DrawMesh.hh"
56 #include <ACG/GL/gl.hh>
57 #include <ACG/Geometry/GPUCacheOptimizer.hh>
58 #include <ACG/GL/VertexDeclaration.hh>
59 #include <ACG/GL/ShaderCache.hh>
81 DrawMeshT<Mesh>::DrawMeshT(
Mesh& _mesh)
83 rebuild_(REBUILD_NONE),
84 prevNumFaces_(0), prevNumVerts_(0),
87 flatMode_(0), bVBOinFlatMode_(0),
88 textureMode_(1), bVBOinHalfedgeTexMode_(1),
89 halfedgeNormalMode_(0), bVBOinHalfedgeNormalMode_(0),
91 offsetPos_(0), offsetNormal_(20), offsetTexc_(12), offsetColor_(32),
92 textureIndexPropertyName_(
"Not Set"),
93 perFaceTextureCoordinatePropertyName_(
"Not Set"),
95 updatePerEdgeBuffers_(1),
96 updatePerHalfedgeBuffers_(1)
99 pickVertexMethod_ = 1;
100 pickVertexShader_ = 0;
114 const void* dataPtr = 0;
123 const Prop1* p1 =
dynamic_cast<const Prop1*
>(_prop);
124 const PropVec1* pv1 =
dynamic_cast<const PropVec1*
>(_prop);
125 const PropVec2* pv2 =
dynamic_cast<const PropVec2*
>(_prop);
126 const PropVec3* pv3 =
dynamic_cast<const PropVec3*
>(_prop);
127 const PropVec4* pv4 =
dynamic_cast<const PropVec4*
>(_prop);
134 dataPtr = p1->
data();
136 dataPtr = pv1->data();
142 dataPtr = pv2->data();
148 dataPtr = pv3->data();
154 dataPtr = pv4->data();
164 const void* dataPtr = 0;
167 dataPtr = testMeshPropertyTypeT<float>(_prop, _outSize);
170 if (_outType) *_outType = GL_FLOAT;
175 dataPtr = testMeshPropertyTypeT<char>(_prop, _outSize);
178 if (_outType) *_outType = GL_BYTE;
183 dataPtr = testMeshPropertyTypeT<unsigned char>(_prop, _outSize);
186 if (_outType) *_outType = GL_UNSIGNED_BYTE;
191 dataPtr = testMeshPropertyTypeT<double>(_prop, _outSize);
195 if (_outType) *_outType = GL_DOUBLE;
200 dataPtr = testMeshPropertyTypeT<int>(_prop, _outSize);
204 if (_outType) *_outType = GL_INT;
209 dataPtr = testMeshPropertyTypeT<unsigned int>(_prop, _outSize);
213 if (_outType) *_outType = GL_UNSIGNED_INT;
218 dataPtr = testMeshPropertyTypeT<short>(_prop, _outSize);
222 if (_outType) *_outType = GL_SHORT;
227 dataPtr = testMeshPropertyTypeT<unsigned short>(_prop, _outSize);
231 if (_outType) *_outType = GL_UNSIGNED_SHORT;
260 std::vector<int> attributeStoredPerHalfedge_;
263 int getNumFaces()
const {
return mesh_.n_faces(); }
273 return mesh_.valence( mesh_.face_handle(_faceID) );
285 const typename Mesh::FaceHandle fh = mesh_.face_handle(_faceID);
293 if ( attributeStoredPerHalfedge_[_attrID] != 0 ) {
294 switch (_faceCorner) {
295 case 0 :
return fh_it->idx();
297 case 1 :
return (mesh_.next_halfedge_handle(*fh_it)).idx();
299 case 2 :
return (mesh_.prev_halfedge_handle(*fh_it)).idx();
301 default : std::cerr <<
" Index error!" << _faceCorner << std::endl;
return -1;
305 switch (_faceCorner) {
306 case 0 :
return mesh_.to_vertex_handle(*fh_it).idx();
308 case 1 :
return (mesh_.to_vertex_handle(mesh_.next_halfedge_handle(*fh_it))).idx();
310 case 2 :
return (mesh_.to_vertex_handle(mesh_.prev_halfedge_handle(*fh_it))).idx();
312 default : std::cerr <<
" Index error!" << _faceCorner << std::endl;
return -1;
321 if ( attributeStoredPerHalfedge_[_attrID] != 0 ) {
323 for (
int i = 0; fh_it.is_valid() && i <= _faceCorner; ++fh_it, ++i )
324 if (i == _faceCorner)
329 for (
int i = 0; fh_it.is_valid() && i <= _faceCorner; ++fh_it, ++i )
330 if (i == _faceCorner)
331 return mesh_.to_vertex_handle(*fh_it).idx();
345 bool getFaceAttr(
const int _faceID,
const int _attrID,
int* _out)
const
347 const typename Mesh::FaceHandle fh = mesh_.face_handle(_faceID);
349 const bool usePerHalfedge = (attributeStoredPerHalfedge_[_attrID] != 0);
353 for (
int i = 0; hh_it.is_valid(); ++hh_it, ++i )
355 _out[i] = usePerHalfedge ? hh_it->idx() : mesh_.to_vertex_handle(*hh_it).idx();
382 for (;adj_it.is_valid(); ++adj_it)
394 for (
int i = 0; adj_it.is_valid() && i < _k; ++adj_it, ++i);
396 return adj_it->idx();
405 template <
class Mesh>
409 if (rebuild_ == REBUILD_NONE)
return;
411 if (!mesh_.n_vertices())
441 createVertexDeclaration();
444 if (mesh_.n_vertices() && mesh_.n_faces() == 0)
446 if (mesh_.n_vertices() > numVerts_)
448 delete [] invVertexMap_;
451 numVerts_ = mesh_.n_vertices();
452 vertices_.resize(numVerts_ * vertexDecl_->getVertexStride());
455 for (
size_t i = 0; i < numVerts_; ++i)
457 mesh_.vertex_handle(i),
458 (
typename Mesh::HalfedgeHandle)(-1),
459 (
typename Mesh::FaceHandle)(-1));
462 rebuild_ = REBUILD_NONE;
469 unsigned int maxFaceVertCount = 0;
470 unsigned int numIndices = 0;
471 unsigned int newTriCount = countTris(&maxFaceVertCount, &numIndices);
473 int bTriangleRebuild = 0;
474 int bVertexRebuild = 0;
476 if (newTriCount > numTris_)
481 numTris_ = newTriCount;
483 bTriangleRebuild = 1;
486 if (prevNumFaces_ != mesh_.n_faces())
488 bTriangleRebuild = 1;
489 prevNumFaces_ = mesh_.n_faces();
492 if (prevNumVerts_ != mesh_.n_vertices())
494 if (prevNumVerts_ < mesh_.n_vertices())
497 delete [] invVertexMap_;
498 invVertexMap_ =
new unsigned int[mesh_.n_vertices()];
502 bTriangleRebuild = 1;
503 prevNumVerts_ = mesh_.n_vertices();
507 if (!bTriangleRebuild && !bVertexRebuild && (rebuild_ & REBUILD_GEOMETRY) && !(rebuild_ & REBUILD_TEXTURES))
513 #pragma omp parallel for
516 for (
unsigned int i = 0; i < numVerts_; ++i)
519 const typename Mesh::HalfedgeHandle hh = mapToHalfedgeHandle(i);
521 typename Mesh::FaceHandle fh(-1);
525 vh = mesh_.to_vertex_handle(hh);
526 fh = mesh_.face_handle(hh);
531 int posID = meshComp_->mapToOriginalVertexID(i, f_id, c_id);
532 vh = mesh_.vertex_handle(posID);
535 readVertex(i, vh, hh, fh);
540 rebuild_ = REBUILD_NONE;
551 int attrIDNorm = -1, attrIDPos = -1, attrIDTexC = -1;
553 for (
int i = 0; i < (int)meshComp_->getVertexDeclaration()->getNumElements(); ++i)
555 const VertexElement* e = meshComp_->getVertexDeclaration()->getElement(i);
569 faceInput->attributeStoredPerHalfedge_.resize(meshComp_->getVertexDeclaration()->getNumElements(), 0);
570 faceInput->attributeStoredPerHalfedge_[attrIDPos] = 0;
571 faceInput->attributeStoredPerHalfedge_[attrIDNorm] = ( (halfedgeNormalMode_ && mesh_.has_halfedge_normals()) ? 1 : 0 );
572 faceInput->attributeStoredPerHalfedge_[attrIDTexC] = ( mesh_.has_halfedge_texcoords2D() ? 1 : 0);
575 for (
size_t i = 0; i < additionalElements_.size(); ++i)
580 faceInput->attributeStoredPerHalfedge_[prop->
declElementID_] = (prop->source_ == PROPERTY_SOURCE_HALFEDGE) ? 1 : 0;
583 meshComp_->setFaceInput(faceInput);
586 for (
unsigned int i = 0; i < mesh_.n_faces(); ++i)
587 meshComp_->setFaceGroup(i, getTextureIDofFace(i));
593 meshComp_->setVertices(mesh_.n_vertices(), mesh_.points(), 24,
false, GL_DOUBLE, 3);
596 if (halfedgeNormalMode_ && mesh_.has_halfedge_normals())
597 meshComp_->setNormals(mesh_.n_halfedges(), mesh_.property(mesh_.halfedge_normals_pph()).data(), 24,
false, GL_DOUBLE, 3);
598 else if (mesh_.has_vertex_normals())
599 meshComp_->setNormals(mesh_.n_vertices(), mesh_.vertex_normals(), 24,
false, GL_DOUBLE, 3);
601 if (mesh_.has_halfedge_texcoords2D())
602 meshComp_->setTexCoords(mesh_.n_halfedges(), mesh_.htexcoords2D(), 8,
false, GL_FLOAT, 2);
606 for (
size_t i = 0; i < additionalElements_.size(); ++i)
619 switch (propDesc->source_)
621 case PROPERTY_SOURCE_VERTEX: baseProp = mesh_._get_vprop(propDesc->
name_);
break;
622 case PROPERTY_SOURCE_FACE: baseProp = mesh_._get_fprop(propDesc->
name_);
break;
623 case PROPERTY_SOURCE_HALFEDGE: baseProp = mesh_._get_hprop(propDesc->
name_);
break;
624 default: baseProp = mesh_._get_vprop(propDesc->
name_);
break;
632 meshComp_->setAttribVec( propDesc->
declElementID_, numAttribs, attribData );
644 meshComp_->build(
true,
true,
true,
true);
648 for (
int i = 0; i < (int)mesh_.n_faces(); ++i)
650 typename Mesh::FaceHandle fh = mesh_.face_handle(i);
656 int vertexId = mesh_.to_vertex_handle(*hh_it).idx();
657 invVertexMap_[vertexId] = meshComp_->mapToDrawVertexID(i, corner++);
663 numTris_ = meshComp_->getNumTriangles();
664 numVerts_ = meshComp_->getNumVertices();
666 vertices_.resize(numVerts_ * vertexDecl_->getVertexStride());
667 meshComp_->getVertexBuffer(&vertices_[0]);
670 for (
int i = 0; i < (int)numVerts_; ++i)
672 typename Mesh::HalfedgeHandle hh = mapToHalfedgeHandle(i);
674 unsigned int col = 0;
677 col = getVertexColor(mesh_.to_vertex_handle(hh));
682 int posID = meshComp_->mapToOriginalVertexID(i, f_id, c_id);
683 col = getVertexColor( mesh_.vertex_handle(posID) );
690 curVBOColorMode_ = 1;
695 const int provokingId = meshComp_->getProvokingVertex();
696 assert(provokingId >= 0 && provokingId < 3);
698 for (
int i = 0; i < (int)numTris_; ++i)
700 int idx = meshComp_->getIndex(i*3+provokingId);
702 int faceId = meshComp_->mapToOriginalFaceID(i);
703 unsigned int fcolor = getFaceColor(mesh_.face_handle(faceId));
705 writeColor(idx, fcolor);
711 for (
int i = 0; i < (int)numTris_; ++i)
713 int idx = meshComp_->getIndex(i*3+provokingId);
715 int faceId = meshComp_->mapToOriginalFaceID(i);
716 unsigned int fcolor = getFaceColor(mesh_.face_handle(faceId));
718 unsigned int storedColor = *(
unsigned int*)(&vertices_[idx * vertexDecl_->getVertexStride() + offsetColor_]);
720 if (storedColor != fcolor)
722 std::cout <<
"warning: possibly found provoking vertex shared by more than one face, writing report to ../../meshcomp_provoking.txt" << std::endl;
728 meshComp_->dbgVerify(
"../../meshcomp_provoking.txt");
735 curVBOColorMode_ = colorMode_;
747 bVBOinHalfedgeNormalMode_ = halfedgeNormalMode_;
749 rebuild_ = REBUILD_NONE;
753 template <
class Mesh>
757 const typename Mesh::HalfedgeHandle _hh,
758 const typename Mesh::FaceHandle _fh)
760 static const typename Mesh::HalfedgeHandle invalidHEH(-1);
761 static const typename Mesh::FaceHandle invalidFH(-1);
769 if (halfedgeNormalMode_ == 0 && mesh_.has_vertex_normals())
770 n = mesh_.normal(_vh);
771 else if (halfedgeNormalMode_ && mesh_.has_halfedge_normals() && _hh != invalidHEH)
772 n = mesh_.normal(_hh);
775 if (mesh_.has_halfedge_texcoords2D())
777 if (_hh != invalidHEH && textureMode_ == 1)
778 texc = mesh_.texcoord2D(_hh);
779 else if (mesh_.has_vertex_texcoords2D())
780 texc = mesh_.texcoord2D(_vh);
782 else if (mesh_.has_vertex_texcoords2D())
783 texc = mesh_.texcoord2D(_vh);
786 unsigned int byteCol[2];
787 for (
int col = 0; col < 2; ++col)
789 Vec4uc vecCol(255, 255, 255, 255);
791 if (col == 0 && mesh_.has_vertex_colors())
792 vecCol = OpenMesh::color_cast<Vec4uc, typename Mesh::Color>(mesh_.color(_vh));
793 if (_fh != invalidFH)
795 if (col == 1 && mesh_.has_face_colors() && _fh.idx() >= 0)
796 vecCol = OpenMesh::color_cast<Vec4uc,typename Mesh::Color>(mesh_.color(_fh));
800 byteCol[col] = (
unsigned char)(vecCol[0]);
801 byteCol[col] |= ((
unsigned char)(vecCol[1])) << 8;
802 byteCol[col] |= ((
unsigned char)(vecCol[2])) << 16;
803 byteCol[col] |= ((
unsigned char)(vecCol[3])) << 24;
814 writePosition(_vertex, mesh_.point(_vh));
815 writeNormal(_vertex, n);
816 writeTexcoord(_vertex, texc);
817 writeColor(_vertex, col);
822 for (
size_t i = 0; i < additionalElements_.size(); ++i)
824 std::cout <<
"not implemented!" << std::endl;
832 template <
class Mesh>
838 unsigned int byteCol;
840 Vec4uc vecCol(255, 255, 255, 255);
842 if ( _vh != invalidVH && mesh_.has_vertex_colors() )
843 vecCol = OpenMesh::color_cast<Vec4uc, typename Mesh::Color>(mesh_.color(_vh));
846 byteCol = (
unsigned char)(vecCol[0]);
847 byteCol |= ((
unsigned char)(vecCol[1])) << 8;
848 byteCol |= ((
unsigned char)(vecCol[2])) << 16;
849 byteCol |= ((
unsigned char)(vecCol[3])) << 24;
854 template <
class Mesh>
858 static const typename Mesh::FaceHandle invalidFH(-1);
860 unsigned int byteCol;
861 Vec4uc vecCol(255, 255, 255, 255);
863 if ( _fh != invalidFH && mesh_.has_face_colors() && _fh.idx() >= 0 )
864 vecCol = OpenMesh::color_cast<Vec4uc,typename Mesh::Color>(mesh_.color(_fh));
867 byteCol = (
unsigned char)(vecCol[0]);
868 byteCol |= ((
unsigned char)(vecCol[1])) << 8;
869 byteCol |= ((
unsigned char)(vecCol[2])) << 16;
870 byteCol |= ((
unsigned char)(vecCol[3])) << 24;
876 template <
class Mesh>
881 if (mesh_.get_property_handle(textureIndexProperty, textureIndexPropertyName_))
882 return mesh_.property(textureIndexProperty, mesh_.face_handle(_face));
884 if (mesh_.has_face_texture_index())
885 return mesh_.texture_index(mesh_.face_handle(_face));
890 template <
class Mesh>
894 return getTextureIDofFace(meshComp_->mapToOriginalFaceID(_tri));
898 template <
class Mesh>
907 if (flatMode_ && meshComp_)
909 for (
unsigned int i = 0; i < numTris_; ++i)
911 int faceId = meshComp_->mapToOriginalFaceID(i);
914 ACG::Vec3d n = mesh_.normal(mesh_.face_handle(faceId));
919 int idx = meshComp_->getIndex(i*3 + meshComp_->getProvokingVertex());
929 for (
unsigned int i = 0; i < numVerts_; ++i)
931 typename Mesh::HalfedgeHandle hh = mapToHalfedgeHandle(i);
938 if (halfedgeNormalMode_ == 1 && mesh_.has_halfedge_normals())
939 n = mesh_.normal( hh );
941 n = mesh_.normal( mesh_.to_vertex_handle(hh) );
955 posID = meshComp_->mapToOriginalVertexID(i, f_id, c_id);
960 writeNormal(i, mesh_.normal( mesh_.vertex_handle(posID) ));
967 if (textureMode_ == 0)
970 if (mesh_.has_vertex_texcoords2D())
972 for (
unsigned int i = 0; i < numVerts_; ++i)
974 typename Mesh::HalfedgeHandle hh = mapToHalfedgeHandle(i);
982 writeTexcoord(i, mesh_.texcoord2D( mesh_.to_vertex_handle(hh) ) );
991 posID = meshComp_->mapToOriginalVertexID(i, f_id, c_id);
997 writeTexcoord(i, mesh_.texcoord2D( mesh_.vertex_handle(posID) ) );
1003 bVBOinHalfedgeTexMode_ = 0;
1007 if (mesh_.has_vertex_texcoords2D() || mesh_.has_halfedge_texcoords2D())
1010 for (
unsigned int i = 0; i < numVerts_; ++i)
1012 typename Mesh::HalfedgeHandle hh = mapToHalfedgeHandle(i);
1017 if (mesh_.has_halfedge_texcoords2D())
1022 writeTexcoord(i, mesh_.texcoord2D( hh ) );
1026 else if (mesh_.has_vertex_texcoords2D())
1034 posID = meshComp_->mapToOriginalVertexID(i, f_id, c_id);
1040 writeTexcoord(i, mesh_.texcoord2D( mesh_.vertex_handle(posID) ) );
1046 bVBOinHalfedgeTexMode_ = 1;
1049 if (colorMode_ && colorMode_ != curVBOColorMode_)
1051 if (colorMode_ == 1)
1055 for (
int i = 0; i < (int)numVerts_; ++i)
1057 typename Mesh::HalfedgeHandle hh = mapToHalfedgeHandle(i);
1062 col = getVertexColor(mesh_.to_vertex_handle(hh));
1067 int posID = meshComp_->mapToOriginalVertexID(i, f_id, c_id);
1068 col = getVertexColor( mesh_.vertex_handle(posID) );
1074 else if (colorMode_ == 2)
1078 const int provokingId = meshComp_->getProvokingVertex();
1079 assert(provokingId >= 0 && provokingId < 3);
1081 for (
int i = 0; i < (int)numTris_; ++i)
1083 int idx = meshComp_->getIndex(i*3+provokingId);
1085 int faceId = meshComp_->mapToOriginalFaceID(i);
1086 unsigned int fcolor = getFaceColor(mesh_.face_handle(faceId));
1089 writeColor(idx, fcolor);
1094 curVBOColorMode_ = colorMode_;
1102 invalidateFullVBO();
1105 template <
class Mesh>
1113 indexType_ = GL_UNSIGNED_INT;
1126 createIndexBuffer();
1130 if (mesh_.n_edges())
1132 std::vector<unsigned int> lineBuffer(mesh_.n_edges() * 2);
1134 for (
unsigned int i = 0; i < mesh_.n_edges(); ++i)
1138 if (indexType_ == GL_UNSIGNED_SHORT)
1141 unsigned int combinedIdx = invVertexMap_[mesh_.from_vertex_handle(hh).idx()] | (invVertexMap_[mesh_.to_vertex_handle(hh).idx()] << 16);
1142 lineBuffer[i] = combinedIdx;
1146 lineBuffer[2 * i] = invVertexMap_[mesh_.from_vertex_handle(hh).idx()];
1147 lineBuffer[2 * i + 1] = invVertexMap_[mesh_.to_vertex_handle(hh).idx()];
1153 fillLineBuffer(mesh_.n_edges(), &lineBuffer[0]);
1159 template <
class Mesh>
1162 delete [] invVertexMap_;
1167 template <
class Mesh>
1170 unsigned int res = 0;
1171 unsigned int sysBufSize = 0;
1173 sysBufSize += meshComp_->getMemoryUsage();
1176 if (!vertices_.empty())
1177 sysBufSize += vertexDecl_->getVertexStride() * numVerts_;
1184 unsigned int mapsSize = 0;
1187 res += mesh_.n_vertices() * 4;
1193 unsigned int pickBufSize = 0;
1195 pickBufSize += pickVertBuf_.capacity() *
sizeof(
ACG::Vec3f);
1196 pickBufSize += pickVertColBuf_.capacity() *
sizeof(
ACG::Vec4uc);
1198 pickBufSize += pickEdgeBuf_.capacity() *
sizeof(
ACG::Vec4uc);
1200 pickBufSize += pickFaceVertexBuf_.capacity() *
sizeof(
ACG::Vec3f);
1201 pickBufSize += pickFaceColBuf_.capacity() *
sizeof(
ACG::Vec4uc);
1204 pickBufSize += pickAnyFaceColBuf_.capacity() *
sizeof(
ACG::Vec4uc);
1205 pickBufSize += pickAnyEdgeColBuf_.capacity() *
sizeof(
ACG::Vec4uc);
1206 pickBufSize += pickAnyVertexColBuf_.capacity() *
sizeof(
ACG::Vec4uc);
1212 unsigned int edgeBufSize = 0;
1214 edgeBufSize += perEdgeVertexBuf_.capacity() *
sizeof(
ACG::Vec3f);
1215 edgeBufSize += perEdgeColorBuf_.capacity() *
sizeof(
ACG::Vec4uc);
1217 edgeBufSize += perHalfedgeVertexBuf_.capacity() *
sizeof(
ACG::Vec3f);
1218 edgeBufSize += perHalfedgeColorBuf_.capacity() *
sizeof(
ACG::Vec4uc);
1224 unsigned int gpuBufSize = 0;
1227 gpuBufSize += numTris_ * 3 * (indexType_ == GL_UNSIGNED_INT ? 4 : 2);
1230 gpuBufSize += numVerts_ * vertexDecl_->getVertexStride();
1234 std::cout <<
"\nDrawMesh memory usage in MB:\n";
1235 std::cout <<
"Vertex+IndexBuffer (SYSMEM only): " << float(sysBufSize) / (1024 * 1024);
1236 std::cout <<
"\nMappings: " << float(mapsSize) / (1024 * 1024);
1237 std::cout <<
"\nPicking Buffers: " << float(pickBufSize) / (1024 * 1024);
1238 std::cout <<
"\nEdge Buffers: " << float(edgeBufSize) / (1024 * 1024);
1239 std::cout <<
"\nTotal SYSMEM: " << float(res) / (1024 * 1024);
1240 std::cout <<
"\nTotal GPU: " << float(gpuBufSize) / (1024 * 1024) << std::endl;
1247 template <
class Mesh>
1251 if ((!numTris_ && mesh_.n_faces())|| ! numVerts_ || (!meshComp_ && mesh_.n_faces()))
1253 rebuild_ = REBUILD_FULL;
1256 if (bVBOinHalfedgeNormalMode_ != halfedgeNormalMode_) rebuild_ = REBUILD_FULL;
1260 if (rebuild_ == REBUILD_NONE)
1262 if (bVBOinFlatMode_ != flatMode_ || bVBOinHalfedgeTexMode_ != textureMode_ || (colorMode_ && curVBOColorMode_ != colorMode_))
1272 template <
class Mesh>
1279 template <
class Mesh>
1286 template <
class Mesh>
1289 if (_v < mesh_.n_vertices())
1292 return invVertexMap_[_v];
1297 return (
unsigned int)-1;
1300 template <
class Mesh>
1318 glClientActiveTexture(GL_TEXTURE0);
1330 template <
class Mesh>
1344 template <
class Mesh>
1358 template <
class Mesh>
1367 vertexDecl_->activateFixedFunction();
1370 #ifdef DEBUG_MEM_USAGE
1371 getMemoryUsage(
true);
1380 for (
int i = 0; i < meshComp_->getNumSubsets(); ++i)
1384 if ( _textureMap->find(sub->id) == _textureMap->end() ) {
1385 std::cerr <<
"Illegal texture index ... trying to access " << sub->id << std::endl;
1392 glDrawElements(GL_TRIANGLES, sub->numTris * 3, indexType_,
1393 (GLvoid*)( (
size_t)sub->startIndex * (indexType_ == GL_UNSIGNED_INT ? 4 : 2)));
1395 glDrawArrays(GL_TRIANGLES, sub->startIndex, sub->numTris * 3);
1401 glDrawElements(GL_TRIANGLES, numTris_ * 3, indexType_, 0);
1403 glDrawArrays(GL_TRIANGLES, 0, numTris_ * 3);
1411 template <
class Mesh>
1418 bindBuffersToRenderObject(&ro);
1431 for (
int i = 0; i < meshComp_->getNumSubsets(); ++i)
1437 if ( _textureMap->find(sub->id) == _textureMap->end() ) {
1438 std::cerr <<
"Illegal texture index ... trying to access " << sub->id << std::endl;
1443 tex.type = GL_TEXTURE_2D;
1444 tex.id = (*_textureMap)[sub->id];
1450 glActiveTextureARB(GL_TEXTURE0);
1451 GLint textureID = 0;
1452 glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureID);
1455 tex.type = GL_TEXTURE_2D;
1463 ro.glDrawElements(GL_TRIANGLES, sub->numTris * 3, indexType_,
1464 (GLvoid*)((
size_t)sub->startIndex * (indexType_ == GL_UNSIGNED_INT ? 4 : 2)));
1466 ro.glDrawArrays(GL_TRIANGLES, sub->startIndex, sub->numTris * 3);
1474 ro.glDrawElements(GL_TRIANGLES, numTris_ * 3, indexType_, 0);
1476 ro.glDrawArrays(GL_TRIANGLES,0, numTris_ * 3);
1483 template <
class Mesh>
1488 if (mesh_.n_edges())
1492 glDrawElements(GL_LINES, mesh_.n_edges() * 2, indexType_, 0);
1499 template <
class Mesh>
1503 bindBuffersToRenderObject(&ro);
1505 if (mesh_.n_edges())
1508 ro.glDrawElements(GL_LINES, mesh_.n_edges() * 2, indexType_, 0);
1514 template <
class Mesh>
1521 glDrawArrays(GL_POINTS, 0, numVerts_);
1526 template <
class Mesh>
1530 bindBuffersToRenderObject(&ro);
1534 ro.glDrawArrays(GL_POINTS, 0, numVerts_);
1542 template <
class Mesh>
1545 unsigned int triCounter = 0;
1547 if (pMaxVertsOut) *pMaxVertsOut = 0;
1548 if (_pOutNumIndices) *_pOutNumIndices = 0;
1550 for (
unsigned int i = 0; i < mesh_.n_faces(); ++i)
1552 typename Mesh::FaceHandle fh = mesh_.face_handle(i);
1555 unsigned int nPolyVerts = 0;
1557 for (
typename Mesh::FaceHalfedgeIter hh_it = mesh_.fh_iter(fh); hh_it.is_valid(); ++hh_it ) ++nPolyVerts;
1559 triCounter += (nPolyVerts - 2);
1563 if (*pMaxVertsOut < nPolyVerts)
1564 *pMaxVertsOut = nPolyVerts;
1567 if (_pOutNumIndices) *_pOutNumIndices += nPolyVerts;
1575 template <
class Mesh>
1579 if (updatePerEdgeBuffers_)
1580 updatePerEdgeBuffers();
1581 return perEdgeVertexBuf_.empty() ? 0 : &(perEdgeVertexBuf_[0]);
1584 template <
class Mesh>
1588 if (updatePerEdgeBuffers_)
1589 updatePerEdgeBuffers();
1590 return perEdgeColorBuf_.empty() ? 0 : &(perEdgeColorBuf_[0]);
1594 template <
class Mesh>
1598 unsigned int idx = 0;
1601 pickVertColBuf_.resize( mesh_.n_vertices() );
1602 pickVertBuf_.resize( mesh_.n_vertices() );
1605 typename Mesh::ConstVertexIter v_it(mesh_.vertices_begin()), v_end(mesh_.vertices_end());
1606 for (; v_it!=v_end; ++v_it, ++idx)
1609 pickVertBuf_[idx] = mesh_.point(mesh_.vertex_handle(idx));
1614 template <
class Mesh>
1618 if (!numVerts_ && mesh_.n_vertices())
1620 rebuild_ = REBUILD_FULL;
1624 #ifndef GL_ARB_texture_buffer_object
1625 pickVertexMethod_ = 1;
1632 if (pickVertexMethod_ == 0)
1634 #ifdef GL_ARB_texture_buffer_object
1636 std::vector<int> forwardMap(numVerts_, 0);
1638 for (
int i = 0; i < (int)numVerts_; ++i)
1640 int vboIdx = mapVertexToVBOIndex(i);
1642 forwardMap[vboIdx] = i;
1644 pickVertexMapTBO_.setBufferData(
sizeof(
int) * numVerts_, &forwardMap[0], GL_R32I, GL_STATIC_DRAW);
1646 #endif // GL_ARB_texture_buffer_object
1656 bindPickVertexIbo();
1657 fillInvVertexMap(mesh_.n_vertices(), invVertexMap_);
1666 template <
class Mesh>
1681 if (pickVertexMethod_ == 0)
1687 return pickVertexShader_ && pickVertexShader_->
isLinked();
1691 template <
class Mesh>
1715 if (!supportsPickingVertices_opt())
1720 if (pickVertexMethod_ == 1 && invVertexMap_)
1721 bindPickVertexIbo();
1724 pickVertexShader_->use();
1725 getVertexDeclaration()->activateShaderPipeline(pickVertexShader_);
1727 pickVertexShader_->setUniform(
"pickVertexOffset", _pickOffset);
1729 if (pickVertexMethod_ == 0)
1731 pickVertexShader_->setUniform(
"vboToInputMap", 0);
1732 #ifdef GL_ARB_texture_buffer_object
1733 pickVertexMap_opt()->bind(GL_TEXTURE0);
1737 pickVertexShader_->setUniform(
"mWVP", _mvp);
1740 if (pickVertexMethod_ == 0)
1741 glDrawArrays(GL_POINTS, 0, getNumVerts());
1744 if (pickVertexIBO_opt() && invVertexMap_)
1745 glDrawElements(GL_POINTS, mesh_.n_vertices(), GL_UNSIGNED_INT, 0);
1747 glDrawArrays(GL_POINTS, 0, mesh_.n_vertices());
1751 getVertexDeclaration()->deactivateShaderPipeline(pickVertexShader_);
1752 pickVertexShader_->disable();
1757 if (pickVertexMethod_ == 1)
1763 template <
class Mesh>
1767 if (!updatePerEdgeBuffers_)
1770 perEdgeVertexBuf_.resize(mesh_.n_edges() * 2);
1772 if ( mesh_.has_edge_colors() ) {
1773 perEdgeColorBuf_.resize(mesh_.n_edges() * 2);
1775 perEdgeColorBuf_.clear();
1777 unsigned int idx = 0;
1779 typename Mesh::ConstEdgeIter e_it(mesh_.edges_sbegin()), e_end(mesh_.edges_end());
1780 for (; e_it!=e_end; ++e_it) {
1782 perEdgeVertexBuf_[idx] = mesh_.point(mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it, 0)));
1783 perEdgeVertexBuf_[idx+1] = mesh_.point(mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it, 1)));
1785 if ( mesh_.has_edge_colors() ) {
1786 const Vec4f color = OpenMesh::color_cast<
Vec4f>( mesh_.color(*e_it) ) ;
1787 perEdgeColorBuf_[ idx ] = color;
1788 perEdgeColorBuf_[ idx + 1 ] = color;
1795 updatePerEdgeBuffers_ = 0;
1797 updateEdgeHalfedgeVertexDeclarations();
1800 template <
class Mesh>
1801 template<
typename Mesh::Normal (DrawMeshT<Mesh>::*NormalLookup)(
typename Mesh::FaceHandle)>
1805 if (!updatePerHalfedgeBuffers_)
1808 perHalfedgeVertexBuf_.resize(mesh_.n_halfedges() * 2);
1810 if ( mesh_.has_halfedge_colors() ) {
1811 perHalfedgeColorBuf_.resize(mesh_.n_halfedges() * 2);
1813 perHalfedgeColorBuf_.clear();
1815 unsigned int idx = 0;
1817 for (
typename Mesh::ConstHalfedgeIter he_it(mesh_.halfedges_sbegin()), he_end(mesh_.halfedges_end());
1818 he_it != he_end; ++he_it) {
1820 typename Mesh::HalfedgeHandle next_heh = mesh_.next_halfedge_handle(*he_it);
1821 typename Mesh::HalfedgeHandle previous_heh = mesh_.prev_halfedge_handle(*he_it);
1823 if (mesh_.is_valid_handle(next_heh) && mesh_.is_valid_handle(previous_heh))
1825 perHalfedgeVertexBuf_[idx] = halfedge_point<NormalLookup>(*he_it);
1826 perHalfedgeVertexBuf_[idx+1] = halfedge_point<NormalLookup>(previous_heh);
1831 perHalfedgeVertexBuf_[idx ] = mesh_.point(mesh_.to_vertex_handle(*he_it));
1832 perHalfedgeVertexBuf_[idx+1] = mesh_.point(mesh_.from_vertex_handle(*he_it));
1835 if ( mesh_.has_halfedge_colors() ) {
1836 const Vec4f color = OpenMesh::color_cast<
Vec4f>( mesh_.color(*he_it) ) ;
1837 perHalfedgeColorBuf_[ idx ] = color;
1838 perHalfedgeColorBuf_[ idx + 1 ] = color;
1844 updatePerHalfedgeBuffers_ = 0;
1846 updateEdgeHalfedgeVertexDeclarations();
1849 template<
class Mesh>
1850 template<
typename Mesh::Normal (DrawMeshT<Mesh>::*NormalLookup)(
typename Mesh::FaceHandle)>
1853 typename Mesh::Point p = mesh_.point(mesh_.to_vertex_handle (_heh));
1854 typename Mesh::Point pp = mesh_.point(mesh_.from_vertex_handle(_heh));
1855 typename Mesh::Point pn = mesh_.point(mesh_.to_vertex_handle(mesh_.next_halfedge_handle(_heh)));
1859 if( !mesh_.is_boundary(_heh))
1861 fn = (this->*NormalLookup)(mesh_.face_handle(_heh));
1864 fn = (this->*NormalLookup)(mesh_.face_handle(mesh_.opposite_halfedge_handle(_heh)));
1866 typename Mesh::Point upd = ((fn%(pn-p)).normalize() + (fn%(p-pp)).normalize()).normalize();
1868 upd *= ((pn-p).norm()+(p-pp).norm())*0.08;
1879 template <
class Mesh>
1883 if (updatePerHalfedgeBuffers_) {
1884 if (mesh_.has_face_normals())
1885 updatePerHalfedgeBuffers<&DrawMeshT::cachedNormalLookup>();
1887 updatePerHalfedgeBuffers<&DrawMeshT::computedTriMeshNormal>();
1889 updatePerHalfedgeBuffers<&DrawMeshT::computedNormal>();
1891 return perHalfedgeVertexBuf_.empty() ? 0 : &(perHalfedgeVertexBuf_[0]);
1894 template <
class Mesh>
1898 if (updatePerHalfedgeBuffers_) {
1899 if (mesh_.has_face_normals())
1900 updatePerHalfedgeBuffers<&DrawMeshT::cachedNormalLookup>();
1902 updatePerHalfedgeBuffers<&DrawMeshT::computedTriMeshNormal>();
1904 updatePerHalfedgeBuffers<&DrawMeshT::computedNormal>();
1906 return perHalfedgeColorBuf_.empty() ? 0 : &(perHalfedgeColorBuf_[0]);
1912 template <
class Mesh>
1914 unsigned int _offset)
1916 updatePerEdgeBuffers();
1918 pickEdgeBuf_.resize(mesh_.n_edges() * 2);
1923 typename Mesh::ConstEdgeIter e_it(mesh_.edges_sbegin()), e_end(mesh_.edges_end());
1924 for (; e_it!=e_end; ++e_it) {
1928 pickEdgeBuf_[idx] = pickColor;
1929 pickEdgeBuf_[idx+1] = pickColor;
1937 template <
class Mesh>
1941 if (!numTris_ && mesh_.n_faces())
1943 rebuild_ = REBUILD_FULL;
1951 template <
class Mesh>
1958 return pickEdgeShader_ && pickEdgeShader_->
isLinked();
1962 template <
class Mesh>
1981 if (!supportsPickingEdges_opt())
1988 pickEdgeShader_->use();
1989 getVertexDeclaration()->activateShaderPipeline(pickEdgeShader_);
1991 pickEdgeShader_->setUniform(
"pickVertexOffset", _pickOffset);
1992 pickEdgeShader_->setUniform(
"mWVP", _mvp);
1995 glDrawElements(GL_LINES, mesh_.n_edges() * 2, indexType_, 0);
1998 getVertexDeclaration()->deactivateShaderPipeline(pickEdgeShader_);
1999 pickEdgeShader_->disable();
2013 template <
class Mesh>
2017 if (!numTris_ && mesh_.n_faces())
2019 rebuild_ = REBUILD_FULL;
2023 pickFaceVertexBuf_.resize(3 * numTris_);
2024 pickFaceColBuf_.resize(3 * numTris_);
2026 for (
unsigned int i = 0; i < numTris_; ++i)
2028 unsigned int faceId = (
unsigned int)meshComp_->mapToOriginalFaceID((
int)i);
2031 for (
unsigned int k = 0; k < 3; ++k)
2033 int idx = meshComp_->getIndex(i*3 + k);
2035 typename Mesh::HalfedgeHandle hh = mapToHalfedgeHandle(idx);
2039 vh = mesh_.to_vertex_handle( hh );
2043 int posID = meshComp_->mapToOriginalVertexID(idx, f_id, c_id);
2044 vh = mesh_.vertex_handle(posID);
2047 pickFaceVertexBuf_[i * 3 + k] = mesh_.point( vh );
2049 pickFaceColBuf_[i * 3 + k] = pickColor;
2058 template <
class Mesh>
2062 if (!numTris_ && mesh_.n_faces())
2064 rebuild_ = REBUILD_FULL;
2068 #ifdef GL_ARB_texture_buffer_object
2069 if (meshComp_ && meshComp_->getNumTriangles())
2072 pickFaceTriToFaceMapTBO_.setBufferData(
sizeof(
int) * meshComp_->getNumTriangles(), meshComp_->mapToOriginalFaceIDPtr(), GL_R32I, GL_STATIC_DRAW);
2074 #endif // GL_ARB_texture_buffer_object
2079 template <
class Mesh>
2082 if (!ACG::Texture::supportsTextureBuffer())
2089 return pickFaceShader_ && pickFaceShader_->
isLinked();
2093 template <
class Mesh>
2129 if (!supportsPickingFaces_opt())
2137 pickFaceShader_->use();
2138 getVertexDeclaration()->activateShaderPipeline(pickFaceShader_);
2140 pickFaceShader_->setUniform(
"pickFaceOffset", _pickOffset);
2141 pickFaceShader_->setUniform(
"triToFaceMap", 0);
2143 #ifdef GL_ARB_texture_buffer_object
2144 pickFaceTriangleMap_opt()->bind(GL_TEXTURE0);
2147 pickFaceShader_->setUniform(
"mWVP", _mvp);
2150 glDrawElements(GL_TRIANGLES, getNumTris() * 3, getIndexType(), 0);
2153 getVertexDeclaration()->deactivateShaderPipeline(pickFaceShader_);
2154 pickFaceShader_->disable();
2164 template <
class Mesh>
2167 if (!numTris_ && mesh_.n_faces())
2169 rebuild_ = REBUILD_FULL;
2173 pickFaceVertexBuf_.resize(3 * numTris_);
2174 pickAnyFaceColBuf_.resize(3 * numTris_);
2176 for (
unsigned int i = 0; i < numTris_; ++i)
2178 int faceId = meshComp_->mapToOriginalFaceID(i);
2180 for (
unsigned int k = 0; k < 3; ++k)
2182 int idx = meshComp_->getIndex(i*3 + k);
2185 typename Mesh::HalfedgeHandle hh = mapToHalfedgeHandle(idx);
2189 vh = mesh_.to_vertex_handle( hh );
2193 int posID = meshComp_->mapToOriginalVertexID(idx, f_id, c_id);
2194 vh = mesh_.vertex_handle(posID);
2197 pickFaceVertexBuf_[i * 3 + k] = mesh_.point( vh );
2199 pickAnyFaceColBuf_[i * 3 + k] = pickColor;
2205 updatePerEdgeBuffers();
2207 pickAnyEdgeColBuf_.resize(mesh_.n_edges() * 2);
2209 unsigned int idx = 0;
2210 typename Mesh::ConstEdgeIter e_it(mesh_.edges_sbegin()), e_end(mesh_.edges_end());
2211 for (; e_it!=e_end; ++e_it) {
2215 pickAnyEdgeColBuf_[idx] = pickColor;
2216 pickAnyEdgeColBuf_[idx+1] = pickColor;
2226 pickAnyVertexColBuf_.resize( mesh_.n_vertices() );
2227 pickVertBuf_.resize( mesh_.n_vertices() );
2230 typename Mesh::ConstVertexIter v_it(mesh_.vertices_begin()), v_end(mesh_.vertices_end());
2231 for (; v_it!=v_end; ++v_it, ++idx)
2233 pickAnyVertexColBuf_[idx] = _state.
pick_get_name_color(idx + mesh_.n_faces() + mesh_.n_edges());
2234 pickVertBuf_[idx] = mesh_.point(mesh_.vertex_handle(idx));
2240 template <
class Mesh>
2243 updatePickingFaces_opt(_state);
2244 updatePickingEdges_opt(_state);
2245 updatePickingVertices_opt(_state);
2250 template <
class Mesh>
2253 return supportsPickingFaces_opt() && supportsPickingEdges_opt() && supportsPickingVertices_opt();
2257 template <
class Mesh>
2267 if (!supportsPickingAny_opt())
2270 drawPickingFaces_opt(_mvp, _pickOffset);
2274 drawPickingEdges_opt(_mvp, _pickOffset + mesh_.n_faces());
2276 drawPickingVertices_opt(_mvp, _pickOffset + mesh_.n_faces() + mesh_.n_edges());
2279 template <
class Mesh>
2286 if ( !mesh_.get_property_handle(textureIndexProperty,_indexPropertyName) ) {
2287 if ( _indexPropertyName !=
"No Texture Index" )
2288 std::cerr <<
"DrawMeshT: Unable to get per face texture Index property named " << _indexPropertyName << std::endl;
2293 textureIndexPropertyName_ = _indexPropertyName;
2300 rebuild_ |= REBUILD_TOPOLOGY;
2303 template <
class Mesh>
2310 if ( !mesh_.get_property_handle(perFaceTextureCoordinateProperty,_perFaceTextureCoordinatePropertyName) ) {
2311 if ( _perFaceTextureCoordinatePropertyName !=
"No Texture" )
2312 std::cerr <<
"DrawMeshT: Unable to get per face texture coordinate property named " << _perFaceTextureCoordinatePropertyName << std::endl;
2317 perFaceTextureCoordinatePropertyName_ = _perFaceTextureCoordinatePropertyName;
2321 rebuild_ |= REBUILD_GEOMETRY;
2325 template <
class Mesh>
2329 for (
unsigned int i = 0; i < meshComp_->getNumSubsets(); ++i)
2331 if (meshComp_->getSubset(i)->id > 0) ++n;
2336 template <
class Mesh>
2342 if ( !mesh_.get_property_handle(perFaceTextureCoordinateProperty, perFaceTextureCoordinatePropertyName_) ) {
2352 template <
class Mesh>
2358 if ( !mesh_.get_property_handle(textureIndexProperty, textureIndexPropertyName_) ) {
2371 template <
class Mesh>
2374 vertexDecl_->clear();
2381 for (
size_t i = 0; i < additionalElements_.size(); ++i)
2397 switch (prop->source_)
2399 case PROPERTY_SOURCE_VERTEX: baseProp = mesh_._get_vprop(prop->
name_);
break;
2400 case PROPERTY_SOURCE_FACE: baseProp = mesh_._get_fprop(prop->
name_);
break;
2401 case PROPERTY_SOURCE_HALFEDGE: baseProp = mesh_._get_hprop(prop->
name_);
break;
2402 default: baseProp = mesh_._get_vprop(prop->
name_);
break;
2420 vertexDecl_->addElement(&prop->
destType_);
2423 std::cerr <<
"Could not detect data type of property " << prop->
name_ << std::endl;
2428 template <
class Mesh>
2431 vertexDeclEdgeCol_->clear();
2433 vertexDeclEdgeCol_->addElement(GL_FLOAT, 4,
VERTEX_USAGE_COLOR, perEdgeColorBuffer());
2435 vertexDeclHalfedgeCol_->clear();
2437 vertexDeclHalfedgeCol_->addElement(GL_FLOAT, 4,
VERTEX_USAGE_COLOR, perHalfedgeColorBuffer());
2439 vertexDeclHalfedgePos_->clear();
2442 vertexDeclEdgeCol_->setVertexStride(0);
2443 vertexDeclHalfedgeCol_->setVertexStride(0);
2444 vertexDeclHalfedgePos_->setVertexStride(0);
2447 template <
class Mesh>
2454 template<
class Mesh>
2457 int faceId = -1, cornerId = -1;
2461 meshComp_->mapToOriginalVertexID(_vertexId, faceId, cornerId);
2465 typename Mesh::FaceHandle fh = mesh_.face_handle(faceId);
2469 for (
int k = 0; k < cornerId && hh_it.is_valid(); ++k )
2475 return typename Mesh::HalfedgeHandle(-1);
2479 template <
class Mesh>
2483 unsigned int offset = _vertex * _stride + _elementOffset;
2486 char* dst =
static_cast<char*
>(_dstBuf) + offset;
2489 memcpy(dst, _elementData, _elementSize);
2492 template <
class Mesh>
2496 float f3[3] = {float(_n[0]), float(_n[1]), float(_n[2])};
2498 writeVertexElement(&vertices_[0], _vertex, vertexDecl_->getVertexStride(), 0, 12, f3);
2501 template <
class Mesh>
2505 float f3[3] = {float(_n[0]), float(_n[1]), float(_n[2])};
2507 writeVertexElement(&vertices_[0], _vertex, vertexDecl_->getVertexStride(), offsetNormal_, 12, f3);
2511 template <
class Mesh>
2514 writeVertexElement(&vertices_[0], _vertex, vertexDecl_->getVertexStride(), offsetTexc_, 8, _uv.data());
2517 template <
class Mesh>
2520 writeVertexElement(&vertices_[0], _vertex, vertexDecl_->getVertexStride(), offsetColor_, 4, &_color);
2524 template <
class Mesh>
2529 writeVertexElement(&vertices_[0], _vertex, vertexDecl_->getVertexStride(), _elementDesc->getByteOffset(), elementSize, _propf.data());
2534 template <
class Mesh>
2539 for (
size_t i = 0; i < additionalElements_.size(); ++i)
2541 if (additionalElements_[i].name_ == _propertyName)
2543 additionalElements_[i].source_ = _source;
2553 prop.
name_ = _propertyName;
2554 prop.source_ = _source;
2558 additionalElements_.push_back(prop);
2564 template <
class Mesh>
2567 bool success =
true;
2571 file.open(_vertexShaderFile.c_str(), std::ios_base::in);
2579 file.getline(line, 0xff);
2582 QString strLine = line;
2583 strLine = strLine.simplified();
2586 if (!strLine.startsWith(
"//") && !strLine.startsWith(
"*/"))
2589 if (strLine.startsWith(
"in ") || strLine.contains(
" in "))
2592 int semIdx = strLine.indexOf(
';');
2600 QString strName = strLine;
2601 strName.remove(semIdx, strName.length());
2603 strName = strName.simplified();
2606 int lastWhite = strName.lastIndexOf(
' ');
2610 strName.remove(0, lastWhite);
2612 strName = strName.simplified();
2615 if (strName !=
"inPosition" &&
2616 strName !=
"inTexCoord" &&
2617 strName !=
"inNormal" &&
2618 strName !=
"inColor")
2622 std::string propName = strName.toStdString();
2625 PropertySource src = PROPERTY_SOURCE_VERTEX;
2627 if (strLine.contains(
"flat "))
2630 src = PROPERTY_SOURCE_FACE;
2632 if (!mesh_._get_fprop(propName))
2633 src = PROPERTY_SOURCE_VERTEX;
2636 if (src == PROPERTY_SOURCE_VERTEX)
2638 if (!mesh_._get_vprop(propName))
2639 src = PROPERTY_SOURCE_HALFEDGE;
2643 if (src == PROPERTY_SOURCE_VERTEX)
2645 if ( mesh_._get_hprop(propName) && src == PROPERTY_SOURCE_VERTEX)
2646 src = PROPERTY_SOURCE_HALFEDGE;
2650 if (src == PROPERTY_SOURCE_HALFEDGE && !mesh_._get_hprop(propName))
2652 std::cerr <<
"DrawMesh error - requested property " << propName <<
" does not exist" << std::endl;
2657 addVertexElement(propName, src);
2678 template<
class Mesh>
2682 file.open(_filename);
2686 for (
int attrId = 0; attrId < 3; ++attrId)
2688 for (
int i = 0; i < numVerts_; ++i)
2691 const char* v = &vertices_[i * vertexDecl_->getVertexStride()];
2693 const float* pos =
reinterpret_cast<const float*
>((
const void*)(v + offsetPos_));
2694 const float* n =
reinterpret_cast<const float*
>((
const void*)(v + offsetNormal_));
2695 const float* texc =
reinterpret_cast<const float*
>((
const void*)(v + offsetTexc_));
2700 case 0: file <<
"v "<<pos[0]<<
" "<<pos[1]<<
" "<<pos[2]<<
"\n";
break;
2701 case 1: file <<
"vt "<<texc[0]<<
" "<<texc[1]<<
"\n";
break;
2702 case 2: file <<
"vn "<<n[0]<<
" "<<n[1]<<
" "<<n[2]<<
"\n";
break;
2709 for (
int i = 0; i < numTris_; ++i)
2712 const int* tri = meshComp_->getIndexBuffer() + i*3;
2714 file <<
"f "<<tri[0]+1<<
"/"<<tri[0]+1<<
"/"<<tri[0]+1<<
" "<<tri[1]+1<<
"/"<<tri[1]+1<<
"/"<<tri[1]+1<<
" "<<tri[2]+1<<
"/"<<tri[2]+1<<
"/"<<tri[2]+1<<
"\n";
2723 template <
class Mesh>
2728 unsigned int stride = vertexDecl_->getVertexStride();
2731 unsigned int offset = _vertex * stride;
2734 memcpy(_dst, &vertices_[offset], stride);
2741 template <
class Mesh>
2744 updateFullVBO_ =
true;
2748 template <
class Mesh>
2763 int numVerts = 3 * numTris;
2765 std::vector<char> fullBuf(numVerts * stride);
2768 for (
int i = 0; i < numTris; ++i)
2770 for (
int k = 0; k < 3; ++k)
2772 int idx = i * 3 + k;
2774 readVertexFromVBO(vertexID, &fullBuf[idx * stride]);
2776 if (colorMode_ == 2)
2780 int faceId = meshComp_->mapToOriginalFaceID(i);
2781 unsigned int fcolor = getFaceColor(mesh_.face_handle(faceId));
2784 writeVertexElement(&fullBuf[0], idx, vertexDecl_->getVertexStride(), offsetColor_, 4, &fcolor);
2790 if (!fullBuf.empty())
2791 vboFull_.upload(fullBuf.size(), &fullBuf[0], GL_STATIC_DRAW);
2794 updateFullVBO_ =
false;
int getFaceSize(const int _faceID) const
GLuint indexBuffer
Use vertex array object.
const void * propDataPtr_
memory address of property data
ShaderGenDesc shaderDesc
Drawmode and other shader params.
bool getFaceAttr(const int _faceID, const int _attrID, int *_out) const
void updatePickingFaces_opt(ACG::GLState &_state)
Update color picking array for the shader implementation.
int perFaceTextureCoordinateAvailable()
Check if per Face Texture coordinates are available.
Namespace providing different geometric functions concerning angles.
int * getFaceAttr(const int _faceID, const int _attrID) const
void addPointRenderObjects(IRenderer *_renderer, const RenderObject *_baseObj)
render vertices only, deferred draw call
void createVBO()
stores the vertex buffer on the gpu
void updateFullVBO()
update the full mesh vbo
static void bindBuffer(GLenum _target, GLuint _buffer)
replaces glBindBuffer, supports locking
void addLineRenderObjects(IRenderer *_renderer, const RenderObject *_baseObj)
render the mesh in wireframe mode, deferred draw call
static bool is_trimesh()
Determine whether this is a PolyMeshT or TriMeshT ( This function does not check the per face vertex ...
Vec4uc pick_get_name_color(unsigned int _idx)
void drawPickingAny_opt(const GLMatrixf &_mvp, int _pickOffset)
Optimized rendering of any picking ids with a shader.
Interface class between scenegraph and renderer.
unsigned int countTris(unsigned int *_pOutMaxPolyVerts=0, unsigned int *_pOutNumIndices=0)
Number of triangles after triangulation of the mesh.
Default property class for any type T.
static void bindTexture(GLenum _target, GLuint _buffer)
replaces glBindTexture, supports locking
std::string vertexShaderInputName_
input name id in vertex shader
static void colorPointer(GLint _size, GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glColorPointer, supports locking
void dumpObj(const char *_filename) const
dump current vertex/index buffer to wavefront obj
void updatePickingEdges(ACG::GLState &_state, uint _offset=0)
Update color picking array for edges.
void rebuild()
draw_mesh updater
GLuint vertexBuffer
VBO, IBO ids, ignored if VAO is provided.
virtual size_t n_elements() const =0
Number of elements in property.
void updatePickingEdges_opt(ACG::GLState &_state)
Update color picking array for the shader implementation.
int getNumIndices() const
unsigned int getVertexColor(const typename Mesh::VertexHandle _vh)
return a vertex color from mesh
void bindBuffers()
eventually rebuilds buffers used for rendering and binds index and vertex buffer
int getNumTriangles() const
Kernel::Point Point
Coordinate type.
void invalidateFullVBO()
the mesh has been changed
void drawVertices()
render vertices only
Handle for a halfedge entity.
void updatePickingVertices(ACG::GLState &_state, uint _offset=0)
std::string name_
property name in openmesh
Description of one vertex element.
unsigned int getVertexStride(unsigned int i=0) const
const VertexDeclaration * getVertexDeclaration() const
static void enableClientState(GLenum _cap)
replaces glEnableClientState, supports locking
const void * testMeshPropertyTypeT(const OpenMesh::BaseProperty *_prop, unsigned int *_outSize) const
test mesh property for type T
GLSL::Program * getProgram(const ShaderGenDesc *_desc, const std::vector< unsigned int > &_mods)
Query a dynamically generated program from cache.
static unsigned int getElementSize(const VertexElement *_pElement)
void draw(std::map< int, GLuint > *_textureMap, bool _nonindexed=false)
binds index and vertex buffer and executes draw calls
Mesh::Point halfedge_point(const typename Mesh::HalfedgeHandle _heh)
compute halfedge point compute visualization point for halfedge (shifted to interior of face) ...
Kernel::ConstFaceHalfedgeIter ConstFaceHalfedgeIter
Circulator.
const VertexDeclaration * vertexDecl
Defines the vertex buffer layout, ignored if VAO is provided.
bool scanVertexShaderForInput(const std::string &_vertexShaderFile)
Scan vertex layout from vertex shader.
void drawPickingFaces_opt(const GLMatrixf &_mvp, int _pickOffset)
Optimized rendering of face picking ids with a shader.
void updatePerEdgeBuffers()
Update all per edge drawing buffers.
void bindBuffersToRenderObject(RenderObject *_obj)
eventually rebuilds buffers used for rendering and binds index and vertex buffer
void createIBO()
stores the index buffer on the gpu
int getSingleFaceAttr(const int _faceID, const int _faceCorner, const int _attrID) const
GLuint getIBO()
get opengl index buffer id
void createVertexDeclaration()
creates all vertex declarations needed for deferred draw call renderer
bool isLinked()
Returns if the program object has been succesfully linked.
VertexDeclaration * getVertexDeclaration()
get vertex declaration of the current vbo layout
ACG::Vec3f * perHalfedgeVertexBuffer()
get a pointer to the per edge vertex buffer
VectorT< float, 3 > Vec3f
unsigned int getFaceColor(const typename Mesh::FaceHandle _fh)
return a face color from mesh
defined by user via VertexElement::shaderInputName_
void addTriRenderObjects(IRenderer *_renderer, const RenderObject *_baseObj, std::map< int, GLuint > *_textureMap, bool _nonindexed=false)
adds RenderObjects to a deferred draw call renderer
void updatePickingAny(ACG::GLState &_state)
Call this function to update the color picking array.
ACG::Vec4f * perHalfedgeColorBuffer()
get a pointer to the per edge color buffer
static void normalPointer(GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glNormalPointer, supports locking
VectorT< unsigned char, 4 > Vec4uc
void updatePickingAny_opt(ACG::GLState &_state)
Update color picking array for the shader implementation.
int declElementID_
element id in vertex declaration
GLSL::Program * pickFaceShader_
optimized face picking shader
bool supportsPickingEdges_opt()
Check if optimized face picking is supported.
void setTextureIndexPropertyName(std::string _indexPropertyName)
set the name of the property used for texture index specification
static void texcoordPointer(GLint _size, GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glTexcoordPointer, supports locking
void unbindBuffers()
disables vertex, normal, texcoord and color pointers in OpenGL
void readVertexFromVBO(unsigned int _vertex, void *_dst)
Read one vertex from the rendering vbo.
void updateEdgeHalfedgeVertexDeclarations()
updates per edge and halfedge vertex declarations
virtual void addRenderObject(RenderObject *_renderObject)
Callback for the scenegraph nodes, which send new render objects via this function.
void updatePickingFaces(ACG::GLState &_state)
Update color picking array for faces.
static ShaderCache * getInstance()
Return instance of the ShaderCache singleton.
unsigned int getNumTextures()
returns the number of used textured of this mesh
unsigned int getMemoryUsage(bool _printReport=false)
measures the size in bytes of allocated memory. eventually prints a report to std::cout ...
Class to define the vertex input layout.
Kernel::ConstVertexFaceIter ConstVertexFaceIter
Circulator.
bool supportsPickingFaces_opt()
Check if optimized face picking is supported.
int getVertexAdjCount(const int _vertexID) const
unsigned int type_
GL_FLOAT, GL_UNSIGNED_BYTE, GL_INT, ...
void addTexture(const Texture &_t)
adds a texture to stage RenderObjects::numTextures()
static void disableClientState(GLenum _cap)
replaces glDisableClientState, supports locking
Kernel::VertexHandle VertexHandle
Handle for referencing the corresponding item.
void readVertex(unsigned int _vertex, const typename Mesh::VertexHandle _vh, const typename Mesh::HalfedgeHandle _hh, const typename Mesh::FaceHandle _fh)
reads a vertex from mesh_ and write it to vertex buffer
static void vertexPointer(GLint _size, GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glVertexPointer, supports locking
ACG::Vec3f * perEdgeVertexBuffer()
get a pointer to the per edge vertex buffer
VertexElement destType_
property type as stored in vbo
unsigned int numElements_
how many elements of type_
int getTextureIDofTri(unsigned int _tri)
get the texture index of a triangle
unsigned int mapVertexToVBOIndex(unsigned int _v)
map from vertex index of the original mesh point buffer to the corresponding vertex index inside the ...
const void * getMeshPropertyType(OpenMesh::BaseProperty *_prop, GLuint *_outType, unsigned int *_outSize) const
get the data type of a mesh property
GLuint getVBO()
get opengl vertex buffer id
const T * data() const
Get pointer to array (does not work for T==bool)
VERTEX_USAGE usage_
position, normal, shader input ..
const char * shaderInputName_
set shader input name, if usage_ = VERTEX_USAGE_USER_DEFINED otherwise this is set automatically...
int perFaceTextureIndexAvailable()
Check if texture indices are available.
GLenum indexType
Index element type.
const void * pointer_
Offset in bytes to the first occurrence of this element in vertex buffer; Or address to vertex data i...
bool supportsPickingVertices_opt()
Check if optimized vertex picking is supported.
const GLenum & depthFunc() const
get glDepthFunc() that is supposed to be active
void setPerFaceTextureCoordinatePropertyName(std::string _perFaceTextureCoordinatePropertyName)
set the name of the property used for texture coordinate
static void bindBufferARB(GLenum _target, GLuint _buffer)
same function as bindBuffer
void updatePerHalfedgeBuffers()
Update all per edge drawing buffer n The updated buffers are: per edge vertex buffer ( 2 vertices per...
void addVertexElement(const std::string &_propertyName, PropertySource _source=PROPERTY_SOURCE_VERTEX)
Add custom elements to the vertex layout.
void updatePickingVertices_opt(ACG::GLState &_state)
Update color picking array for the shader implementation.
Kernel::FaceHalfedgeIter FaceHalfedgeIter
Circulator.
ACG::Vec4f * perEdgeColorBuffer()
get a pointer to the per edge color buffer
int getIndex(int _i) const
bool supportsPickingAny_opt()
Check if optimized any picking is supported.
void drawPickingVertices_opt(const GLMatrixf &_mvp, int _pickOffset)
Optimized rendering of vertex picking ids with a shader.
void drawLines()
render the mesh in wireframe mode
int getTextureIDofFace(unsigned int _face)
get the texture index of a face
void drawPickingEdges_opt(const GLMatrixf &_mvp, int _pickOffset)
Optimized rendering of edge picking ids with a shader.
VertexElement sourceType_
property type as stored in openmesh
void updateGPUBuffers()
eventually update vertex and index buffers
int getVertexAdjFace(const int _vertexID, const int _k) const