max export 4. 폴리곤 정보좀 볼까?

반응형


그래프에서 왼쪽 "Base Objects"를 누르면 Object 타입이 나온다.

이 Object가 무었인지에 대해 이야기 하기 전에 node에 대해 살짝 알아보고 넘어가는게 좋을 듯 싶다.

node란 무었인가?
3ds 맥스 뷰포트에서 오브젝트에 대한 가시적 표현을 node라 부른다.
뷰포트에서 선택되고 이동될 수 있는 것과 노드 사이에는 1대1관계가 존재한다.
node는 max의 장면상에서 오브젝트와 1대1 대응하는 아이템이다.
모든 절차적 오브젝트, 라이트, 카메라, 헬퍼 오브젝트등 뷰포트에나타나는 것은 연결된 node를 가진다.

Object
Object 클래스는 화면에서 보이는 모든 요소들의 기반 클래스이며 INode:GetObjectRef()함수를 통해 얻을 수 있다.
max 표준 프리미티브와 max에 등록된 모든 플러그인 절차적 오브젝트는 오브젝트의 ClassID와 SuperClassID가 주어진다.
ClassID는 단일식별자이며 유니크한 값이다.
SuperClassID는 클래스가 표현하는 오브젝트의 유형을 기술하는 시스템 정의 상수이다.
 
이제 오브젝트에서 폴리곤 정보를 출력해 본다.
폴리곤 정보중에서 정점과 삼각형(한 면)의 인덱스 정보를 살짝 출력해 보자.

1. 노드에서 Object의 reference 정보를 얻어온다.

2. 얻어온 Object reference 정보를 통해 Object 내부 정보를 얻어올 수 있는데
   Object에는 SuperClassIDClassID정보가 있다.
   이 정보들은 각각 SuperClassID()와 ClassID()를 통해 얻어올 수 있다.

3. 이 Object에서 폴리곤에 관한 정보를 얻을 수 있도록 TriObject로 변환시킨다.
    이때, 변환 가능 여부는 CanConvertToType()함수를 사용하면 된다.

4. TriObject를 내부 Mesh정보를 얻을 수 있도록 TriObject내부의 Mesh정보를 이용한다.
    mesh정보를 얻기 위해 TriObject::GetMesh()함수를 사용하면 된다.

5. Mesh::getNumVerts 함수를 사용하면 정점의 갯수를 얻을 수 있다.

6. 실제 정점의 값은 Mesh::getVert()함수를 사용하여 얻을 수 있다.

7. Triangle의 갯수또한 Mesh::getNumFaces를 사용하여 얻을 수 있다.

8 하나의 Triangle는 세개의 인덱스 값을 가지는데 이는 Face::getAllVerts()를 사용하여 얻는다.
  

위의 순서대로 나열된 내용을 아래에 구현하였다.
void MgExport2::ExportObject(INode* node, int treeDepth)
{
 // 해당 노드의 Object의 reference를 얻는다.
 Object* object = node->GetObjectRef();

 // root node는 Object를 가지지 않는다.
 if(NULL != object)
 {
  SClass_ID superClassID  = object->SuperClassID();
  Class_ID  classID  = object->ClassID();

  // class type 출력
  Write(treeDepth, "Object Super Class ID : %X", superClassID);
  Write(treeDepth, "Object Class ID : (%X, %X)", classID.PartA(), classID.PartB());

  // 이 object를 우리가 이해할 수 있는 어떤것으로 변환해야 한다.
  // 여기서는 Class_ID를 사용해서 TriObject로 변환한다.
  if(object->CanConvertToType(triObjectClassID))
  {
   TriObject* triObject = (TriObject*)object->ConvertToType(0, triObjectClassID);
   if(NULL != triObject)
   {
    // mech의 계층 출력
    ExportObject(triObject, treeDepth + 1);

    // TriObject pointer가 원래의 Object를 가르키지 않는다면
    // 새로운 인스턴스란 말이고 이제 그걸 쓰면 된다.
    if(triObject != object)
    {
     // 어떠한 max class에서도 결코 직접적으로 delete를 호출하면 안된다.
     triObject->DeleteMe();
    }
   }
  }
 }
}

void MgExport2::ExportObject(TriObject* triObject, int treeDepth)
{
 // data container을 얻는다.
 Mesh& mesh =triObject->GetMesh();

 // 얼마나 많은 정점들이 있는가?
 int cntVertex = mesh.getNumVerts();
 Write(treeDepth, "Number of Vertices: %i", cntVertex);

 int i = 0;

 // 정점 position들을 출력한다.
 for(i=0; i<cntVertex; i++)
 {
  Point3& vertex = mesh.getVert(i);
  Write(treeDepth, "Vertex[%02i] : (%f,\t%f,\t%f)", i, vertex.x, vertex.y, vertex.z);
 }

 // triangle indices를 출력한다.
 int cntTriangle = mesh.getNumFaces();
 Write(treeDepth, "Number of Triangle : %i", cntTriangle);
 for(i=0; i<cntTriangle; i++)
 {
  // face를 얻는다.
  Face& face = mesh.faces[i];

  // face의 모든 정점들을 얻는다.
  DWORD* indices = face.getAllVerts();

  // Face의 모든 정점들을 출력한다.

 


  Write(treeDepth, "Face[%02i], Vertex IDs : (%u, %u, %u)", i, indices[0], indices[1], indices[2]);
 }
}

간단하게 요약하자면 INode에서 Object를 얻고 Object를 TriObject로 변환해서 삼각형 정보를 얻을 수 있게 한다.
TriObject에서 Mesh정보를 얻고 이 Mesh에 저장되어 있는 정점의 정보와 면을 구축하는 정점 인덱스 정보를 출력한다.


TAGS.

Comments