Click here to Skip to main content
15,884,298 members
Articles / Desktop Programming / MFC

Achieving PostScript and Wmf outputs for OpenGL

Rate me:
Please Sign up or sign in to vote.
4.96/5 (42 votes)
9 Jun 2003 400.2K   10.7K   137  
This article explains how to generate resolution independent versions of 3D meshes rendered by OpenGL/MFC programs, i.e. how to export the rendering results to vectorial formats such as encapsulated postscript (EPS) and Windows enhanced metafile (EMF) formats. The main goal consists of being able to
//********************************************
// ParserVrml.cpp
// class CParserVrml
//********************************************
// alliez@usc.edu
// Created : 02/04/98
// Modified : 02/04/98
//********************************************

#include "stdafx.h"
#include "Base3d.h"
#include "ParserVrml.h"

//********************************************
// Constructor
//********************************************
CParserVrml::CParserVrml()
{
	m_pBuffer = NULL;
	m_pBufferWord[0] = '\0';
	m_pBufferLine[0] = '\0';
	m_IndexBuffer = 0;
}

//********************************************
// Destructor
//********************************************
CParserVrml::~CParserVrml()
{
	Free();
}

//********************************************
// Destructor
//********************************************
void CParserVrml::Free(void)
{
	if(m_pBuffer != NULL)
		delete [] m_pBuffer;
	m_IndexBuffer = 0;
}

//********************************************
// Run
//********************************************
int CParserVrml::Run(char *filename,
										 CSceneGraph3d *pSceneGraph)
{
	TRACE("\n");
	TRACE("Start vrml parser\n");
	TRACE("  file : %s\n",filename);

	// Free
	TRACE("  free...");
	Free();
	TRACE("ok\n");

	// ReadFile
	if(!ReadFile(filename))
		return 0;

	// CheckVersion
	if(!CheckVersion())
		return 0;

	CountDef();
	CountMesh();

	while(OffsetToStringBeginLine("DEF"))
		ReadMesh(pSceneGraph);

	TRACE("End vrml parser\n");
	TRACE("\n");
	return 1;
}


//********************************************
// ReadFile
//********************************************
int CParserVrml::ReadFile(char *filename)
{
	m_FileName = filename;

	CFile file;
	CFileException ex;

	// Opening
	TRACE("  opening...");
	if(!file.Open(filename, CFile::modeRead | CFile::typeBinary,&ex))
	{
		#ifdef _DEBUG
		  afxDump << "File could not be opened " << ex.m_cause << "\n";
		#endif
		TRACE("unable to open file for reading\n");
		return 0;
	}
	TRACE("ok\n");

	// Size file
	m_SizeFile = file.GetLength();
	TRACE("  length : %d bytes\n",m_SizeFile);

	// Alloc
	TRACE("  alloc...");
	m_pBuffer = new char[m_SizeFile];
	if(m_pBuffer == NULL)
	{
		TRACE("insuffisant memory\n");
		return 0;
	}
	TRACE("ok\n");

	// Reading
	TRACE("  reading...");
	TRY
	{
		file.Read(m_pBuffer,m_SizeFile);
	}
	CATCH(CFileException, e)
	{
		#ifdef _DEBUG
				afxDump << "Error during reading " << e->m_cause << "\n";
		#endif
		TRACE("error during reading\n");
		file.Close();
		return 0;
	}
	END_CATCH
	TRACE("ok\n");

	// Closing
	file.Close();

	return 1;
}

//********************************************
// ReadLine
// eol : '\n'
// eos : '\0'
//********************************************
int CParserVrml::ReadLine()
{
	m_pBufferLine[0] = '\0';
	int i=0;
	do
		m_pBufferLine[i++] = m_pBuffer[m_IndexBuffer++];
	while(m_pBuffer[m_IndexBuffer-1] != '\n' && 
		    i < MAX_LINE_VRML &&
				m_IndexBuffer < m_SizeFile);

	m_pBufferLine[i-1] = '\0';

	//TRACE("  line : %s\n",m_pBufferLine);

	return 1;
}


//********************************************
// ReadLine
// eol : '\n'
// eos : '\0'
//********************************************
int CParserVrml::ReadWord()
{
	m_pBufferWord[0] = '\0';
	int i=0;

	// Jump to next valid character
	while((m_pBuffer[m_IndexBuffer] == '\n' || 
		     m_pBuffer[m_IndexBuffer] == '\t' || 
		     m_pBuffer[m_IndexBuffer] == '\r' || 
		     m_pBuffer[m_IndexBuffer] == ' ') &&
				 m_IndexBuffer < m_SizeFile)
		m_IndexBuffer++;

	// Check eof
	if(m_IndexBuffer >= m_SizeFile)
		return 0;

	do
		m_pBufferWord[i++] = m_pBuffer[m_IndexBuffer++];
	while(m_pBuffer[m_IndexBuffer-1] != '\n' && 
		    m_pBuffer[m_IndexBuffer-1] != '\t' && 
		    m_pBuffer[m_IndexBuffer-1] != '\r' && 
		    m_pBuffer[m_IndexBuffer-1] != ' ' && 
		    i < MAX_WORD_VRML &&
				m_IndexBuffer < m_SizeFile);

	m_pBufferWord[i-1] = '\0';

	//TRACE("  word : %s\n",m_pBufferWord);

	return 1;
}




//********************************************
// CheckVersion
//********************************************
int CParserVrml::CheckVersion()
{
	ReadLine();
	TRACE("  check version (vrml 2.0)...");
	if(strstr(m_pBufferLine,"#VRML V2.0") != NULL)
	{
		TRACE("ok\n");
		return 1;
	}
	TRACE("invalid\n");
	return 0;
}



//********************************************
// CountDef
//********************************************
void CParserVrml::CountDef(void)
{
	int tmp = m_IndexBuffer;
	int nb = 0;
	while(m_IndexBuffer < m_SizeFile)
	{
		ReadLine();
		if(strncmp(m_pBufferLine,"DEF",3) == 0)
			nb++;
	}
	TRACE("  %d objects\n",nb);
	m_IndexBuffer = tmp;
}

//********************************************
// CountMesh
//********************************************
int CParserVrml::CountMesh(void)
{
	int tmp = m_IndexBuffer;
	int nb = 0;
	while(m_IndexBuffer < m_SizeFile)
	{
		ReadLine();
		if(strstr(m_pBufferLine,"IndexedFaceSet") != NULL)
			nb++;
	}
	TRACE("  %d meshes\n",nb);
	m_IndexBuffer = tmp;
	return nb;
}

//********************************************
// OffsetToStringBeginLine
//********************************************
int CParserVrml::OffsetToStringBeginLine(char *string)
{
	while(m_IndexBuffer < m_SizeFile)
	{
		ReadLine();
		if(strncmp(m_pBufferLine,string,strlen(string)) == 0)
		{
			m_IndexBuffer -= strlen(m_pBufferLine)+1;
			/*
			TRACE("  begin line : %c%c%c%c%c...\n",m_pBuffer[m_IndexBuffer],
				                                     m_pBuffer[m_IndexBuffer+1],
				                                     m_pBuffer[m_IndexBuffer+2],
				                                     m_pBuffer[m_IndexBuffer+3],
																				     m_pBuffer[m_IndexBuffer+4]);*/
			return 1;
		}
	}
	return 0;
}

//********************************************
// OffsetToString
//********************************************
int CParserVrml::OffsetToString(char *string)
{
	while(m_IndexBuffer < m_SizeFile)
	{
		ReadLine();
		char *adr = strstr(m_pBufferLine,string);
		if(strstr(m_pBufferLine,string) != NULL)
		{
			m_IndexBuffer = m_IndexBuffer - strlen(m_pBufferLine) - 1 + (adr-m_pBufferLine);
			ASSERT(m_IndexBuffer >= 0);
			/*
			TRACE("  offset to string : %c%c%c%c%c... IndexBuffer : %d\n",m_pBuffer[m_IndexBuffer],
 				                                           m_pBuffer[m_IndexBuffer+1], 
				                                           m_pBuffer[m_IndexBuffer+2],
				                                           m_pBuffer[m_IndexBuffer+3],
																				           m_pBuffer[m_IndexBuffer+4],m_IndexBuffer);*/

			return 1;
		}
	}
	return 0;
}

//********************************************
// OffsetToString
//********************************************
int CParserVrml::OffsetToStringBefore(char *string,
																			char *before)
{
	while(m_IndexBuffer < m_SizeFile)
	{
		ReadLine();
		char *adr = strstr(m_pBufferLine,string);
		if(strstr(m_pBufferLine,before) != NULL)
			return 0;
		if(strstr(m_pBufferLine,string) != NULL)
		{
			m_IndexBuffer = m_IndexBuffer - strlen(m_pBufferLine) - 1 + (adr-m_pBufferLine);
			ASSERT(m_IndexBuffer >= 0);
			/*
			TRACE("  offset to string : %c%c%c%c%c... IndexBuffer : %d\n",m_pBuffer[m_IndexBuffer],
 				                                           m_pBuffer[m_IndexBuffer+1], 
				                                           m_pBuffer[m_IndexBuffer+2],
				                                           m_pBuffer[m_IndexBuffer+3],
																				           m_pBuffer[m_IndexBuffer+4],m_IndexBuffer);*/

			return 1;
		}
	}
	return 0;
}

//********************************************
// CheckMesh
//********************************************
int CParserVrml::CheckMesh()
{
	// Find a possible mesh
	TRACE("  check mesh...");
	OffsetToStringBeginLine("DEF");
	int tmp = m_IndexBuffer;
	ReadLine();
	if(strstr(m_pBufferLine,"DEF") != NULL && 
	   strstr(m_pBufferLine,"Transform") != NULL)
	{
		m_IndexBuffer = tmp;
		if(OffsetToString("Transform") &&
		   OffsetToString("Material") &&
		   OffsetToString("IndexedFaceSet"))
		{
			m_IndexBuffer = tmp;
			TRACE("ok\n");
			return 1;
		}
	}
	//m_IndexBuffer = tmp;
	TRACE("not a mesh\n");
	return 0;
}

