Added DXF implementation. No support for polymeshes yes, just 3DFACE elements are implemented.
Added strtol64s function, refactored SMDLoader.cpp to use it. git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@120 67173fc5-114c-0410-ac8e-9d2fd5bffc1fpull/1/head
parent
ad4cc033d8
commit
56563016b0
|
@ -41,6 +41,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
/** @file Implementation of the DXF importer class */
|
/** @file Implementation of the DXF importer class */
|
||||||
#include "DXFLoader.h"
|
#include "DXFLoader.h"
|
||||||
|
#include "ParsingUtils.h"
|
||||||
|
#include "fast_atof.h"
|
||||||
|
#include "MaterialSystem.h"
|
||||||
|
|
||||||
// public ASSIMP headers
|
// public ASSIMP headers
|
||||||
#include "../include/aiScene.h"
|
#include "../include/aiScene.h"
|
||||||
|
@ -85,6 +88,32 @@ bool DXFImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler) const
|
||||||
extension[2] != 'x' && extension[2] != 'X' ||
|
extension[2] != 'x' && extension[2] != 'X' ||
|
||||||
extension[3] != 'f' && extension[3] != 'F');
|
extension[3] != 'f' && extension[3] != 'F');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
bool DXFImporter::GetNextLine()
|
||||||
|
{
|
||||||
|
if(!SkipLine(buffer,&buffer))return false;
|
||||||
|
if(!SkipSpaces(buffer,&buffer))return GetNextLine();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
bool DXFImporter::GetNextToken()
|
||||||
|
{
|
||||||
|
SkipSpaces(buffer,&buffer);
|
||||||
|
groupCode = strtol10s(buffer,&buffer);
|
||||||
|
if(!GetNextLine())return false;
|
||||||
|
|
||||||
|
// copy the data line to a separate buffer
|
||||||
|
char* m = cursor;
|
||||||
|
while (!IsLineEnd ( *buffer ) && m < (cursor+sizeof(cursor)/sizeof(char)))
|
||||||
|
*m++ = *buffer++;
|
||||||
|
|
||||||
|
*m = '\0';
|
||||||
|
GetNextLine();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Imports the given file into the given scene structure.
|
// Imports the given file into the given scene structure.
|
||||||
void DXFImporter::InternReadFile( const std::string& pFile,
|
void DXFImporter::InternReadFile( const std::string& pFile,
|
||||||
|
@ -96,5 +125,264 @@ void DXFImporter::InternReadFile( const std::string& pFile,
|
||||||
if( file.get() == NULL)
|
if( file.get() == NULL)
|
||||||
throw new ImportErrorException( "Failed to open DXF file " + pFile + "");
|
throw new ImportErrorException( "Failed to open DXF file " + pFile + "");
|
||||||
|
|
||||||
throw new ImportErrorException("DXF: not yet implemented");
|
// read the contents of the file in a buffer
|
||||||
|
unsigned int m = (unsigned int)file->FileSize();
|
||||||
|
std::vector<char> buffer2(m+1);
|
||||||
|
buffer = &buffer2[0];
|
||||||
|
file->Read( &buffer2[0], m,1);
|
||||||
|
buffer2[m] = '\0';
|
||||||
|
|
||||||
|
mDefaultLayer = NULL;
|
||||||
|
|
||||||
|
// now get all lines of the file
|
||||||
|
while (GetNextToken())
|
||||||
|
{
|
||||||
|
if (2 == groupCode)
|
||||||
|
{
|
||||||
|
// ENTITIES section
|
||||||
|
if (!::strcmp(cursor,"ENTITIES"))
|
||||||
|
if (!ParseEntities())break;
|
||||||
|
|
||||||
|
// HEADER section - just to print the file format version
|
||||||
|
else if (!::strcmp(cursor,"HEADER"))
|
||||||
|
if (!ParseHeader())break;
|
||||||
|
|
||||||
|
// other sections such as BLOCK - skip them to make
|
||||||
|
// sure there will be no name conflicts
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bool b = false;
|
||||||
|
while (GetNextToken())
|
||||||
|
{
|
||||||
|
if (!groupCode && !::strcmp(cursor,"ENDSEC"))
|
||||||
|
{b = true;break;}
|
||||||
|
}
|
||||||
|
if (!b)break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// print comment strings
|
||||||
|
else if (999 == groupCode)
|
||||||
|
{
|
||||||
|
DefaultLogger::get()->info(std::string( cursor ));
|
||||||
|
}
|
||||||
|
else if (!groupCode && !::strcmp(cursor,"EOF"))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mLayers.empty())
|
||||||
|
throw new ImportErrorException("DXF: this file contains no 3d data");
|
||||||
|
|
||||||
|
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes = (unsigned int)mLayers.size()];
|
||||||
|
m = 0;
|
||||||
|
for (std::vector<LayerInfo>::const_iterator it = mLayers.begin(),end = mLayers.end();
|
||||||
|
it != end;++it)
|
||||||
|
{
|
||||||
|
// generate the output mesh
|
||||||
|
aiMesh* pMesh = pScene->mMeshes[m++] = new aiMesh();
|
||||||
|
const std::vector<aiVector3D>& vPositions = (*it).vPositions;
|
||||||
|
|
||||||
|
pMesh->mNumFaces = (unsigned int)vPositions.size() / 4u;
|
||||||
|
pMesh->mFaces = new aiFace[pMesh->mNumFaces];
|
||||||
|
|
||||||
|
aiVector3D* vpOut = pMesh->mVertices = new aiVector3D[vPositions.size()];
|
||||||
|
const aiVector3D* vp = &vPositions[0];
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < pMesh->mNumFaces;++i)
|
||||||
|
{
|
||||||
|
aiFace& face = pMesh->mFaces[i];
|
||||||
|
|
||||||
|
// check whether we need four indices here
|
||||||
|
if (vp[3] != vp[2])
|
||||||
|
{
|
||||||
|
face.mNumIndices = 4;
|
||||||
|
}
|
||||||
|
else face.mNumIndices = 3;
|
||||||
|
face.mIndices = new unsigned int[face.mNumIndices];
|
||||||
|
|
||||||
|
for (unsigned int a = 0; a < face.mNumIndices;++a)
|
||||||
|
{
|
||||||
|
*vpOut++ = vp[a];
|
||||||
|
face.mIndices[a] = pMesh->mNumVertices++;
|
||||||
|
}
|
||||||
|
vp += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// generate the output scene graph
|
||||||
|
pScene->mRootNode = new aiNode();
|
||||||
|
pScene->mRootNode->mName.Set("<DXF_ROOT>");
|
||||||
|
|
||||||
|
if (1 == pScene->mNumMeshes)
|
||||||
|
{
|
||||||
|
pScene->mRootNode->mMeshes = new unsigned int[ pScene->mRootNode->mNumMeshes = 1 ];
|
||||||
|
pScene->mRootNode->mMeshes[0] = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pScene->mRootNode->mChildren = new aiNode*[ pScene->mRootNode->mNumChildren = pScene->mNumMeshes ];
|
||||||
|
for (m = 0; m < pScene->mRootNode->mNumChildren;++m)
|
||||||
|
{
|
||||||
|
aiNode* p = pScene->mRootNode->mChildren[m] = new aiNode();
|
||||||
|
p->mName.length = ::strlen( mLayers[m].name );
|
||||||
|
::strcpy(p->mName.data, mLayers[m].name);
|
||||||
|
|
||||||
|
p->mMeshes = new unsigned int[p->mNumMeshes = 1];
|
||||||
|
p->mMeshes[0] = m;
|
||||||
|
p->mParent = pScene->mRootNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// generate a default material
|
||||||
|
MaterialHelper* pcMat = new MaterialHelper();
|
||||||
|
aiString s;
|
||||||
|
s.Set(AI_DEFAULT_MATERIAL_NAME);
|
||||||
|
pcMat->AddProperty(&s, AI_MATKEY_NAME);
|
||||||
|
|
||||||
|
aiColor4D clrDiffuse(0.6f,0.6f,0.6f,1.0f);
|
||||||
|
pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_DIFFUSE);
|
||||||
|
|
||||||
|
clrDiffuse = aiColor4D(1.0f,1.0f,1.0f,1.0f);
|
||||||
|
pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_SPECULAR);
|
||||||
|
|
||||||
|
clrDiffuse = aiColor4D(0.05f,0.05f,0.05f,1.0f);
|
||||||
|
pcMat->AddProperty(&clrDiffuse,1,AI_MATKEY_COLOR_AMBIENT);
|
||||||
|
|
||||||
|
pScene->mNumMaterials = 1;
|
||||||
|
pScene->mMaterials = new aiMaterial*[1];
|
||||||
|
pScene->mMaterials[0] = pcMat;
|
||||||
|
|
||||||
|
// --- everything destructs automatically ---
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
bool DXFImporter::ParseEntities()
|
||||||
|
{
|
||||||
|
while (GetNextToken())
|
||||||
|
{
|
||||||
|
if (!groupCode)
|
||||||
|
{
|
||||||
|
while (true) {
|
||||||
|
if (!::strcmp(cursor,"3DFACE"))
|
||||||
|
if (!Parse3DFace()) return false; else continue;
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
if (!::strcmp(cursor,"ENDSEC"))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
bool DXFImporter::ParseHeader()
|
||||||
|
{
|
||||||
|
// --- at the moment we don't need any information from the header
|
||||||
|
while (GetNextToken())
|
||||||
|
{
|
||||||
|
if (!groupCode)
|
||||||
|
{
|
||||||
|
if (!::strcmp(cursor,"ENDSEC"))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// print comment strings
|
||||||
|
else if (999 == groupCode)
|
||||||
|
{
|
||||||
|
DefaultLogger::get()->info(std::string( cursor ));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
bool DXFImporter::Parse3DFace()
|
||||||
|
{
|
||||||
|
bool ret = false;
|
||||||
|
LayerInfo* out = NULL;
|
||||||
|
|
||||||
|
aiVector3D vip[4]; // -- vectors are initialized to zero
|
||||||
|
while (GetNextToken())
|
||||||
|
{
|
||||||
|
switch (groupCode)
|
||||||
|
{
|
||||||
|
case 0: ret = true;break;
|
||||||
|
|
||||||
|
// 8 specifies the layer
|
||||||
|
case 8:
|
||||||
|
{
|
||||||
|
for (std::vector<LayerInfo>::iterator it = mLayers.begin(),end = mLayers.end();
|
||||||
|
it != end;++it)
|
||||||
|
{
|
||||||
|
if (!::strcmp( (*it).name, cursor ))
|
||||||
|
{
|
||||||
|
out = &(*it);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!out)
|
||||||
|
{
|
||||||
|
// we don't have this layer yet
|
||||||
|
mLayers.push_back(LayerInfo());
|
||||||
|
out = &mLayers.back();
|
||||||
|
::strcpy(out->name,cursor);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// x position of the first corner
|
||||||
|
case 10: vip[0].x = fast_atof(cursor);break;
|
||||||
|
|
||||||
|
// y position of the first corner
|
||||||
|
case 20: vip[0].y = -fast_atof(cursor);break;
|
||||||
|
|
||||||
|
// z position of the first corner
|
||||||
|
case 30: vip[0].z = fast_atof(cursor);break;
|
||||||
|
|
||||||
|
// x position of the second corner
|
||||||
|
case 11: vip[1].x = fast_atof(cursor);break;
|
||||||
|
|
||||||
|
// y position of the second corner
|
||||||
|
case 21: vip[1].y = -fast_atof(cursor);break;
|
||||||
|
|
||||||
|
// z position of the second corner
|
||||||
|
case 31: vip[1].z = fast_atof(cursor);break;
|
||||||
|
|
||||||
|
// x position of the third corner
|
||||||
|
case 12: vip[2].x = fast_atof(cursor);break;
|
||||||
|
|
||||||
|
// y position of the third corner
|
||||||
|
case 22: vip[2].y = -fast_atof(cursor);break;
|
||||||
|
|
||||||
|
// z position of the third corner
|
||||||
|
case 32: vip[2].z = fast_atof(cursor);break;
|
||||||
|
|
||||||
|
// x position of the fourth corner
|
||||||
|
case 13: vip[3].x = fast_atof(cursor);break;
|
||||||
|
|
||||||
|
// y position of the fourth corner
|
||||||
|
case 23: vip[3].y = -fast_atof(cursor);break;
|
||||||
|
|
||||||
|
// z position of the fourth corner
|
||||||
|
case 33: vip[3].z = fast_atof(cursor);break;
|
||||||
|
};
|
||||||
|
if (ret)break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// use a default layer if necessary
|
||||||
|
if (!out)
|
||||||
|
{
|
||||||
|
if (!mDefaultLayer)
|
||||||
|
{
|
||||||
|
mLayers.push_back(LayerInfo());
|
||||||
|
mDefaultLayer = &mLayers.back();
|
||||||
|
}
|
||||||
|
out = mDefaultLayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// add the faces to the face list for this layer
|
||||||
|
out->vPositions.push_back(vip[0]);
|
||||||
|
out->vPositions.push_back(vip[1]);
|
||||||
|
out->vPositions.push_back(vip[2]);
|
||||||
|
out->vPositions.push_back(vip[3]);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef AI_DXFLOADER_H_INCLUDED
|
#ifndef AI_DXFLOADER_H_INCLUDED
|
||||||
#define AI_DXFLOADER_H_INCLUDED
|
#define AI_DXFLOADER_H_INCLUDED
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "BaseImporter.h"
|
#include "BaseImporter.h"
|
||||||
#include "../include/aiTypes.h"
|
#include "../include/aiTypes.h"
|
||||||
|
|
||||||
|
@ -86,6 +88,64 @@ protected:
|
||||||
void InternReadFile( const std::string& pFile, aiScene* pScene,
|
void InternReadFile( const std::string& pFile, aiScene* pScene,
|
||||||
IOSystem* pIOHandler);
|
IOSystem* pIOHandler);
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Get the next line from the file.
|
||||||
|
* @return false if the end of the file was reached
|
||||||
|
*/
|
||||||
|
bool GetNextLine();
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Get the next token (group code + data line) from the file.
|
||||||
|
* @return false if the end of the file was reached
|
||||||
|
*/
|
||||||
|
bool GetNextToken();
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Parses the ENTITIES section in the file
|
||||||
|
* @return false if the end of the file was reached
|
||||||
|
*/
|
||||||
|
bool ParseEntities();
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Parses the HEADER section in the file
|
||||||
|
* @return false if the end of the file was reached
|
||||||
|
*/
|
||||||
|
bool ParseHeader();
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------
|
||||||
|
/** Parses a 3DFACE section in the file
|
||||||
|
* @return false if the end of the file was reached
|
||||||
|
*/
|
||||||
|
bool Parse3DFace();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// points to the next section
|
||||||
|
const char* buffer;
|
||||||
|
|
||||||
|
// specifies the current group code
|
||||||
|
int groupCode;
|
||||||
|
|
||||||
|
// contains the current data line
|
||||||
|
char cursor[4096];
|
||||||
|
|
||||||
|
// describes a single layer in the DXF file
|
||||||
|
struct LayerInfo
|
||||||
|
{
|
||||||
|
LayerInfo()
|
||||||
|
{
|
||||||
|
name[0] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
char name[4096];
|
||||||
|
|
||||||
|
// face buffer - order is x,y,z,w v1,v2,v3 (w is equal to z if unused)
|
||||||
|
std::vector<aiVector3D> vPositions;
|
||||||
|
};
|
||||||
|
|
||||||
|
// list of all loaded layers
|
||||||
|
std::vector<LayerInfo> mLayers;
|
||||||
|
LayerInfo* mDefaultLayer;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
|
|
|
@ -107,6 +107,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#if (!defined AI_BUILD_NO_LWO_IMPORTER)
|
#if (!defined AI_BUILD_NO_LWO_IMPORTER)
|
||||||
# include "LWOLoader.h"
|
# include "LWOLoader.h"
|
||||||
#endif
|
#endif
|
||||||
|
#if (!defined AI_BUILD_NO_DXF_IMPORTER)
|
||||||
|
# include "DXFLoader.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// PostProcess-Steps
|
// PostProcess-Steps
|
||||||
|
@ -222,6 +225,9 @@ Importer::Importer() :
|
||||||
#if (!defined AI_BUILD_NO_LWO_IMPORTER)
|
#if (!defined AI_BUILD_NO_LWO_IMPORTER)
|
||||||
mImporter.push_back( new LWOImporter());
|
mImporter.push_back( new LWOImporter());
|
||||||
#endif
|
#endif
|
||||||
|
#if (!defined AI_BUILD_NO_DXF_IMPORTER)
|
||||||
|
mImporter.push_back( new DXFImporter());
|
||||||
|
#endif
|
||||||
|
|
||||||
// add an instance of each post processing step here in the order
|
// add an instance of each post processing step here in the order
|
||||||
// of sequence it is executed. steps that are added here are not validated -
|
// of sequence it is executed. steps that are added here are not validated -
|
||||||
|
|
|
@ -1061,9 +1061,8 @@ bool SMDImporter::ParseFloat(const char* szCurrent,
|
||||||
const char** szCurrentOut, float& out)
|
const char** szCurrentOut, float& out)
|
||||||
{
|
{
|
||||||
if(!SkipSpaces(szCurrent,&szCurrent))
|
if(!SkipSpaces(szCurrent,&szCurrent))
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
*szCurrentOut = fast_atof_move(szCurrent,out);
|
*szCurrentOut = fast_atof_move(szCurrent,out);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1073,9 +1072,8 @@ bool SMDImporter::ParseUnsignedInt(const char* szCurrent,
|
||||||
const char** szCurrentOut, uint32_t& out)
|
const char** szCurrentOut, uint32_t& out)
|
||||||
{
|
{
|
||||||
if(!SkipSpaces(szCurrent,&szCurrent))
|
if(!SkipSpaces(szCurrent,&szCurrent))
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
out = (uint32_t)strtol10(szCurrent,szCurrentOut);
|
out = (uint32_t)strtol10(szCurrent,szCurrentOut);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1085,21 +1083,9 @@ bool SMDImporter::ParseSignedInt(const char* szCurrent,
|
||||||
const char** szCurrentOut, int32_t& out)
|
const char** szCurrentOut, int32_t& out)
|
||||||
{
|
{
|
||||||
if(!SkipSpaces(szCurrent,&szCurrent))
|
if(!SkipSpaces(szCurrent,&szCurrent))
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
// handle signs
|
|
||||||
bool bInv = false;
|
|
||||||
if ('-' == *szCurrent)
|
|
||||||
{
|
|
||||||
++szCurrent;
|
|
||||||
bInv = true;
|
|
||||||
}
|
|
||||||
else if ('+' == *szCurrent)++szCurrent;
|
|
||||||
|
|
||||||
// parse the integer
|
out = (int32_t)strtol10s(szCurrent,szCurrentOut);
|
||||||
out = (int32_t)strtol10(szCurrent,szCurrentOut);
|
|
||||||
if (bInv)out = -out;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -58,6 +58,18 @@ inline unsigned int strtol10( const char* in, const char** out=0)
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------
|
||||||
|
// signed variant of strtol10
|
||||||
|
inline int strtol10s( const char* in, const char** out=0)
|
||||||
|
{
|
||||||
|
bool bNeg = false;
|
||||||
|
if ('-' == *in){++in;bNeg = true;}
|
||||||
|
if ('+' == *in)++in;
|
||||||
|
int value = strtol10(in,out);
|
||||||
|
if (bNeg)value = -value;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------
|
||||||
// specal version of the function, providing higher accuracy
|
// specal version of the function, providing higher accuracy
|
||||||
|
|
Loading…
Reference in New Issue