44 #define ACG_DRAW_MESH_TCC 48 #include "DrawMesh.hh" 50 #include <ACG/GL/gl.hh> 51 #include <ACG/Geometry/GPUCacheOptimizer.hh> 52 #include <ACG/GL/VertexDeclaration.hh> 53 #include <ACG/GL/ShaderCache.hh> 75 DrawMeshT<Mesh>::DrawMeshT(
Mesh& _mesh)
77 rebuild_(REBUILD_NONE),
78 prevNumFaces_(0), prevNumVerts_(0),
81 flatMode_(0), bVBOinFlatMode_(0),
82 textureMode_(1), bVBOinHalfedgeTexMode_(1),
83 halfedgeNormalMode_(0), bVBOinHalfedgeNormalMode_(0),
85 offsetPos_(0), offsetNormal_(20), offsetTexc_(12), offsetColor_(32),
86 textureIndexPropertyName_(
"Not Set"),
87 perFaceTextureCoordinatePropertyName_(
"h:texcoords2D"),
89 updatePerEdgeBuffers_(1),
90 updatePerHalfedgeBuffers_(1)
96 pickVertexShader_ = 0;
101 createVertexDeclaration();
103 vertexDeclEdgeNew_.addElement(GL_FLOAT, 3, VERTEX_USAGE_POSITION);
104 vertexDeclEdgeNew_.addElement(GL_FLOAT, 4, VERTEX_USAGE_COLOR);
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(static_cast<unsigned int>(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 (
size_t 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)
577 const VertexProperty* prop = &additionalElements_[i];
579 if (prop->declElementID_ >= 0)
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)
608 VertexProperty* propDesc = &additionalElements_[i];
610 if (propDesc->declElementID_ >= 0)
612 const VertexElement* el = vertexDecl_->getElement((
unsigned int)propDesc->declElementID_);
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;
630 const void* attribData = propDesc->propDataPtr_;
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_;
1168 template <
class Mesh>
1171 unsigned int res = 0;
1172 unsigned int sysBufSize = 0;
1177 if (!vertices_.empty())
1178 sysBufSize += vertexDecl_->getVertexStride() * numVerts_;
1185 unsigned int mapsSize = 0;
1188 res += mesh_.n_vertices() * 4;
1194 unsigned int pickBufSize = 0;
1196 pickBufSize += pickVertBuf_.capacity() *
sizeof(
ACG::Vec3f);
1197 pickBufSize += pickVertColBuf_.capacity() *
sizeof(
ACG::Vec4uc);
1199 pickBufSize += pickEdgeBuf_.capacity() *
sizeof(
ACG::Vec4uc);
1201 pickBufSize += pickFaceVertexBuf_.capacity() *
sizeof(
ACG::Vec3f);
1202 pickBufSize += pickFaceColBuf_.capacity() *
sizeof(
ACG::Vec4uc);
1205 pickBufSize += pickAnyFaceColBuf_.capacity() *
sizeof(
ACG::Vec4uc);
1206 pickBufSize += pickAnyEdgeColBuf_.capacity() *
sizeof(
ACG::Vec4uc);
1207 pickBufSize += pickAnyVertexColBuf_.capacity() *
sizeof(
ACG::Vec4uc);
1213 unsigned int edgeBufSize = 0;
1215 edgeBufSize += perEdgeVertexBuf_.capacity() *
sizeof(
ACG::Vec3f);
1216 edgeBufSize += perEdgeColorBuf_.capacity() *
sizeof(
ACG::Vec4uc);
1218 edgeBufSize += perHalfedgeVertexBuf_.capacity() *
sizeof(
ACG::Vec3f);
1219 edgeBufSize += perHalfedgeColorBuf_.capacity() *
sizeof(
ACG::Vec4uc);
1225 unsigned int gpuBufSize = 0;
1228 gpuBufSize += numTris_ * 3 * (indexType_ == GL_UNSIGNED_INT ? 4 : 2);
1231 gpuBufSize += numVerts_ * vertexDecl_->getVertexStride();
1235 std::cout <<
"\nDrawMesh memory usage in MB:\n";
1236 std::cout <<
"Vertex+IndexBuffer (SYSMEM only): " << float(sysBufSize) / (1024 * 1024);
1237 std::cout <<
"\nMappings: " << float(mapsSize) / (1024 * 1024);
1238 std::cout <<
"\nPicking Buffers: " << float(pickBufSize) / (1024 * 1024);
1239 std::cout <<
"\nEdge Buffers: " << float(edgeBufSize) / (1024 * 1024);
1240 std::cout <<
"\nTotal SYSMEM: " << float(res) / (1024 * 1024);
1241 std::cout <<
"\nTotal GPU: " << float(gpuBufSize) / (1024 * 1024) << std::endl;
1248 template <
class Mesh>
1252 if ((!numTris_ && mesh_.n_faces())|| ! numVerts_ || (!meshComp_ && mesh_.n_faces()))
1254 rebuild_ = REBUILD_FULL;
1257 if (bVBOinHalfedgeNormalMode_ != halfedgeNormalMode_) rebuild_ = REBUILD_FULL;
1261 if (rebuild_ == REBUILD_NONE)
1263 if (bVBOinFlatMode_ != flatMode_ || bVBOinHalfedgeTexMode_ != textureMode_ || (colorMode_ && curVBOColorMode_ != colorMode_))
1273 template <
class Mesh>
1280 template <
class Mesh>
1287 template <
class Mesh>
1290 if (_v < mesh_.n_vertices())
1293 return invVertexMap_[_v];
1298 return (
unsigned int)-1;
1301 template <
class Mesh>
1319 glClientActiveTexture(GL_TEXTURE0);
1331 template <
class Mesh>
1345 template <
class Mesh>
1359 template <
class Mesh>
1368 vertexDecl_->activateFixedFunction();
1371 #ifdef DEBUG_MEM_USAGE 1372 getMemoryUsage(
true);
1381 for (
int i = 0; i < meshComp_->getNumSubsets(); ++i)
1385 if ( _textureMap->find(sub->id) == _textureMap->end() ) {
1386 std::cerr <<
"Illegal texture index ... trying to access " << sub->id << std::endl;
1393 glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(sub->numTris * 3), indexType_,
1394 (GLvoid*)( (
size_t)sub->startIndex * (indexType_ == GL_UNSIGNED_INT ? 4 : 2)));
1396 glDrawArrays(GL_TRIANGLES, sub->startIndex, static_cast<GLsizei>(sub->numTris * 3));
1402 glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(numTris_ * 3), indexType_, 0);
1404 glDrawArrays(GL_TRIANGLES, 0, static_cast<GLsizei>(numTris_ * 3));
1412 template <
class Mesh>
1419 bindBuffersToRenderObject(&ro);
1432 for (
int i = 0; i < meshComp_->getNumSubsets(); ++i)
1438 if ( _textureMap->find(sub->id) == _textureMap->end() ) {
1439 std::cerr <<
"Illegal texture index ... trying to access " << sub->id << std::endl;
1444 tex.type = GL_TEXTURE_2D;
1445 tex.id = (*_textureMap)[sub->id];
1451 GLState::activeTexture(GL_TEXTURE0);
1452 GLint textureID = 0;
1453 glGetIntegerv(GL_TEXTURE_BINDING_2D, &textureID);
1456 tex.type = GL_TEXTURE_2D;
1464 ro.glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(sub->numTris * 3), indexType_,
1465 (GLvoid*)((
size_t)sub->startIndex * (indexType_ == GL_UNSIGNED_INT ? 4 : 2)));
1467 ro.glDrawArrays(GL_TRIANGLES, sub->startIndex, static_cast<GLsizei>(sub->numTris * 3) );
1475 ro.glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(numTris_ * 3), indexType_, 0);
1477 ro.glDrawArrays(GL_TRIANGLES,0, static_cast<GLsizei>(numTris_ * 3));
1484 template <
class Mesh>
1489 if (mesh_.n_edges())
1493 glDrawElements(GL_LINES, static_cast<GLsizei>(mesh_.n_edges() * 2), indexType_, 0);
1500 template <
class Mesh>
1503 updatePerEdgeBuffersNew();
1504 if (!mesh_.n_edges())
1509 ro.glDrawArrays(GL_LINES, 0, static_cast<GLsizei>(mesh_.n_edges() * 2));
1513 template <
class Mesh>
1520 glDrawArrays(GL_POINTS, 0, static_cast<GLsizei>(numVerts_));
1525 template <
class Mesh>
1529 bindBuffersToRenderObject(&ro);
1533 ro.glDrawArrays(GL_POINTS, 0, static_cast<GLsizei>(numVerts_));
1541 template <
class Mesh>
1544 unsigned int triCounter = 0;
1546 if (pMaxVertsOut) *pMaxVertsOut = 0;
1547 if (_pOutNumIndices) *_pOutNumIndices = 0;
1549 for (
unsigned int i = 0; i < mesh_.n_faces(); ++i)
1551 typename Mesh::FaceHandle fh = mesh_.face_handle(i);
1554 unsigned int nPolyVerts = 0;
1556 for (
typename Mesh::FaceHalfedgeIter hh_it = mesh_.fh_iter(fh); hh_it.is_valid(); ++hh_it ) ++nPolyVerts;
1558 triCounter += (nPolyVerts - 2);
1562 if (*pMaxVertsOut < nPolyVerts)
1563 *pMaxVertsOut = nPolyVerts;
1566 if (_pOutNumIndices) *_pOutNumIndices += nPolyVerts;
1574 template <
class Mesh>
1578 if (updatePerEdgeBuffers_)
1579 updatePerEdgeBuffers();
1580 return perEdgeVertexBuf_.empty() ? 0 : &(perEdgeVertexBuf_[0]);
1583 template <
class Mesh>
1587 if (updatePerEdgeBuffers_)
1588 updatePerEdgeBuffers();
1589 return perEdgeColorBuf_.empty() ? 0 : &(perEdgeColorBuf_[0]);
1593 template <
class Mesh>
1597 unsigned int idx = 0;
1600 pickVertColBuf_.resize( mesh_.n_vertices() );
1601 pickVertBuf_.resize( mesh_.n_vertices() );
1604 typename Mesh::ConstVertexIter v_it(mesh_.vertices_begin()), v_end(mesh_.vertices_end());
1605 for (; v_it!=v_end; ++v_it, ++idx)
1608 pickVertBuf_[idx] = mesh_.point(mesh_.vertex_handle(idx));
1613 template <
class Mesh>
1617 if (!numVerts_ && mesh_.n_vertices())
1619 rebuild_ = REBUILD_FULL;
1627 if (pickVertexMethod_ == 0)
1629 std::vector<int> forwardMap(numVerts_, 0);
1631 for (
int i = 0; i < (int)numVerts_; ++i)
1633 int vboIdx = mapVertexToVBOIndex(i);
1635 forwardMap[vboIdx] = i;
1637 pickVertexMapTBO_.setBufferData(
sizeof(
int) * numVerts_, &forwardMap[0], GL_R32I, GL_STATIC_DRAW);
1647 bindPickVertexIbo();
1648 fillInvVertexMap(mesh_.n_vertices(), invVertexMap_);
1657 template <
class Mesh>
1664 if (pickVertexMethod_ == 0)
1666 desc.fragmentTemplateFile =
"Picking/pick_vertices_fs.glsl";
1667 desc.vertexTemplateFile =
"Picking/pick_vertices_vs.glsl";
1671 desc.fragmentTemplateFile =
"Picking/pick_vertices_fs2.glsl";
1672 desc.vertexTemplateFile =
"Picking/vertex.glsl";
1674 pickVertexShader_ = ShaderCache::getInstance()->getProgram(&desc,
nullptr);
1677 return pickVertexShader_ && pickVertexShader_->isLinked();
1681 template <
class Mesh>
1705 if (!supportsPickingVertices_opt())
1710 if (pickVertexMethod_ == 1 && invVertexMap_)
1711 bindPickVertexIbo();
1714 pickVertexShader_->use();
1715 getVertexDeclaration()->activateShaderPipeline(pickVertexShader_);
1717 pickVertexShader_->setUniform(
"pickVertexOffset", static_cast<GLint>(_pickOffset) );
1719 if (pickVertexMethod_ == 0)
1721 pickVertexShader_->setUniform(
"vboToInputMap", 0);
1722 pickVertexMap_opt()->bind(GL_TEXTURE0);
1725 pickVertexShader_->setUniform(
"mWVP", _mvp);
1728 if (pickVertexMethod_ == 0)
1729 glDrawArrays(GL_POINTS, 0, static_cast<GLsizei>(getNumVerts()));
1732 if (pickVertexIBO_opt() && invVertexMap_)
1733 glDrawElements(GL_POINTS, static_cast<GLsizei>(mesh_.n_vertices()), GL_UNSIGNED_INT, 0);
1735 glDrawArrays(GL_POINTS, 0, static_cast<GLsizei>(mesh_.n_vertices()));
1739 getVertexDeclaration()->deactivateShaderPipeline(pickVertexShader_);
1740 pickVertexShader_->disable();
1745 if (pickVertexMethod_ == 1)
1751 template <
class Mesh>
1755 if (!updatePerEdgeBuffers_)
1758 perEdgeVertexBuf_.resize(mesh_.n_edges() * 2);
1760 if ( mesh_.has_edge_colors() ) {
1761 perEdgeColorBuf_.resize(mesh_.n_edges() * 2);
1763 perEdgeColorBuf_.clear();
1765 unsigned int idx = 0;
1767 typename Mesh::ConstEdgeIter e_it(mesh_.edges_sbegin()), e_end(mesh_.edges_end());
1768 for (; e_it!=e_end; ++e_it) {
1770 perEdgeVertexBuf_[idx] = mesh_.point(mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it, 0)));
1771 perEdgeVertexBuf_[idx+1] = mesh_.point(mesh_.to_vertex_handle(mesh_.halfedge_handle(*e_it, 1)));
1773 if ( mesh_.has_edge_colors() ) {
1774 const Vec4f color = OpenMesh::color_cast<
Vec4f>( mesh_.color(*e_it) ) ;
1775 perEdgeColorBuf_[ idx ] = color;
1776 perEdgeColorBuf_[ idx + 1 ] = color;
1783 updatePerEdgeBuffers_ = 0;
1785 updateEdgeHalfedgeVertexDeclarations();
1788 template <
class Mesh>
1791 if (!updatePerEdgeBuffers_)
1793 perEdgeBuf_.clear();
1794 perEdgeBuf_.reserve(mesh_.n_edges() * 2 * (3 + 4));
1795 auto push_vec4 = [
this](
const Vec4f &v) {
1796 perEdgeBuf_.push_back(v[0]);
1797 perEdgeBuf_.push_back(v[1]);
1798 perEdgeBuf_.push_back(v[2]);
1799 perEdgeBuf_.push_back(v[3]);
1801 auto push_vec3 = [
this](
const Vec3d &v) {
1802 perEdgeBuf_.push_back(v[0]);
1803 perEdgeBuf_.push_back(v[1]);
1804 perEdgeBuf_.push_back(v[2]);
1806 bool have_edge_colors = mesh_.has_edge_colors();
1807 Vec4f color {0.f, 1.f, 0.f, 1.f};
1808 for (
const auto &eh: mesh_.edges()) {
1809 if (have_edge_colors) {
1810 color = OpenMesh::color_cast<
Vec4f>(mesh_.color(eh));
1812 auto heh = mesh_.halfedge_handle(eh, 0);
1813 ACG::Vec3d pos_from = mesh_.point(mesh_.from_vertex_handle(heh));
1814 ACG::Vec3d pos_to = mesh_.point(mesh_.to_vertex_handle(heh));
1815 push_vec3(pos_from);
1822 perEdgeBuf_.size() *
sizeof(perEdgeBuf_[0]),
1823 static_cast<GLvoid*>(perEdgeBuf_.data()),
1827 updatePerEdgeBuffers_ = 0;
1830 template <
class Mesh>
1831 template<
typename Mesh::Normal (DrawMeshT<Mesh>::*NormalLookup)(
typename Mesh::FaceHandle)>
1835 if (!updatePerHalfedgeBuffers_)
1838 perHalfedgeVertexBuf_.resize(mesh_.n_halfedges() * 2);
1840 if ( mesh_.has_halfedge_colors() ) {
1841 perHalfedgeColorBuf_.resize(mesh_.n_halfedges() * 2);
1843 perHalfedgeColorBuf_.clear();
1845 unsigned int idx = 0;
1847 for (
typename Mesh::ConstHalfedgeIter he_it(mesh_.halfedges_sbegin()), he_end(mesh_.halfedges_end());
1848 he_it != he_end; ++he_it) {
1850 typename Mesh::HalfedgeHandle next_heh = mesh_.next_halfedge_handle(*he_it);
1851 typename Mesh::HalfedgeHandle previous_heh = mesh_.prev_halfedge_handle(*he_it);
1853 if (mesh_.is_valid_handle(next_heh) && mesh_.is_valid_handle(previous_heh))
1855 perHalfedgeVertexBuf_[idx] = halfedge_point<NormalLookup>(*he_it);
1856 perHalfedgeVertexBuf_[idx+1] = halfedge_point<NormalLookup>(previous_heh);
1861 perHalfedgeVertexBuf_[idx ] = mesh_.point(mesh_.to_vertex_handle(*he_it));
1862 perHalfedgeVertexBuf_[idx+1] = mesh_.point(mesh_.from_vertex_handle(*he_it));
1865 if ( mesh_.has_halfedge_colors() ) {
1866 const Vec4f color = OpenMesh::color_cast<
Vec4f>( mesh_.color(*he_it) ) ;
1867 perHalfedgeColorBuf_[ idx ] = color;
1868 perHalfedgeColorBuf_[ idx + 1 ] = color;
1873 if(perHalfedgeVertexBuf_.size() > 0)
1875 fillHEVBO(perHalfedgeVertexBuf_.size(),
sizeof(perHalfedgeVertexBuf_[0]), perHalfedgeVertexBuf_.data());
1878 updatePerHalfedgeBuffers_ = 0;
1880 updateEdgeHalfedgeVertexDeclarations();
1883 template<
class Mesh>
1884 template<
typename Mesh::Normal (DrawMeshT<Mesh>::*NormalLookup)(
typename Mesh::FaceHandle)>
1887 typename Mesh::Point p = mesh_.point(mesh_.to_vertex_handle (_heh));
1888 typename Mesh::Point pp = mesh_.point(mesh_.from_vertex_handle(_heh));
1889 typename Mesh::Point pn = mesh_.point(mesh_.to_vertex_handle(mesh_.next_halfedge_handle(_heh)));
1893 if( !mesh_.is_boundary(_heh))
1895 fn = (this->*NormalLookup)(mesh_.face_handle(_heh));
1898 fn = (this->*NormalLookup)(mesh_.face_handle(mesh_.opposite_halfedge_handle(_heh)));
1900 typename Mesh::Point upd = ((fn%(pn-p)).normalize() + (fn%(p-pp)).normalize()).normalize();
1902 upd *= ((pn-p).norm()+(p-pp).norm())*0.08;
1913 template <
class Mesh>
1917 if (updatePerHalfedgeBuffers_) {
1918 if (mesh_.has_face_normals())
1919 updatePerHalfedgeBuffers<&DrawMeshT::cachedNormalLookup>();
1921 updatePerHalfedgeBuffers<&DrawMeshT::computedTriMeshNormal>();
1923 updatePerHalfedgeBuffers<&DrawMeshT::computedNormal>();
1925 return perHalfedgeVertexBuf_.empty() ? 0 : &(perHalfedgeVertexBuf_[0]);
1928 template <
class Mesh>
1932 if (updatePerHalfedgeBuffers_) {
1933 if (mesh_.has_face_normals())
1934 updatePerHalfedgeBuffers<&DrawMeshT::cachedNormalLookup>();
1936 updatePerHalfedgeBuffers<&DrawMeshT::computedTriMeshNormal>();
1938 updatePerHalfedgeBuffers<&DrawMeshT::computedNormal>();
1940 return perHalfedgeColorBuf_.empty() ? 0 : &(perHalfedgeColorBuf_[0]);
1946 template <
class Mesh>
1948 unsigned int _offset)
1950 updatePerEdgeBuffers();
1952 pickEdgeBuf_.resize(mesh_.n_edges() * 2);
1957 typename Mesh::ConstEdgeIter e_it(mesh_.edges_sbegin()), e_end(mesh_.edges_end());
1958 for (; e_it!=e_end; ++e_it) {
1962 pickEdgeBuf_[idx] = pickColor;
1963 pickEdgeBuf_[idx+1] = pickColor;
1971 template <
class Mesh>
1975 if (!numTris_ && mesh_.n_faces())
1977 rebuild_ = REBUILD_FULL;
1985 template <
class Mesh>
1990 desc.vertexTemplateFile =
"Picking/vertex.glsl" ;
1991 desc.fragmentTemplateFile =
"Picking/pick_vertices_fs2.glsl" ;
1992 pickEdgeShader_ = ShaderCache::getInstance()->getProgram(&desc,
nullptr);
1995 return pickEdgeShader_ && pickEdgeShader_->isLinked();
1999 template <
class Mesh>
2018 if (!supportsPickingEdges_opt())
2025 pickEdgeShader_->use();
2026 getVertexDeclaration()->activateShaderPipeline(pickEdgeShader_);
2028 pickEdgeShader_->setUniform(
"pickVertexOffset", static_cast<GLint>(_pickOffset) );
2029 pickEdgeShader_->setUniform(
"mWVP", _mvp);
2032 glDrawElements(GL_LINES, static_cast<GLsizei>(mesh_.n_edges() * 2), indexType_, 0);
2035 getVertexDeclaration()->deactivateShaderPipeline(pickEdgeShader_);
2036 pickEdgeShader_->disable();
2050 template <
class Mesh>
2054 if (!numTris_ && mesh_.n_faces())
2056 rebuild_ = REBUILD_FULL;
2060 pickFaceVertexBuf_.resize(3 * numTris_);
2061 pickFaceColBuf_.resize(3 * numTris_);
2063 for (
unsigned int i = 0; i < numTris_; ++i)
2065 unsigned int faceId = (
unsigned int)meshComp_->mapToOriginalFaceID((
int)i);
2068 for (
unsigned int k = 0; k < 3; ++k)
2070 int idx = meshComp_->getIndex(i*3 + k);
2072 typename Mesh::HalfedgeHandle hh = mapToHalfedgeHandle(idx);
2076 vh = mesh_.to_vertex_handle( hh );
2080 int posID = meshComp_->mapToOriginalVertexID(idx, f_id, c_id);
2081 vh = mesh_.vertex_handle(posID);
2084 pickFaceVertexBuf_[i * 3 + k] = mesh_.point( vh );
2086 pickFaceColBuf_[i * 3 + k] = pickColor;
2095 template <
class Mesh>
2099 if (!numTris_ && mesh_.n_faces())
2101 rebuild_ = REBUILD_FULL;
2105 if (meshComp_ && meshComp_->getNumTriangles())
2108 pickFaceTriToFaceMapTBO_.setBufferData(
sizeof(
int) * meshComp_->getNumTriangles(), meshComp_->mapToOriginalFaceIDPtr(), GL_R32I, GL_STATIC_DRAW);
2114 template <
class Mesh>
2117 if (!ACG::Texture::supportsTextureBuffer())
2122 desc.vertexTemplateFile =
"Picking/vertex.glsl";
2123 desc.fragmentTemplateFile =
"Picking/pick_face.glsl";
2124 pickFaceShader_ = ShaderCache::getInstance()->getProgram(&desc,
nullptr);
2127 return pickFaceShader_ && pickFaceShader_->isLinked();
2131 template <
class Mesh>
2167 if (!supportsPickingFaces_opt())
2175 pickFaceShader_->use();
2176 getVertexDeclaration()->activateShaderPipeline(pickFaceShader_);
2178 pickFaceShader_->setUniform(
"pickFaceOffset", static_cast<GLint>(_pickOffset));
2179 pickFaceShader_->setUniform(
"triToFaceMap", 0);
2181 pickFaceTriangleMap_opt()->bind(GL_TEXTURE0);
2183 pickFaceShader_->setUniform(
"mWVP", _mvp);
2186 glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(getNumTris() * 3), getIndexType(), 0);
2189 getVertexDeclaration()->deactivateShaderPipeline(pickFaceShader_);
2190 pickFaceShader_->disable();
2200 template <
class Mesh>
2203 if (!numTris_ && mesh_.n_faces())
2205 rebuild_ = REBUILD_FULL;
2209 pickFaceVertexBuf_.resize(3 * numTris_);
2210 pickAnyFaceColBuf_.resize(3 * numTris_);
2212 for (
unsigned int i = 0; i < numTris_; ++i)
2214 int faceId = meshComp_->mapToOriginalFaceID(i);
2216 for (
unsigned int k = 0; k < 3; ++k)
2218 int idx = meshComp_->getIndex(i*3 + k);
2221 typename Mesh::HalfedgeHandle hh = mapToHalfedgeHandle(idx);
2225 vh = mesh_.to_vertex_handle( hh );
2229 int posID = meshComp_->mapToOriginalVertexID(idx, f_id, c_id);
2230 vh = mesh_.vertex_handle(posID);
2233 pickFaceVertexBuf_[i * 3 + k] = mesh_.point( vh );
2235 pickAnyFaceColBuf_[i * 3 + k] = pickColor;
2241 updatePerEdgeBuffers();
2243 pickAnyEdgeColBuf_.resize(mesh_.n_edges() * 2);
2245 unsigned int idx = 0;
2246 typename Mesh::ConstEdgeIter e_it(mesh_.edges_sbegin()), e_end(mesh_.edges_end());
2247 for (; e_it!=e_end; ++e_it) {
2251 pickAnyEdgeColBuf_[idx] = pickColor;
2252 pickAnyEdgeColBuf_[idx+1] = pickColor;
2262 pickAnyVertexColBuf_.resize( mesh_.n_vertices() );
2263 pickVertBuf_.resize( mesh_.n_vertices() );
2266 typename Mesh::ConstVertexIter v_it(mesh_.vertices_begin()), v_end(mesh_.vertices_end());
2267 for (; v_it!=v_end; ++v_it, ++idx)
2269 pickAnyVertexColBuf_[idx] = _state.
pick_get_name_color(idx + mesh_.n_faces() + mesh_.n_edges());
2270 pickVertBuf_[idx] = mesh_.point(mesh_.vertex_handle(idx));
2276 template <
class Mesh>
2279 updatePickingFaces_opt(_state);
2280 updatePickingEdges_opt(_state);
2281 updatePickingVertices_opt(_state);
2286 template <
class Mesh>
2289 return supportsPickingFaces_opt() && supportsPickingEdges_opt() && supportsPickingVertices_opt();
2293 template <
class Mesh>
2303 if (!supportsPickingAny_opt())
2306 drawPickingFaces_opt(_mvp, _pickOffset);
2310 drawPickingEdges_opt(_mvp, _pickOffset + mesh_.n_faces());
2312 drawPickingVertices_opt(_mvp, _pickOffset + mesh_.n_faces() + mesh_.n_edges());
2315 template <
class Mesh>
2322 if ( !mesh_.get_property_handle(textureIndexProperty,_indexPropertyName) ) {
2323 if ( _indexPropertyName !=
"No Texture Index" )
2324 std::cerr <<
"DrawMeshT: Unable to get per face texture Index property named " << _indexPropertyName << std::endl;
2329 textureIndexPropertyName_ = _indexPropertyName;
2336 rebuild_ |= REBUILD_TOPOLOGY;
2339 template <
class Mesh>
2346 if ( !mesh_.get_property_handle(perFaceTextureCoordinateProperty,_perFaceTextureCoordinatePropertyName) ) {
2347 if ( _perFaceTextureCoordinatePropertyName !=
"No Texture" )
2348 std::cerr <<
"DrawMeshT: Unable to get per face texture coordinate property named " << _perFaceTextureCoordinatePropertyName << std::endl;
2353 perFaceTextureCoordinatePropertyName_ = _perFaceTextureCoordinatePropertyName;
2357 rebuild_ |= REBUILD_GEOMETRY;
2361 template <
class Mesh>
2365 for (
int i = 0; i < meshComp_->getNumSubsets(); ++i)
2367 if (meshComp_->getSubset(i)->id > 0) ++n;
2372 template <
class Mesh>
2378 if ( !mesh_.get_property_handle(perFaceTextureCoordinateProperty, perFaceTextureCoordinatePropertyName_) ) {
2388 template <
class Mesh>
2394 if ( !mesh_.get_property_handle(textureIndexProperty, textureIndexPropertyName_) ) {
2407 template <
class Mesh>
2410 vertexDecl_->clear();
2417 for (
size_t i = 0; i < additionalElements_.size(); ++i)
2419 VertexProperty* prop = &additionalElements_[i];
2422 prop->sourceType_.numElements_ = 0;
2423 prop->sourceType_.pointer_ = 0;
2424 prop->sourceType_.type_ = 0;
2425 prop->sourceType_.shaderInputName_ = 0;
2427 prop->propDataPtr_ = 0;
2428 prop->declElementID_ = -1;
2433 switch (prop->source_)
2435 case PROPERTY_SOURCE_VERTEX: baseProp = mesh_._get_vprop(prop->name_);
break;
2436 case PROPERTY_SOURCE_FACE: baseProp = mesh_._get_fprop(prop->name_);
break;
2437 case PROPERTY_SOURCE_HALFEDGE: baseProp = mesh_._get_hprop(prop->name_);
break;
2438 default: baseProp = mesh_._get_vprop(prop->name_);
break;
2442 prop->propDataPtr_ = getMeshPropertyType(baseProp, &prop->sourceType_.type_, &prop->sourceType_.numElements_);
2445 if (prop->propDataPtr_)
2447 prop->sourceType_.shaderInputName_ = prop->name_.c_str();
2450 prop->destType_ = prop->sourceType_;
2452 prop->destType_.shaderInputName_ = prop->vertexShaderInputName_.c_str();
2454 prop->declElementID_ = int(vertexDecl_->getNumElements());
2456 vertexDecl_->addElement(&prop->destType_);
2459 std::cerr <<
"Could not detect data type of property " << prop->name_ << std::endl;
2464 template <
class Mesh>
2467 vertexDeclEdgeCol_->clear();
2469 vertexDeclEdgeCol_->addElement(GL_FLOAT, 4,
VERTEX_USAGE_COLOR, perEdgeColorBuffer());
2471 vertexDeclHalfedgeCol_->clear();
2473 vertexDeclHalfedgeCol_->addElement(GL_FLOAT, 4,
VERTEX_USAGE_COLOR, perHalfedgeColorBuffer());
2475 vertexDeclHalfedgePos_->clear();
2478 vertexDeclEdgeCol_->setVertexStride(0);
2479 vertexDeclHalfedgeCol_->setVertexStride(0);
2480 vertexDeclHalfedgePos_->setVertexStride(0);
2483 template <
class Mesh>
2490 template<
class Mesh>
2493 int faceId = -1, cornerId = -1;
2497 meshComp_->mapToOriginalVertexID(_vertexId, faceId, cornerId);
2501 typename Mesh::FaceHandle fh = mesh_.face_handle(faceId);
2505 for (
int k = 0; k < cornerId && hh_it.is_valid(); ++k )
2511 return typename Mesh::HalfedgeHandle(-1);
2515 template <
class Mesh>
2519 size_t offset = _vertex * _stride + _elementOffset;
2522 char* dst =
static_cast<char*
>(_dstBuf) + offset;
2525 memcpy(dst, _elementData, _elementSize);
2528 template <
class Mesh>
2532 float f3[3] = {float(_n[0]), float(_n[1]), float(_n[2])};
2534 writeVertexElement(&vertices_[0], _vertex, vertexDecl_->getVertexStride(), 0, 12, f3);
2537 template <
class Mesh>
2541 float f3[3] = {float(_n[0]), float(_n[1]), float(_n[2])};
2543 writeVertexElement(&vertices_[0], _vertex, vertexDecl_->getVertexStride(), offsetNormal_, 12, f3);
2547 template <
class Mesh>
2550 writeVertexElement(&vertices_[0], _vertex, vertexDecl_->getVertexStride(), offsetTexc_, 8, _uv.
data());
2553 template <
class Mesh>
2556 writeVertexElement(&vertices_[0], _vertex, vertexDecl_->getVertexStride(), offsetColor_, 4, &_color);
2560 template <
class Mesh>
2563 const size_t elementSize = VertexDeclaration::getElementSize(_elementDesc);
2565 writeVertexElement(&vertices_[0], _vertex, vertexDecl_->getVertexStride(), _elementDesc->
getByteOffset(), elementSize, _propf.
data());
2570 template <
class Mesh>
2575 for (
size_t i = 0; i < additionalElements_.size(); ++i)
2577 if (additionalElements_[i].name_ == _propertyName)
2579 additionalElements_[i].source_ = _source;
2587 VertexProperty prop;
2589 prop.name_ = _propertyName;
2590 prop.source_ = _source;
2591 prop.vertexShaderInputName_ = _propertyName;
2594 additionalElements_.push_back(prop);
2600 template <
class Mesh>
2603 bool success =
true;
2607 file.open(_vertexShaderFile.c_str(), std::ios_base::in);
2615 file.getline(line, 0xff);
2618 QString strLine = line;
2619 strLine = strLine.simplified();
2622 if (!strLine.startsWith(
"//") && !strLine.startsWith(
"*/"))
2625 if (strLine.startsWith(
"in ") || strLine.contains(
" in "))
2628 int semIdx = strLine.indexOf(
';');
2636 QString strName = strLine;
2637 strName.remove(semIdx, strName.length());
2639 strName = strName.simplified();
2642 int lastWhite = strName.lastIndexOf(
' ');
2646 strName.remove(0, lastWhite);
2648 strName = strName.simplified();
2651 if (strName !=
"inPosition" &&
2652 strName !=
"inTexCoord" &&
2653 strName !=
"inNormal" &&
2654 strName !=
"inColor")
2658 std::string propName = strName.toStdString();
2661 PropertySource src = PROPERTY_SOURCE_VERTEX;
2663 if (strLine.contains(
"flat "))
2666 src = PROPERTY_SOURCE_FACE;
2668 if (!mesh_._get_fprop(propName))
2669 src = PROPERTY_SOURCE_VERTEX;
2672 if (src == PROPERTY_SOURCE_VERTEX)
2674 if (!mesh_._get_vprop(propName))
2675 src = PROPERTY_SOURCE_HALFEDGE;
2679 if (src == PROPERTY_SOURCE_VERTEX)
2681 if ( mesh_._get_hprop(propName) && src == PROPERTY_SOURCE_VERTEX)
2682 src = PROPERTY_SOURCE_HALFEDGE;
2686 if (src == PROPERTY_SOURCE_HALFEDGE && !mesh_._get_hprop(propName))
2688 std::cerr <<
"DrawMesh error - requested property " << propName <<
" does not exist" << std::endl;
2693 addVertexElement(propName, src);
2714 template<
class Mesh>
2718 file.open(_filename);
2722 for (
int attrId = 0; attrId < 3; ++attrId)
2724 for (
size_t i = 0; i < numVerts_; ++i)
2727 const char* v = &vertices_[i * vertexDecl_->getVertexStride()];
2729 const float* pos =
reinterpret_cast<const float*
>((
const void*)(v + offsetPos_));
2730 const float* n =
reinterpret_cast<const float*
>((
const void*)(v + offsetNormal_));
2731 const float* texc =
reinterpret_cast<const float*
>((
const void*)(v + offsetTexc_));
2736 case 0: file <<
"v "<<pos[0]<<
" "<<pos[1]<<
" "<<pos[2]<<
"\n";
break;
2737 case 1: file <<
"vt "<<texc[0]<<
" "<<texc[1]<<
"\n";
break;
2738 case 2: file <<
"vn "<<n[0]<<
" "<<n[1]<<
" "<<n[2]<<
"\n";
break;
2745 for (
size_t i = 0; i < numTris_; ++i)
2748 const int* tri = meshComp_->getIndexBuffer() + i*3;
2750 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";
2759 template <
class Mesh>
2764 unsigned int stride = vertexDecl_->getVertexStride();
2767 unsigned int offset = _vertex * stride;
2770 memcpy(_dst, &vertices_[offset], stride);
2777 template <
class Mesh>
2780 updateFullVBO_ =
true;
2784 template <
class Mesh>
2799 int numVerts = 3 * numTris;
2801 std::vector<char> fullBuf(numVerts * stride);
2804 for (
int i = 0; i < numTris; ++i)
2806 for (
int k = 0; k < 3; ++k)
2808 int idx = i * 3 + k;
2810 readVertexFromVBO(vertexID, &fullBuf[idx * stride]);
2812 if (colorMode_ == 2)
2816 int faceId = meshComp_->mapToOriginalFaceID(i);
2817 unsigned int fcolor = getFaceColor(mesh_.face_handle(faceId));
2820 writeVertexElement(&fullBuf[0], idx, vertexDecl_->getVertexStride(), offsetColor_, 4, &fcolor);
2826 if (!fullBuf.empty())
2827 vboFull_.upload(fullBuf.size(), &fullBuf[0], GL_STATIC_DRAW);
2830 updateFullVBO_ =
false;
void drawPickingFaces_opt(const GLMatrixf &_mvp, size_t _pickOffset)
Optimized rendering of face picking ids with a shader.
GLenum indexType
Index element type.
bool supportsPickingAny_opt()
Check if optimized any picking is supported.
void drawPickingVertices_opt(const GLMatrixf &_mvp, size_t _pickOffset)
Optimized rendering of vertex picking ids with a shader.
virtual size_t n_elements() const =0
Number of elements in property.
Kernel::ConstVertexFaceIter ConstVertexFaceIter
Circulator.
unsigned int getMemoryUsage(bool _printReport=false)
measures the size in bytes of allocated memory. eventually prints a report to std::cout ...
defined by user via VertexElement::shaderInputName_
void updateEdgeHalfedgeVertexDeclarations()
updates per edge and halfedge vertex declarations
void addTexture(const Texture &_t)
adds a texture to stage RenderObjects::numTextures()
Namespace providing different geometric functions concerning angles.
Handle for a halfedge entity.
Kernel::Point Point
Coordinate type.
void readVertexFromVBO(unsigned int _vertex, void *_dst)
Read one vertex from the rendering vbo.
static void bindTexture(GLenum _target, GLuint _buffer)
replaces glBindTexture, supports locking
Class to define the vertex input layout.
ShaderGenDesc shaderDesc
Drawmode and other shader params.
static constexpr bool is_trimesh()
Determine whether this is a PolyMeshT or TriMeshT (This function does not check the per face vertex c...
bool supportsPickingFaces_opt()
Check if optimized face picking is supported.
GLuint vertexBuffer
VBO, IBO ids, ignored if VAO is provided.
const GLenum & depthFunc() const
get glDepthFunc() that is supposed to be active
VERTEX_USAGE usage_
position, normal, shader input ..
Vec4uc pick_get_name_color(size_t _idx)
static void texcoordPointer(GLint _size, GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glTexcoordPointer, supports locking
static void vertexPointer(GLint _size, GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glVertexPointer, supports locking
Scalar * data()
access to Scalar array
bool ACGDLLEXPORT openGLVersionTest(const int _major, const int _minor)
void addTriRenderObjects(IRenderer *_renderer, const RenderObject *_baseObj, std::map< int, GLuint > *_textureMap, bool _nonindexed=false)
adds RenderObjects to a deferred draw call renderer
unsigned int getVertexStride(unsigned int i=0) const
Kernel::ConstFaceHalfedgeIter ConstFaceHalfedgeIter
Circulator.
VectorT< float, 3 > Vec3f
Description of one vertex element.
void addVertexElement(const std::string &_propertyName, PropertySource _source=PROPERTY_SOURCE_VERTEX)
Add custom elements to the vertex layout.
Default property class for any type T.
void createVertexDeclaration()
creates all vertex declarations needed for deferred draw call renderer
void invalidateFullVBO()
the mesh has been changed
static void disableClientState(GLenum _cap)
replaces glDisableClientState, supports locking
const T * data() const
Get pointer to array (does not work for T==bool)
GLuint indexBuffer
Use vertex array object.
static void enableClientState(GLenum _cap)
replaces glEnableClientState, supports locking
const VertexDeclaration * vertexDecl
Defines the vertex buffer layout, ignored if VAO is provided.
unsigned int getByteOffset() const
virtual void addRenderObject(RenderObject *_renderObject)
Callback for the scenegraph nodes, which send new render objects via this function.
static void colorPointer(GLint _size, GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glColorPointer, supports locking
bool supportsPickingVertices_opt()
Check if optimized vertex picking is supported.
VertexDeclaration * getVertexDeclaration()
get vertex declaration of the current vbo layout
Kernel::FaceHalfedgeIter FaceHalfedgeIter
Circulator.
void drawPickingAny_opt(const GLMatrixf &_mvp, size_t _pickOffset)
Optimized rendering of any picking ids with a shader.
void updateFullVBO()
update the full mesh vbo
bool supportsPickingEdges_opt()
Check if optimized face picking is supported.
static void bindBufferARB(GLenum _target, GLuint _buffer)
same function as bindBuffer
int getNumTriangles() const
bool scanVertexShaderForInput(const std::string &_vertexShaderFile)
Scan vertex layout from vertex shader.
const VertexDeclaration * getVertexDeclaration() const
VectorT< unsigned char, 4 > Vec4uc
Interface class between scenegraph and renderer.
void drawPickingEdges_opt(const GLMatrixf &_mvp, size_t _pickOffset)
Optimized rendering of edge picking ids with a shader.
static void bindBuffer(GLenum _target, GLuint _buffer)
replaces glBindBuffer, supports locking
Kernel::VertexHandle VertexHandle
Handle for referencing the corresponding item.
int getIndex(int _i) const
static void normalPointer(GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glNormalPointer, supports locking