//********************************************
// ReadMesh
//********************************************
int CParserVrml::ReadMesh(CSceneGraph3d *pSceneGraph)
{
	// Check
	if(!CheckMesh())
		return 0;

	int tmp = m_IndexBuffer;
	ReadLine();
	ASSERT(strstr(m_pBufferLine,"DEF") != NULL);
	ASSERT(strstr(m_pBufferLine,"Transform") != NULL);
	// DEF [name] Transform {
	if(sscanf(m_pBufferLine,"DEF %s Transform",m_pBufferWord) != 1)
	{
		TRACE("  invalid syntax (BufferLine : %s BufferWord : %s\n",m_pBufferLine,m_pBufferWord);
		return 0;
	}

	TRACE("  start reading mesh %s\n",m_pBufferWord);

	m_IndexBuffer = tmp;

	int IndexTexture = -1;

	// Transform
	//********************************************
	// Syntax :
	// Transform {
  // translation -360.7 1370 3471
  // rotation 0.3236 -0.3236 -0.8891 -1.688
  // scale -49.36 -49.36 -49.36
  // scaleOrientation -0.689 0.4766 -0.546 -0.6007

	OffsetToString("Transform");
	ReadLine(); // Transform
	CTransform transform;
	transform.Clear();

	// Translation
	tmp = m_IndexBuffer;
	ReadLine();
	if(strstr(m_pBufferLine,"translation") != NULL)
	{
		// Come back
		m_IndexBuffer = tmp;
		// Jump after "translation"
		ReadWord(); 

		float x,y,z;
		ReadWord();
		int success = sscanf(m_pBufferWord,"%f",&x);
		ReadWord();
		success &= sscanf(m_pBufferWord,"%f",&y);
		ReadWord();
		success &= sscanf(m_pBufferWord,"%f",&z);
		if(success)
		{
			transform.SetTranslation(CVector3d(x,y,z));
			TRACE("    translation : %g %g %g\n",x,y,z);
		}
		ReadLine();
		tmp = m_IndexBuffer;
		ReadLine();
	}

	// Rotation
	if(strstr(m_pBufferLine,"rotation") != NULL)
	{
		// Come back
		m_IndexBuffer = tmp;
		// Jump after "rotation"
		ReadWord(); 

		float x,y,z,value;
		ReadWord();
		int success = sscanf(m_pBufferWord,"%f",&x);
		ReadWord();
		success &= sscanf(m_pBufferWord,"%f",&y);
		ReadWord();
		success &= sscanf(m_pBufferWord,"%f",&z);
		ReadWord();
		success &= sscanf(m_pBufferWord,"%f",&value);
		if(success)
		{
			transform.SetRotation(CVector3d(x,y,z));
			transform.SetValueRotation(value/3.1415926f*180.0f);
			TRACE("    rotation : %g %g %g %g\n",x,y,z,value);
		}
		ReadLine();
		tmp = m_IndexBuffer;
		ReadLine();
	}

	// Scale
	if(strstr(m_pBufferLine,"scale") != NULL)
	{
		// Come back
		m_IndexBuffer = tmp;
		// Jump after "scale"
		ReadWord(); 

		float x,y,z;
		ReadWord();
		int success = sscanf(m_pBufferWord,"%f",&x);
		ReadWord();
		success &= sscanf(m_pBufferWord,"%f",&y);
		ReadWord();
		success &= sscanf(m_pBufferWord,"%f",&z);
		if(success)
		{
			transform.SetScale(CVector3d(x,y,z));
			TRACE("    scale : %g %g %g\n",x,y,z);
		}
		ReadLine();
		tmp = m_IndexBuffer;
		ReadLine();
	}

	// ScaleOrientation
	if(strstr(m_pBufferLine,"scaleOrientation") != NULL)
	{
		// Come back
		m_IndexBuffer = tmp;
		// Jump after "scaleOrientation"
		ReadWord(); 

		float x,y,z,value;
		ReadWord();
		int success = sscanf(m_pBufferWord,"%f",&x);
		ReadWord();
		success &= sscanf(m_pBufferWord,"%f",&y);
		ReadWord();
		success &= sscanf(m_pBufferWord,"%f",&z);
		ReadWord();
		success &= sscanf(m_pBufferWord,"%f",&value);
		if(success)
		{
			//transform.SetScale(CVector3d(x,y,z));
			TRACE("    scaleOrientation : %g %g %g %g\n",x,y,z,value);
		}
		ReadLine();
	}

	// Material
	//********************************************
	// appearance Appearance {
  // material Material {
  // diffuseColor 0.5686 0.1098 0.6941
	CMaterial material;
	if(OffsetToString("Material"))
	{
		ReadLine();

		tmp = m_IndexBuffer;

		// Diffuse color
		ReadLine(); 
		if(strstr(m_pBufferLine,"diffuseColor") != NULL)
		{
			// Come back
			m_IndexBuffer = tmp;

			// Jump
			ReadWord();

			float r,g,b;
			ReadWord();
			int success = sscanf(m_pBufferWord,"%f",&r);
			ReadWord();
			success &= sscanf(m_pBufferWord,"%f",&g);
			ReadWord();
			success &= sscanf(m_pBufferWord,"%f",&b);
			if(success)
			{
				material.SetDiffuse(r,g,b,1.0f);
				TRACE("    diffuseColor : %g %g %g\n",r,g,b);
			}
		}
	}

	// Texture
	//********************************************
	int texture = 0;
	if(OffsetToStringBefore("texture ImageTexture","geometry"))
	{
		texture = 1;
		ReadLine();
		tmp = m_IndexBuffer;

		ReadLine(); 
		if(strstr(m_pBufferLine,"url") != NULL)
		{
			// Come back
			m_IndexBuffer = tmp;

			// Jump
			ReadWord();
			char string[MAX_PATH];
			ReadWord();
			sscanf(m_pBufferWord,"%s",string);

			// Remove ""
			CString TextureName = string;
			TextureName = TextureName.Mid(1,TextureName.GetLength()-2);
			TRACE("    texture : %s\n",TextureName);

			// Ask SceneGraph to add texture, if needed
			char *name = TextureName.GetBuffer(MAX_PATH);
			if(!pSceneGraph->HasTexture(name,&IndexTexture))
			{
				CTexture *pTexture = new CTexture;
				pTexture->ReadFile(name);
				IndexTexture = pSceneGraph->AddTexture(pTexture);
			}
			TextureName.ReleaseBuffer();
		}
	}
	else // come back
		m_IndexBuffer = tmp;

	// Mesh
	//********************************************
	int NbVertex,NbFace,NbTextureCoordinate;
	// Count size (do not offset in file)
	if(!SizeMesh(&NbVertex,&NbFace,texture,&NbTextureCoordinate))
		return 0;

	// Add mesh
	CMesh3d *pMesh = new CMesh3d;
	pSceneGraph->Add(pMesh);
	// Set Size (faster)
	pMesh->m_ArrayVertex.SetSize(NbVertex);
	pMesh->m_ArrayFace.SetSize(NbFace);
	if(texture)
	{
		pMesh->m_pTextureCoordinate = new float[NbTextureCoordinate*2]; // x y 
		pMesh->m_pTextureCoordinateIndex = new int[NbFace*3];           // triangular faces
		pMesh->m_IndexTexture = IndexTexture;
	}
	// Store mesh (offset in file)
	StoreMesh(&pMesh->m_ArrayVertex,&pMesh->m_ArrayFace,texture,
		pMesh->m_pTextureCoordinate,pMesh->m_pTextureCoordinateIndex);

	// Transform & material
	pMesh->SetTransform(transform);
	pMesh->SetMaterial(&material);

	TRACE("  end reading mesh\n");

	return 1;
}

