⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wmletmanifoldmesh.cpp

📁 3D Game Engine Design Source Code非常棒
💻 CPP
字号:
// Magic Software, Inc.
// http://www.magic-software.com
// http://www.wild-magic.com
// Copyright (c) 2003.  All Rights Reserved
//
// The Wild Magic Library (WML) source code is supplied under the terms of
// the license agreement http://www.magic-software.com/License/WildMagic.pdf
// and may not be copied or disclosed except in accordance with the terms of
// that agreement.

#include "WmlETManifoldMesh.h"
using namespace Wml;

#include <fstream>
using namespace std;

//----------------------------------------------------------------------------
ETManifoldMesh::ETManifoldMesh (ECreator oECreator, TCreator oTCreator)
{
    m_oECreator = ( oECreator ? oECreator : CreateEdge );
    m_oTCreator = ( oTCreator ? oTCreator : CreateTriangle );
}
//----------------------------------------------------------------------------
ETManifoldMesh::~ETManifoldMesh ()
{
    EMap::iterator pkEIter;
    for (pkEIter = m_kEMap.begin(); pkEIter != m_kEMap.end(); pkEIter++)
        delete pkEIter->second;

    TMap::iterator pkTIter;
    for (pkTIter = m_kTMap.begin(); pkTIter != m_kTMap.end(); pkTIter++)
        delete pkTIter->second;
}
//----------------------------------------------------------------------------
ETManifoldMesh::EPtr ETManifoldMesh::CreateEdge (int iV0, int iV1)
{
    return new Edge(iV0,iV1);
}
//----------------------------------------------------------------------------
ETManifoldMesh::TPtr ETManifoldMesh::CreateTriangle (int iV0, int iV1,
    int iV2)
{
    return new Triangle(iV0,iV1,iV2);
}
//----------------------------------------------------------------------------
ETManifoldMesh::TPtr ETManifoldMesh::InsertTriangle (int iV0, int iV1,
    int iV2)
{
    TriangleKey kTKey(iV0,iV1,iV2);
    TMapIterator pkTIter = m_kTMap.find(kTKey);
    if ( pkTIter != m_kTMap.end() )
    {
        // triangle already exists
        return NULL;
    }

    // add new triangle
    TPtr pkT = m_oTCreator(iV0,iV1,iV2);
    m_kTMap[kTKey] = pkT;

    // add edges to mesh
    for (int i0 = 2, i1 = 0; i1 < 3; i0 = i1++)
    {
        EdgeKey kEKey(pkT->V[i0],pkT->V[i1]);
        EPtr pkE;
        EMapIterator pkEIter = m_kEMap.find(kEKey);
        if ( pkEIter == m_kEMap.end() )
        {
            // first time edge encountered
            pkE = m_oECreator(pkT->V[i0],pkT->V[i1]);
            m_kEMap[kEKey] = pkE;

            // update edge and triangle
            pkE->T[0] = pkT;
            pkT->E[i0] = pkE;
        }
        else
        {
            // second time edge encountered
            pkE = pkEIter->second;
            assert( pkE );

            // update edge
            if ( pkE->T[1] )
            {
                assert( false );  // mesh must be manifold
                return NULL;
            }
            pkE->T[1] = pkT;

            // update adjacent triangles
            TPtr pkAdj = pkE->T[0];
            assert( pkAdj );
            for (int i = 0; i < 3; i++)
            {
                if ( pkAdj->E[i] == pkE )
                {
                    pkAdj->T[i] = pkT;
                    break;
                }
            }

            // update triangle
            pkT->E[i0] = pkE;
            pkT->T[i0] = pkAdj;
        }
    }

    return pkT;
}
//----------------------------------------------------------------------------
bool ETManifoldMesh::RemoveTriangle (int iV0, int iV1, int iV2)
{
    TriangleKey kTKey(iV0,iV1,iV2);
    TMapIterator pkTIter = m_kTMap.find(kTKey);
    if ( pkTIter == m_kTMap.end() )
    {
        // triangle does not exist
        return false;
    }

    TPtr pkT = pkTIter->second;
    for (int i = 0; i < 3; i++)
    {
        // inform edges you are going away
        Edge* pkE = pkT->E[i];
        assert( pkE );
        if ( pkE->T[0] == pkT )
        {
            // one-triangle edges always have pointer in slot zero
            pkE->T[0] = pkE->T[1];
            pkE->T[1] = NULL;
        }
        else if ( pkE->T[1] == pkT )
        {
            pkE->T[1] = NULL;
        }
        else
        {
            assert( false );
            return false;
        }

        // remove edge if you had the last reference to it
        if ( !pkE->T[0] && !pkE->T[1] )
        {
            EdgeKey kEKey(pkE->V[0],pkE->V[1]);
            m_kEMap.erase(kEKey);
            delete pkE;
        }

        // inform adjacent triangles you are going away
        TPtr pkA = pkT->T[i];
        if ( pkA )
        {
            for (int j = 0; j < 3; j++)
            {
                if ( pkA->T[j] == pkT )
                {
                    pkA->T[j] = NULL;
                    break;
                }
            }
        }
    }

    m_kTMap.erase(kTKey);
    delete pkT;
    return true;
}
//----------------------------------------------------------------------------
bool ETManifoldMesh::IsClosed () const
{
    EMapCIterator pkEIter;
    for (pkEIter = m_kEMap.begin(); pkEIter != m_kEMap.end(); pkEIter++)
    {
        const Edge* pkE = pkEIter->second;
        if ( !pkE->T[0] || !pkE->T[1] )
            return false;
    }
    return true;
}
//----------------------------------------------------------------------------
void ETManifoldMesh::Print (const char* acFilename)
{
    ofstream kOStr(acFilename);
    if ( !kOStr )
        return;

    // assign unique indices to the edges
    map<Edge*,int> kEIndex;
    kEIndex[0] = 0;
    int i = 1;
    EMapIterator pkEIter;
    for (pkEIter = m_kEMap.begin(); pkEIter != m_kEMap.end(); pkEIter++)
    {
        if ( pkEIter->second )
            kEIndex[pkEIter->second] = i++;
    }

    // assign unique indices to the triangles
    map<TPtr,int> kTIndex;
    kTIndex[0] = 0;
    i = 1;
    TMapIterator pkTIter;
    for (pkTIter = m_kTMap.begin(); pkTIter != m_kTMap.end(); pkTIter++)
    {
        if ( pkTIter->second )
            kTIndex[pkTIter->second] = i++;
    }

    // print edges
    kOStr << "edge quantity = " << (int)m_kEMap.size() << endl;
    for (pkEIter = m_kEMap.begin(); pkEIter != m_kEMap.end(); pkEIter++)
    {
        const Edge& rkE = *pkEIter->second;
        kOStr << 'e' << kEIndex[pkEIter->second] << " <"
              << 'v' << rkE.V[0] << ",v" << rkE.V[1] << "; ";
        if ( rkE.T[0] )
            kOStr << 't' << kTIndex[rkE.T[0]];
        else
            kOStr << '*';
        kOStr << ',';
        if ( rkE.T[1] )
            kOStr << 't' << kTIndex[rkE.T[1]];
        else
            kOStr << '*';
        kOStr << '>' << endl;
    }
    kOStr << endl;

    // print triangles
    kOStr << "triangle quantity = " << (int)m_kTMap.size() << endl;
    for (pkTIter = m_kTMap.begin(); pkTIter != m_kTMap.end(); pkTIter++)
    {
        const Triangle& rkT = *pkTIter->second;
        kOStr << 't' << kTIndex[pkTIter->second] << " <"
              << 'v' << rkT.V[0] << ",v" << rkT.V[1] << ",v" << rkT.V[2]
              << "; ";
        if ( rkT.E[0] )
            kOStr << 'e' << kEIndex[rkT.E[0]];
        else
            kOStr << '*';
        kOStr << ',';
        if ( rkT.E[1] )
            kOStr << 'e' << kEIndex[rkT.E[1]];
        else
            kOStr << '*';
        kOStr << ',';
        if ( rkT.E[2] )
            kOStr << 'e' << kEIndex[rkT.E[2]];
        else
            kOStr << '*';
        kOStr << "; ";

        if ( rkT.T[0] )
            kOStr << 't' << kTIndex[rkT.T[0]];
        else
            kOStr << '*';
        kOStr << ',';
        if ( rkT.T[1] )
            kOStr << 't' << kTIndex[rkT.T[1]];
        else
            kOStr << '*';
        kOStr << ',';
        if ( rkT.T[2] )
            kOStr << 't' << kTIndex[rkT.T[2]];
        else
            kOStr << '*';
        kOStr << '>' << endl;
    }
    kOStr << endl;
}
//----------------------------------------------------------------------------
ETManifoldMesh::Edge::Edge (int iV0, int iV1)
{
    V[0] = iV0;
    V[1] = iV1;
    T[0] = NULL;
    T[1] = NULL;
}
//----------------------------------------------------------------------------
ETManifoldMesh::Edge::~Edge ()
{
}
//----------------------------------------------------------------------------
ETManifoldMesh::Triangle::Triangle (int iV0, int iV1, int iV2)
{
    V[0] = iV0;
    V[1] = iV1;
    V[2] = iV2;

    for (int i = 0; i < 3; i++)
    {
        E[i] = NULL;
        T[i] = NULL;
    }
}
//----------------------------------------------------------------------------
ETManifoldMesh::Triangle::~Triangle ()
{
}
//----------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -