44#define ACG_DRAW_MESH_TCC
50#include <ACG/GL/gl.hh>
51#include <ACG/Geometry/GPUCacheOptimizer.hh>
52#include <ACG/GL/VertexDeclaration.hh>
53#include <ACG/GL/ShaderCache.hh>
75DrawMeshT<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(); }
271 int getFaceSize(
const int _faceID)
const
273 return mesh_.valence( mesh_.face_handle(_faceID) );
292 if ( mesh_.is_trimesh()) {
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
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();
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)),
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)
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)
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)
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;
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;
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;
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;
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));
894 return getTextureIDofFace(meshComp_->mapToOriginalFaceID(_tri));
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)
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)
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)
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)
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();
1105template <
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]);
1159template <
class Mesh>
1162 delete [] invVertexMap_;
1168template <
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;
1248template <
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_))
1273template <
class Mesh>
1280template <
class Mesh>
1287template <
class Mesh>
1290 if (_v < mesh_.n_vertices())
1293 return invVertexMap_[_v];
1298 return (
unsigned int)-1;
1301template <
class Mesh>
1319 glClientActiveTexture(GL_TEXTURE0);
1331template <
class Mesh>
1345template <
class Mesh>
1359template <
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));
1412template <
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));
1484template <
class Mesh>
1489 if (mesh_.n_edges())
1493 glDrawElements(GL_LINES,
static_cast<GLsizei
>(mesh_.n_edges() * 2), indexType_, 0);
1500template <
class Mesh>
1503 updatePerEdgeBuffersNew();
1504 if (!mesh_.n_edges())
1509 ro.glDrawArrays(GL_LINES, 0,
static_cast<GLsizei
>(mesh_.n_edges() * 2));
1513template <
class Mesh>
1520 glDrawArrays(GL_POINTS, 0,
static_cast<GLsizei
>(numVerts_));
1525template <
class Mesh>
1529 bindBuffersToRenderObject(&ro);
1533 ro.glDrawArrays(GL_POINTS, 0,
static_cast<GLsizei
>(numVerts_));
1541template <
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)
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;
1574template <
class Mesh>
1578 if (updatePerEdgeBuffers_)
1579 updatePerEdgeBuffers();
1580 return perEdgeVertexBuf_.empty() ? 0 : &(perEdgeVertexBuf_[0]);
1583template <
class Mesh>
1587 if (updatePerEdgeBuffers_)
1588 updatePerEdgeBuffers();
1589 return perEdgeColorBuf_.empty() ? 0 : &(perEdgeColorBuf_[0]);
1593template <
class Mesh>
1597 unsigned int idx = 0;
1600 pickVertColBuf_.resize( mesh_.n_vertices() );
1601 pickVertBuf_.resize( mesh_.n_vertices() );
1605 for (; v_it!=v_end; ++v_it, ++idx)
1608 pickVertBuf_[idx] = mesh_.point(mesh_.vertex_handle(idx));
1613template <
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_);
1657template <
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();
1681template <
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)
1751template <
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;
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();
1788template <
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;
1830template <
class Mesh>
1831template<
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;
1848 he_it != he_end; ++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();
1884template<
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;
1913template <
class Mesh>
1917 if (updatePerHalfedgeBuffers_) {
1918 if (mesh_.has_face_normals())
1919 updatePerHalfedgeBuffers<&DrawMeshT::cachedNormalLookup>();
1920 else if (mesh_.is_trimesh())
1921 updatePerHalfedgeBuffers<&DrawMeshT::computedTriMeshNormal>();
1923 updatePerHalfedgeBuffers<&DrawMeshT::computedNormal>();
1925 return perHalfedgeVertexBuf_.empty() ? 0 : &(perHalfedgeVertexBuf_[0]);
1928template <
class Mesh>
1932 if (updatePerHalfedgeBuffers_) {
1933 if (mesh_.has_face_normals())
1934 updatePerHalfedgeBuffers<&DrawMeshT::cachedNormalLookup>();
1935 else if (mesh_.is_trimesh())
1936 updatePerHalfedgeBuffers<&DrawMeshT::computedTriMeshNormal>();
1938 updatePerHalfedgeBuffers<&DrawMeshT::computedNormal>();
1940 return perHalfedgeColorBuf_.empty() ? 0 : &(perHalfedgeColorBuf_[0]);
1946template <
class Mesh>
1948 unsigned int _offset)
1950 updatePerEdgeBuffers();
1952 pickEdgeBuf_.resize(mesh_.n_edges() * 2);
1958 for (; e_it!=e_end; ++e_it) {
1962 pickEdgeBuf_[idx] = pickColor;
1963 pickEdgeBuf_[idx+1] = pickColor;
1971template <
class Mesh>
1975 if (!numTris_ && mesh_.n_faces())
1977 rebuild_ = REBUILD_FULL;
1985template <
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();
1999template <
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();
2050template <
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);
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;
2095template <
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);
2114template <
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();
2131template <
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();
2200template <
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);
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;
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() );
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));
2276template <
class Mesh>
2279 updatePickingFaces_opt(_state);
2280 updatePickingEdges_opt(_state);
2281 updatePickingVertices_opt(_state);
2286template <
class Mesh>
2289 return supportsPickingFaces_opt() && supportsPickingEdges_opt() && supportsPickingVertices_opt();
2293template <
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());
2315template <
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;
2339template <
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;
2361template <
class Mesh>
2365 for (
int i = 0; i < meshComp_->getNumSubsets(); ++i)
2367 if (meshComp_->getSubset(i)->id > 0) ++n;
2372template <
class Mesh>
2378 if ( !mesh_.get_property_handle(perFaceTextureCoordinateProperty, perFaceTextureCoordinatePropertyName_) ) {
2388template <
class Mesh>
2394 if ( !mesh_.get_property_handle(textureIndexProperty, textureIndexPropertyName_) ) {
2407template <
class Mesh>
2410 vertexDecl_->clear();
2417 for (
size_t i = 0; i < additionalElements_.size(); ++i)
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;
2456 vertexDecl_->addElement(&prop->
destType_);
2459 std::cerr <<
"Could not detect data type of property " << prop->
name_ << std::endl;
2464template <
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);
2483template <
class Mesh>
2493 int faceId = -1, cornerId = -1;
2497 meshComp_->mapToOriginalVertexID(_vertexId, faceId, cornerId);
2505 for (
int k = 0; k < cornerId && hh_it.is_valid(); ++k )
2515template <
class Mesh>
2519 size_t offset = _vertex * _stride + _elementOffset;
2522 char* dst =
static_cast<char*
>(_dstBuf) + offset;
2525 memcpy(dst, _elementData, _elementSize);
2528template <
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);
2537template <
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);
2547template <
class Mesh>
2550 writeVertexElement(&vertices_[0], _vertex, vertexDecl_->getVertexStride(), offsetTexc_, 8, _uv.
data());
2553template <
class Mesh>
2556 writeVertexElement(&vertices_[0], _vertex, vertexDecl_->getVertexStride(), offsetColor_, 4, &_color);
2560template <
class Mesh>
2563 const size_t elementSize = VertexDeclaration::getElementSize(_elementDesc);
2565 writeVertexElement(&vertices_[0], _vertex, vertexDecl_->getVertexStride(), _elementDesc->getByteOffset(), elementSize, _propf.
data());
2570template <
class Mesh>
2575 for (
size_t i = 0; i < additionalElements_.size(); ++i)
2577 if (additionalElements_[i].name_ == _propertyName)
2579 additionalElements_[i].source_ = _source;
2589 prop.
name_ = _propertyName;
2590 prop.source_ = _source;
2594 additionalElements_.push_back(prop);
2600template <
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);
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";
2759template <
class Mesh>
2764 unsigned int stride = vertexDecl_->getVertexStride();
2767 unsigned int offset = _vertex * stride;
2770 memcpy(_dst, &vertices_[offset], stride);
2777template <
class Mesh>
2780 updateFullVBO_ =
true;
2784template <
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;
VertexDeclaration * getVertexDeclaration()
get vertex declaration of the current vbo layout
void createVertexDeclaration()
creates all vertex declarations needed for deferred draw call renderer
void drawPickingFaces_opt(const GLMatrixf &_mvp, size_t _pickOffset)
Optimized rendering of face picking ids with a shader.
void drawPickingEdges_opt(const GLMatrixf &_mvp, size_t _pickOffset)
Optimized rendering of edge picking ids with a shader.
void drawPickingAny_opt(const GLMatrixf &_mvp, size_t _pickOffset)
Optimized rendering of any picking ids with a shader.
void addVertexElement(const std::string &_propertyName, PropertySource _source=PROPERTY_SOURCE_VERTEX)
Add custom elements to the vertex layout.
unsigned int getMemoryUsage(bool _printReport=false)
measures the size in bytes of allocated memory. eventually prints a report to std::cout
void invalidateFullVBO()
the mesh has been changed
bool supportsPickingAny_opt()
Check if optimized any picking is supported.
bool supportsPickingVertices_opt()
Check if optimized vertex picking is supported.
void readVertexFromVBO(unsigned int _vertex, void *_dst)
Read one vertex from the rendering vbo.
bool supportsPickingEdges_opt()
Check if optimized face picking is supported.
bool supportsPickingFaces_opt()
Check if optimized face picking is supported.
void addTriRenderObjects(IRenderer *_renderer, const RenderObject *_baseObj, std::map< int, GLuint > *_textureMap, bool _nonindexed=false)
adds RenderObjects to a deferred draw call renderer
void updateFullVBO()
update the full mesh vbo
void drawPickingVertices_opt(const GLMatrixf &_mvp, size_t _pickOffset)
Optimized rendering of vertex picking ids with a shader.
bool scanVertexShaderForInput(const std::string &_vertexShaderFile)
Scan vertex layout from vertex shader.
void updateEdgeHalfedgeVertexDeclarations()
updates per edge and halfedge vertex declarations
static void disableClientState(GLenum _cap)
replaces glDisableClientState, supports locking
static void colorPointer(GLint _size, GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glColorPointer, supports locking
static void vertexPointer(GLint _size, GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glVertexPointer, supports locking
Vec4uc pick_get_name_color(size_t _idx)
static void bindBufferARB(GLenum _target, GLuint _buffer)
same function as bindBuffer
static void bindTexture(GLenum _target, GLuint _buffer)
replaces glBindTexture, supports locking
static void normalPointer(GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glNormalPointer, supports locking
static void enableClientState(GLenum _cap)
replaces glEnableClientState, supports locking
static void texcoordPointer(GLint _size, GLenum _type, GLsizei _stride, const GLvoid *_pointer)
replaces glTexcoordPointer, supports locking
const GLenum & depthFunc() const
get glDepthFunc() that is supposed to be active
static void bindBuffer(GLenum _target, GLuint _buffer)
replaces glBindBuffer, supports locking
virtual void addRenderObject(RenderObject *_renderObject)
Callback for the scenegraph nodes, which send new render objects via this function.
int getNumTriangles() const
int getIndex(int _i) const
const VertexDeclaration * getVertexDeclaration() const
Class to define the vertex input layout.
unsigned int getVertexStride(unsigned int i=0) const
virtual size_t n_elements() const =0
Number of elements in property.
Kernel::VertexHandle VertexHandle
Handle for referencing the corresponding item.
Kernel::ConstFaceHalfedgeIter ConstFaceHalfedgeIter
Circulator.
Kernel::ConstVertexFaceIter ConstVertexFaceIter
Circulator.
Kernel::ConstHalfedgeIter ConstHalfedgeIter
Scalar type.
Kernel::FaceHandle FaceHandle
Scalar type.
Kernel::HalfedgeHandle HalfedgeHandle
Scalar type.
Kernel::ConstEdgeIter ConstEdgeIter
Scalar type.
Kernel::ConstVertexIter ConstVertexIter
Scalar type.
Kernel::FaceHalfedgeIter FaceHalfedgeIter
Circulator.
Kernel::Point Point
Coordinate type.
Default property class for any type T.
const T * data() const
Get pointer to array (does not work for T==bool)
Scalar * data()
access to Scalar array
Namespace providing different geometric functions concerning angles.
bool ACGDLLEXPORT openGLVersionTest(const int _major, const int _minor)
VectorT< float, 3 > Vec3f
@ VERTEX_USAGE_NORMAL
"inNormal"
@ VERTEX_USAGE_COLOR
"inColor"
@ VERTEX_USAGE_POSITION
"inPosition"
@ VERTEX_USAGE_TEXCOORD
"inTexCoord"
@ VERTEX_USAGE_SHADER_INPUT
defined by user via VertexElement::shaderInputName_
VectorT< unsigned char, 4 > Vec4uc
const void * propDataPtr_
memory address of property data
VertexElement sourceType_
property type as stored in openmesh
std::string vertexShaderInputName_
input name id in vertex shader
VertexElement destType_
property type as stored in vbo
std::string name_
property name in openmesh
int declElementID_
element id in vertex declaration
Interface class between scenegraph and renderer.
ShaderGenDesc shaderDesc
Drawmode and other shader params.
const VertexDeclaration * vertexDecl
Defines the vertex buffer layout, ignored if VAO is provided.
void addTexture(const Texture &_t)
adds a texture to stage RenderObjects::numTextures()
GLuint indexBuffer
Use vertex array object.
GLuint vertexBuffer
VBO, IBO ids, ignored if VAO is provided.
GLenum indexType
Index element type.
Description of one vertex element.
unsigned int numElements_
how many elements of type_
const void * pointer_
Offset in bytes to the first occurrence of this element in vertex buffer; Or address to vertex data i...
VERTEX_USAGE usage_
position, normal, shader input ..
unsigned int type_
GL_FLOAT, GL_UNSIGNED_BYTE, GL_INT, ...
const char * shaderInputName_
set shader input name, if usage_ = VERTEX_USAGE_USER_DEFINED otherwise this is set automatically,...
Handle for a halfedge entity.