//********************************************
// SizeMesh
//********************************************
int CParserVrml::SizeMesh(int *pNbVertex,
													int *pNbFace,
													int HasTexture,
													int *pNbTextureCoordinate /* = NULL */)
{
	TRACE("    size mesh...");
	int tmp = m_IndexBuffer;

	ASSERT(pNbVertex != NULL);
	ASSERT(pNbFace != NULL);

	if(!OffsetToString("IndexedFaceSet"))
	{
		TRACE("invalid mesh\n");
		return 0;
	}

	// Count points
	//***********************************************
	if(!OffsetToString("Coordinate { point ["))
	{
		TRACE("invalid mesh\n");
		return 0;
	}

	m_IndexBuffer += strlen("Coordinate { point [") + 1;

	// Cur : x y z,
	// End : x y z]
	int NbVertex = 0;
	int success;
	do
	{
		float x,y,z;
		ReadWord();
		success = sscanf(m_pBufferWord,"%f",&x);
		ReadWord();
		success &= sscanf(m_pBufferWord,"%f",&y);
		ReadWord();
		success &= sscanf(m_pBufferWord,"%f",&z);
		NbVertex += success;
		//TRACE("\n (%g %g %g) ",x,y,z);
	}
	while(success);
	TRACE(" %d points,",NbVertex);

	if(NbVertex <= 0)
		return 0;


	// Count texture coordinates, if needed 
	//***********************************************
	int NbTextureCoordinate = 0;
	if(HasTexture)
	{
		if(!OffsetToString("TextureCoordinate { point ["))
		{
			TRACE("invalid texture coordinates\n");
			return 0;
		}

		m_IndexBuffer += strlen("TextureCoordinate { point [") + 1;

		// Cur : x y,
		// End : x y]
		int success;
		do
		{
			float x,y;
			ReadWord();
			success = sscanf(m_pBufferWord,"%f",&x);
			ReadWord();
			success &= sscanf(m_pBufferWord,"%f",&y);
			NbTextureCoordinate += success;
			//TRACE("\n (%g %g %g) ",x,y,z);
		}
		while(success);
		TRACE(" %d texture coordinates,",NbTextureCoordinate);

		if(NbTextureCoordinate <= 0)
			return 0;
	}


	// Count faces, accept only triangles
	//***********************************************
	m_IndexBuffer = tmp;
	if(!OffsetToString("coordIndex ["))
	{
		TRACE("invalid mesh\n");
		return 0;
	}
	m_IndexBuffer += strlen("coordIndex [") + 1;

	// Cur : int, int, int, -1,
	// End : int, int, int, -1]
	int NbFace = 0;
	do
	{
		int v1,v2,v3;
		ReadWord();
		success  = sscanf(m_pBufferWord,"%d,",&v1);
		ReadWord();
		success &= sscanf(m_pBufferWord,"%d,",&v2);
		ReadWord();
		success &= sscanf(m_pBufferWord,"%d,",&v3);
		NbFace += success;

		ASSERT(v1 >= 0);
		ASSERT(v2 >= 0);
		ASSERT(v3 >= 0);

		int test;
		ReadWord();
		sscanf(m_pBufferWord,"%d",&test);
		if(strstr(m_pBufferWord,"]") != NULL)
			success = 0;
	}
	while(success);
	TRACE(" %d faces,",NbFace);

	if(NbFace <= 0)
		return 0;

	// Count texture coordinate index 
	//***********************************************
	if(HasTexture)
	{
		m_IndexBuffer = tmp;
		if(!OffsetToString("texCoordIndex ["))
		{
			TRACE("invalid texture coordinate index\n");
			return 0;
		}
		m_IndexBuffer += strlen("texCoordIndex [") + 1;

		// Cur : int, int, int, -1,
		// End : int, int, int, -1]
		int NbCoordIndex = 0;
		do
		{
			int v1,v2,v3;
			ReadWord();
			success  = sscanf(m_pBufferWord,"%d,",&v1);
			ReadWord();
			success &= sscanf(m_pBufferWord,"%d,",&v2);
			ReadWord();
			success &= sscanf(m_pBufferWord,"%d,",&v3);
			NbCoordIndex += success;

			ASSERT(v1 >= 0);
			ASSERT(v2 >= 0);
			ASSERT(v3 >= 0);

			int test;
			ReadWord();
			sscanf(m_pBufferWord,"%d",&test);
			if(strstr(m_pBufferWord,"]") != NULL)
				success = 0;
		}
		while(success);
		TRACE(" %d coordinate index\n",NbCoordIndex);

		if(NbFace != NbCoordIndex)
		{
			TRACE(" different values for coord index and faces\n");
			return 0;
		}
	}

	// Store result
	*pNbVertex = NbVertex;
	*pNbFace = NbFace;
	if(HasTexture)
		*pNbTextureCoordinate = NbTextureCoordinate;

	m_IndexBuffer = tmp;

	return 1;
}


