Node Traversal

3DSMAX의 모델 구조는 씬 노드로 이뤄져 있다. 이번 장에서는 씬 노드를 순회 하면서 노드의 이름을 출력해 문자열로 출력해 본다.

class maxPluginTest : public SceneExport {

    ......

    ......

    ......

    private:

        //씬노드를 순회하는 재귀 호출 메쏘드

        void Export(INode* pNode, int iTreeDepth = 0);

        FILE* m_pFile;

        //m_pFile 저장 시작

        bool BeginWriting(const char* pPath);

        //m_pFile 저장 완료

        void EndWriting();

        //iTreeDepth의 깊이를 indent로 전달하여 문자열로 m_pFile에 저장한다.

        void Write(int indent, const char* pMsg, ...);

 

};

DoExport()에서 간단하게 테스트 하기 위해 기본의 실행문은 주석 처리한다.
Export() 명령에 의해 재귀 호출 실행 되면서 노드의 이름을 저장한다.

int    maxPluginTest::DoExport(const TCHAR *name,ExpInterface *ei,Interface *i, BOOL suppressPrompts, DWORD options)

{

    //TODO: Implement the actual file Export here and

    //        return TRUE If the file is exported properly

/*

    if(!suppressPrompts)

        DialogBoxParam(hInstance,

                MAKEINTRESOURCE(IDD_PANEL),

                GetActiveWindow(),

                maxPluginTestOptionsDlgProc, (LPARAM)this);

*/

    if (BeginWriting(name))

    {

        // Interface* can also be accessed by GetCOREInterface()

        INode* pRootNode = i->GetRootNode();

 

        //Export tree.

        Export(pRootNode);

 

        EndWriting();

 

        return TRUE; // We have successfully exported to our file!

    }

 

    // If we are here, something in the export failed.

    return FALSE;

}

 

 

void maxPluginTest::Export(INode* pNode, int iTreeDepth /* = 0 */)

{

    // First step to export: What are we exporting?

    // Here we are going to export the basic scene tree,

    // identifying each node by name.

 

    MCHAR* pNodeName = pNode->GetName();

    int nChildren = pNode->NumberOfChildren();

 

    // Write out this node as [NodeName] : XX Children

    Write(iTreeDepth, "[%s] : %i children", pNodeName, nChildren);

 

    // Recursively call the children

    iTreeDepth++;

    for (int i = 0; i < nChildren; i++)

    {

        Export(pNode->GetChildNode(i), iTreeDepth);

    }

}

 

bool maxPluginTest::BeginWriting(const char *pPath)

{

    // Check we are not currently writing

    DbgAssert(m_pFile == NULL);

 

    errno_t lErr = fopen_s(&m_pFile, pPath, "w");

    return ( lErr == 0 );

}

 

void maxPluginTest::EndWriting()

{

    DbgAssert(m_pFile != NULL);

 

    fclose(m_pFile);

    m_pFile = NULL;

}

 

void maxPluginTest::Write(int indent, const char* pMsg, ...)

{

    DbgAssert(m_pFile != NULL);

 

    // first, write in the indent

    for (int i = 0; i < indent; i++) fprintf_s(m_pFile, "\t");

 

    // Write the message, passing in our variable

    // parameters to a function that wraps printf

    va_list vargs;

    va_start(vargs, pMsg);

    vfprintf_s(m_pFile, pMsg, vargs);

    va_end(vargs);

 

    // Finish the line

    fprintf_s(m_pFile, "\n");

}

 

박스를 하나 익스포트 한후 실행 결과

[Scene Root] : 1 children
    [Box01] : 0 children