Ejemplo n.º 1
0
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);
}