//********************************************
// StoreMesh
//********************************************
int CParserVrml::StoreMesh(CArray3d<CVertex3d> *pArrayVertex,
													 CArray3d<CFace3d> *pArrayFace,
													 int HasTexture,
													 float *pTextureCoordinate,
													 int *pTextureCoordinateIndex)
{
	TRACE("    store mesh...");
	int tmp = m_IndexBuffer;

	if(!OffsetToString("IndexedFaceSet"))
	{
		TRACE("invalid mesh\n");
		return 0;
	}

	// Store vertices
	//***********************************************
	if(!OffsetToString("Coordinate { point ["))
	{
		TRACE("invalid mesh\n");
		return 0;
	}
	m_IndexBuffer += strlen("Coordinate { point [") + 1;
	// Cur : x y z,
	// End : x y z]
	int success;
	int NbVertex = 0;
	do
	{
		float x,y,z;
		ReadWord();
		success = sscanf(m_pBufferWord,"%f",&x);
		ReadWord();
		success &= sscanf(m_pBufferWord,"%f",&y);
		ReadWord();
		success &= sscanf(m_pBufferWord,"%f",&z);
		if(success)
			pArrayVertex->SetAt(NbVertex++,new CVertex3d(x,y,z));
		//TRACE("\n (%g %g %g) ",x,y,z);
	}
	while(success);
	TRACE(" added %d vertices,",NbVertex);

	// Store texture coordinates (if needed)
	//***********************************************
	if(HasTexture)
	{
		if(!OffsetToString("TextureCoordinate { point ["))
		{
			TRACE("invalid texture coordinate\n");
			return 0;
		}
		m_IndexBuffer += strlen("TextureCoordinate { point [") + 1;
		// Cur : x y,
		// End : x y
		int success;
		int NbTextureCoordinate = 0;
		do
		{
			float x,y;
			ReadWord();
			success = sscanf(m_pBufferWord,"%f",&x);
			ReadWord();
			success &= sscanf(m_pBufferWord,"%f",&y);
			if(success)
			{
				pTextureCoordinate[2*NbTextureCoordinate] = x;
				pTextureCoordinate[2*NbTextureCoordinate+1] = y;
				NbTextureCoordinate++;
			}
			//TRACE("\n (%g %g) ",x,y);
		}
		while(success);
		TRACE(" added %d texture coordinates,",NbTextureCoordinate);
	}

	

	// Store faces, accept only triangles
	//***********************************************
	m_IndexBuffer = tmp;
	if(!OffsetToString("coordIndex ["))
	{
		TRACE("invalid mesh\n");
		return 0;
	}
	m_IndexBuffer += strlen("coordIndex [") + 1;

	// Cur : int, int, int, -1,
	// End : int, int, int, -1]
	int NbFace = 0;
	do
	{
		int v1,v2,v3;
		ReadWord();
		success  = sscanf(m_pBufferWord,"%d,",&v1);
		ReadWord();
		success &= sscanf(m_pBufferWord,"%d,",&v2);
		ReadWord();
		success &= sscanf(m_pBufferWord,"%d,",&v3);

		ASSERT(v1 >= 0);
		ASSERT(v2 >= 0);
		ASSERT(v3 >= 0);


		if(success && v1 >= 0 && v2 >= 0 && v3 >= 0)
		{
			CFace3d *pFace = new CFace3d(pArrayVertex->GetAt(v1),
				                           pArrayVertex->GetAt(v2),
																	 pArrayVertex->GetAt(v3));
			pArrayFace->SetAt(NbFace++,pFace);
		}

		int test;
		ReadWord();
		sscanf(m_pBufferWord,"%d",&test);
		if(strstr(m_pBufferWord,"]") != NULL)
			success = 0;

	}
	while(success);
	TRACE(" added %d faces\n",NbFace);

	// Store texture coord index
	//***********************************************
	if(HasTexture)
	{
		m_IndexBuffer = tmp;
		if(!OffsetToString("texCoordIndex ["))
		{
			TRACE("invalid mesh\n");
			return 0;
		}
		m_IndexBuffer += strlen("texCoordIndex [") + 1;

		// Cur : int, int, int, -1,
		// End : int, int, int, -1]
		int NbTexCoordIndex = 0;
		do
		{
			int v1,v2,v3;
			ReadWord();
			success  = sscanf(m_pBufferWord,"%d,",&v1);
			ReadWord();
			success &= sscanf(m_pBufferWord,"%d,",&v2);
			ReadWord();
			success &= sscanf(m_pBufferWord,"%d,",&v3);

			ASSERT(v1 >= 0);
			ASSERT(v2 >= 0);
			ASSERT(v3 >= 0);

			if(success && v1 >= 0 && v2 >= 0 && v3 >= 0)
			{
				pTextureCoordinateIndex[3*NbTexCoordIndex] = v1;
				pTextureCoordinateIndex[3*NbTexCoordIndex+1] = v2;
				pTextureCoordinateIndex[3*NbTexCoordIndex+2] = v3;
				NbTexCoordIndex++;
			}

			int test;
			ReadWord();
			sscanf(m_pBufferWord,"%d",&test);
			if(strstr(m_pBufferWord,"]") != NULL)
				success = 0;

		}
		while(success);
		TRACE(" added %d texture coordinate index\n",NbTexCoordIndex);
	}

	return 1;
}

// ** EOF **





By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
France France
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions