PolygonalDrawable * ObjIO::createPolygonalDrawable( const ObjObject & object , const ObjGroup & group) { if(group.vis.empty()) return NULL; // TODO: this should test if all consecutive offsets are equal 3. // The current expression could return false positives. if(group.vis.size() / 3 != group.foffs.size()) { qCritical("Ignore polygon with num vertices != 3 (only triangles are supported)."); return NULL; } const bool usesTexCoordIndices(!group.vtis.empty()); const bool usesNormalIndices(!group.vnis.empty()); PolygonalDrawable * drawable = new PolygonalDrawable(); const GLuint size(static_cast<GLuint>(group.vis.size())); for(GLuint i = 0; i < size; ++i) { // add vertex and its new index based on obj index // TODO: make use of vertex reuse! drawable->indices().push_back(i); drawable->vertices().push_back(object.vs[group.vis[i]]); if(usesTexCoordIndices) drawable->texcs().push_back(object.vts[group.vtis[i]]); if(usesNormalIndices) drawable->normals().push_back(object.vns[group.vnis[i]]); } // TODO: support other modes here! drawable->setMode(GL_TRIANGLES); if(!usesNormalIndices) drawable->retrieveNormals(); return drawable; }
void HalfEdgeStructure::setup(PolygonalDrawable & drawable) { if(drawable.indices().isEmpty()) return; const int nTriangles(drawable.indices().size() / 3); m_faces.resize(nTriangles); // TODO: there is strict triangle support only... assert(drawable.indices().size() % 3 == 0); // Map of edges (given by two indices) -> opposite half-edge typedef std::map<std::pair<QVector3D const *, QVector3D const *>, HalfEdge*> t_opp_map; t_opp_map opp; const int he_count = nTriangles * 3; m_halfEdges.resize(he_count); for(int k = 0; k < nTriangles; k++) { m_faces[k].he = &m_halfEdges[k * 3]; for (int i = 0; i < 3; ++i) { const int j(k * 3 + i); m_halfEdges[j].prev = &m_halfEdges[(i == 0) ? j + 2 : j - 1]; m_halfEdges[j].next = &m_halfEdges[(i == 2) ? j - 2 : j + 1]; m_halfEdges[j].opp = NULL; m_halfEdges[j].face = &m_faces[k]; const int l(drawable.indices()[j]); m_halfEdges[j].vertex = &(drawable.vertices()[l]); m_halfEdges[j].normal = drawable.normals()[l]; } // set opposite-pointers for (int i = 0; i < 3; ++i) { const int j(k * 3 + i); QVector3D const * v0 = m_halfEdges[j].vertex; QVector3D const * v1 = m_halfEdges[j].next->vertex; // Check if opposite half-edge is already stored t_opp_map::iterator p = opp.find(t_opp_map::key_type(v0, v1)); if(p == opp.end()) { // no: Add half-edge in opposite direction opp[t_opp_map::key_type(v1, v0)] = &m_halfEdges[j]; } else { // yes: Set opposite-pointers of both half-edges p->second->opp = &m_halfEdges[j]; m_halfEdges[j].opp = p->second; opp.erase(p); } } } calculatePerFaceNormals(); calculatePerVertexNormals(0.f); }