Merge branch 'master' of git://github.com/assimp/assimp

This commit is contained in:
Alexander Gessler
2012-12-21 16:24:05 +01:00
179 changed files with 20711 additions and 7693 deletions

View File

@@ -44,6 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "AssimpPCH.h"
#ifndef ASSIMP_BUILD_NO_ASE_IMPORTER
// internal headers
#include "TextureTransform.h"
@@ -2148,3 +2149,5 @@ void Parser::ParseLV4MeshLong(unsigned int& iOut)
// parse the value
iOut = strtoul10(filePtr,&filePtr);
}
#endif // !! ASSIMP_BUILD_NO_BASE_IMPORTER

View File

@@ -514,7 +514,8 @@ void ColladaLoader::BuildMeshesForNode( const ColladaParser& pParser, const Coll
// assign the material index
dstMesh->mMaterialIndex = matIdx;
}
dstMesh->mName = mid.mMeshOrController;
}
}
}

View File

@@ -1369,9 +1369,11 @@ void ColladaParser::ReadEffectColor( aiColor4D& pColor, Sampler& pSampler)
int attrTex = GetAttribute( "texture");
pSampler.mName = mReader->getAttributeValue( attrTex);
// get name of UV source channel
attrTex = GetAttribute( "texcoord");
pSampler.mUVChannel = mReader->getAttributeValue( attrTex);
// get name of UV source channel. Specification demands it to be there, but some exporters
// don't write it. It will be the default UV channel in case it's missing.
attrTex = TestAttribute( "texcoord");
if( attrTex >= 0 )
pSampler.mUVChannel = mReader->getAttributeValue( attrTex);
//SkipElement();
}
else if( IsElement( "technique"))
@@ -1795,14 +1797,13 @@ void ColladaParser::ReadAccessor( const std::string& pID)
SkipElement();
} else
{
ThrowException( "Unexpected sub element in tag \"accessor\".");
ThrowException( boost::str( boost::format( "Unexpected sub element <%s> in tag <accessor>") % mReader->getNodeName()));
}
}
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
{
if( strcmp( mReader->getNodeName(), "accessor") != 0)
ThrowException( "Expected end of \"accessor\" element.");
ThrowException( "Expected end of <accessor> element.");
break;
}
}
@@ -1826,13 +1827,13 @@ void ColladaParser::ReadVertexData( Mesh* pMesh)
ReadInputChannel( pMesh->mPerVertexData);
} else
{
ThrowException( "Unexpected sub element in tag \"vertices\".");
ThrowException( boost::str( boost::format( "Unexpected sub element <%s> in tag <vertices>") % mReader->getNodeName()));
}
}
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
{
if( strcmp( mReader->getNodeName(), "vertices") != 0)
ThrowException( "Expected end of \"vertices\" element.");
ThrowException( "Expected end of <vertices> element.");
break;
}
@@ -1919,13 +1920,13 @@ void ColladaParser::ReadIndexData( Mesh* pMesh)
}
} else
{
ThrowException( "Unexpected sub element in tag \"vertices\".");
ThrowException( boost::str( boost::format( "Unexpected sub element <%s> in tag <%s>") % mReader->getNodeName() % elementName));
}
}
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
{
if( mReader->getNodeName() != elementName)
ThrowException( boost::str( boost::format( "Expected end of \"%s\" element.") % elementName));
ThrowException( boost::str( boost::format( "Expected end of <%s> element.") % elementName));
break;
}
@@ -2063,7 +2064,7 @@ void ColladaParser::ReadPrimitives( Mesh* pMesh, std::vector<InputChannel>& pPer
{
// warn if the vertex channel does not refer to the <vertices> element in the same mesh
if( input.mAccessor != pMesh->mVertexID)
ThrowException( "Unsupported vertex referencing scheme. I fucking hate Collada.");
ThrowException( "Unsupported vertex referencing scheme.");
continue;
}
@@ -2230,7 +2231,13 @@ void ColladaParser::ExtractDataObjectFromChannel( const InputChannel& pInput, si
pMesh->mColors[pInput.mIndex].insert( pMesh->mColors[pInput.mIndex].end(),
pMesh->mPositions.size() - pMesh->mColors[pInput.mIndex].size() - 1, aiColor4D( 0, 0, 0, 1));
pMesh->mColors[pInput.mIndex].push_back( aiColor4D( obj[0], obj[1], obj[2], obj[3]));
//pMesh->mColors[pInput.mIndex].push_back( aiColor4D( obj[0], obj[1], obj[2], obj[3]));
aiColor4D result(0, 0, 0, 1);
for (size_t i = 0; i < pInput.mResolved->mSize; ++i)
{
result[i] = obj[pInput.mResolved->mSubOffset[i]];
}
pMesh->mColors[pInput.mIndex].push_back(result);
} else
{
DefaultLogger::get()->error("Collada: too many vertex color sets. Skipping.");

File diff suppressed because it is too large Load Diff

View File

@@ -45,7 +45,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "AssimpPCH.h"
#ifndef ASSIMP_BUILD_NO_IFC_IMPORTER
#include "IFCUtil.h"
#include "PolyTools.h"
#include "ProcessHelper.h"
namespace Assimp {
@@ -127,6 +129,122 @@ void TempMesh::Append(const TempMesh& other)
vertcnt.insert(vertcnt.end(),other.vertcnt.begin(),other.vertcnt.end());
}
// ------------------------------------------------------------------------------------------------
void TempMesh::RemoveDegenerates()
{
// The strategy is simple: walk the mesh and compute normals using
// Newell's algorithm. The length of the normals gives the area
// of the polygons, which is close to zero for lines.
std::vector<IfcVector3> normals;
ComputePolygonNormals(normals, false);
bool drop = false;
size_t inor = 0;
std::vector<IfcVector3>::iterator vit = verts.begin();
for (std::vector<unsigned int>::iterator it = vertcnt.begin(); it != vertcnt.end(); ++inor) {
const unsigned int pcount = *it;
if (normals[inor].SquareLength() < 1e-5f) {
it = vertcnt.erase(it);
vit = verts.erase(vit, vit + pcount);
drop = true;
continue;
}
vit += pcount;
++it;
}
if(drop) {
IFCImporter::LogDebug("removing degenerate faces");
}
}
// ------------------------------------------------------------------------------------------------
void TempMesh::ComputePolygonNormals(std::vector<IfcVector3>& normals,
bool normalize,
size_t ofs) const
{
size_t max_vcount = 0;
std::vector<unsigned int>::const_iterator begin = vertcnt.begin()+ofs, end = vertcnt.end(), iit;
for(iit = begin; iit != end; ++iit) {
max_vcount = std::max(max_vcount,static_cast<size_t>(*iit));
}
std::vector<IfcFloat> temp((max_vcount+2)*4);
normals.reserve( normals.size() + vertcnt.size()-ofs );
// `NewellNormal()` currently has a relatively strange interface and need to
// re-structure things a bit to meet them.
size_t vidx = std::accumulate(vertcnt.begin(),begin,0);
for(iit = begin; iit != end; vidx += *iit++) {
if (!*iit) {
normals.push_back(IfcVector3());
continue;
}
for(size_t vofs = 0, cnt = 0; vofs < *iit; ++vofs) {
const IfcVector3& v = verts[vidx+vofs];
temp[cnt++] = v.x;
temp[cnt++] = v.y;
temp[cnt++] = v.z;
#ifdef _DEBUG
temp[cnt] = std::numeric_limits<IfcFloat>::quiet_NaN();
#endif
++cnt;
}
normals.push_back(IfcVector3());
NewellNormal<4,4,4>(normals.back(),*iit,&temp[0],&temp[1],&temp[2]);
}
if(normalize) {
BOOST_FOREACH(IfcVector3& n, normals) {
n.Normalize();
}
}
}
// ------------------------------------------------------------------------------------------------
// Compute the normal of the last polygon in the given mesh
IfcVector3 TempMesh::ComputeLastPolygonNormal(bool normalize) const
{
size_t total = vertcnt.back(), vidx = verts.size() - total;
std::vector<IfcFloat> temp((total+2)*3);
for(size_t vofs = 0, cnt = 0; vofs < total; ++vofs) {
const IfcVector3& v = verts[vidx+vofs];
temp[cnt++] = v.x;
temp[cnt++] = v.y;
temp[cnt++] = v.z;
}
IfcVector3 nor;
NewellNormal<3,3,3>(nor,total,&temp[0],&temp[1],&temp[2]);
return normalize ? nor.Normalize() : nor;
}
// ------------------------------------------------------------------------------------------------
void TempMesh::FixupFaceOrientation()
{
const IfcVector3 vavg = Center();
std::vector<IfcVector3> normals;
ComputePolygonNormals(normals);
size_t c = 0, ofs = 0;
BOOST_FOREACH(unsigned int cnt, vertcnt) {
if (cnt>2){
const IfcVector3& thisvert = verts[c];
if (normals[ofs]*(thisvert-vavg) < 0) {
std::reverse(verts.begin()+c,verts.begin()+cnt+c);
}
}
c += cnt;
++ofs;
}
}
// ------------------------------------------------------------------------------------------------
void TempMesh::RemoveAdjacentDuplicates()
{
@@ -189,7 +307,7 @@ void TempMesh::RemoveAdjacentDuplicates()
base += cnt;
}
if(drop) {
IFCImporter::LogDebug("removed duplicate vertices");
IFCImporter::LogDebug("removing duplicate vertices");
}
}

View File

@@ -76,12 +76,27 @@ struct delete_fun
struct TempMesh;
struct TempOpening
{
const IFC::IfcExtrudedAreaSolid* solid;
const IFC::IfcSolidModel* solid;
IfcVector3 extrusionDir;
boost::shared_ptr<TempMesh> profileMesh;
// list of points generated for this opening. This is used to
// create connections between two opposing holes created
// from a single opening instance (two because walls tend to
// have two sides). If !empty(), the other side of the wall
// has already been processed.
std::vector<IfcVector3> wallPoints;
// ------------------------------------------------------------------------------
TempOpening(const IFC::IfcExtrudedAreaSolid* solid,IfcVector3 extrusionDir,boost::shared_ptr<TempMesh> profileMesh)
TempOpening()
: solid()
, extrusionDir()
, profileMesh()
{
}
// ------------------------------------------------------------------------------
TempOpening(const IFC::IfcSolidModel* solid,IfcVector3 extrusionDir,boost::shared_ptr<TempMesh> profileMesh)
: solid(solid)
, extrusionDir(extrusionDir)
, profileMesh(profileMesh)
@@ -168,7 +183,19 @@ struct TempMesh
void Transform(const IfcMatrix4& mat);
IfcVector3 Center() const;
void Append(const TempMesh& other);
bool IsEmpty() const {
return verts.empty() && vertcnt.empty();
}
void RemoveAdjacentDuplicates();
void RemoveDegenerates();
void FixupFaceOrientation();
IfcVector3 ComputeLastPolygonNormal(bool normalize = true) const;
void ComputePolygonNormals(std::vector<IfcVector3>& normals,
bool normalize = true,
size_t ofs = 0) const;
};

View File

@@ -45,6 +45,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "AssimpPCH.h"
#ifndef ASSIMP_BUILD_NO_IRR_IMPORTER
#include "IRRLoader.h"
#include "ParsingUtils.h"
#include "fast_atof.h"
@@ -1471,3 +1473,5 @@ void IRRImporter::InternReadFile( const std::string& pFile,
*/
return;
}
#endif // !! ASSIMP_BUILD_NO_IRR_IMPORTER

View File

@@ -43,6 +43,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "AssimpPCH.h"
#ifndef ASSIMP_BUILD_NO_IRR_IMPORTER
#include "IRRMeshLoader.h"
#include "ParsingUtils.h"
#include "fast_atof.h"
@@ -509,3 +511,5 @@ void IRRMeshImporter::InternReadFile( const std::string& pFile,
delete reader;
AI_DEBUG_INVALIDATE_PTR(reader);
}
#endif // !! ASSIMP_BUILD_NO_IRR_IMPORTER

View File

@@ -45,6 +45,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "AssimpPCH.h"
#ifndef ASSIMP_BUILD_NO_IRR_IMPORTER
#include "IRRShared.h"
#include "ParsingUtils.h"
#include "fast_atof.h"
@@ -494,3 +496,5 @@ aiMaterial* IrrlichtBase::ParseMaterial(unsigned int& matFlags)
DefaultLogger::get()->error("IRRMESH: Unexpected end of file. Material is not complete");
return mat;
}
#endif // !! ASSIMP_BUILD_NO_IRR_IMPORTER

View File

@@ -44,6 +44,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "AssimpPCH.h"
#ifndef ASSIMP_BUILD_NO_LWS_IMPORTER
#include "LWSLoader.h"
#include "ParsingUtils.h"
@@ -918,3 +919,5 @@ void LWSImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
}
}
#endif // !! ASSIMP_BUILD_NO_LWS_IMPORTER

View File

@@ -310,7 +310,7 @@ struct Model
m_Groups.clear();
for ( std::map<std::string, Material*>::iterator it = m_MaterialMap.begin(); it != m_MaterialMap.end(); ++it ) {
// delete it->second;
delete it->second;
}
}
};

View File

@@ -100,7 +100,7 @@ void OgreImporter::InternReadFile(const std::string &pFile, aiScene *pScene, Ass
//Read the Mesh File:
boost::scoped_ptr<CIrrXML_IOStreamReader> mIOWrapper( new CIrrXML_IOStreamReader( file.get()));
XmlReader* MeshFile = irr::io::createIrrXMLReader(mIOWrapper.get());
boost::scoped_ptr<XmlReader> MeshFile(irr::io::createIrrXMLReader(mIOWrapper.get()));
if(!MeshFile)//parse the xml file
throw DeadlyImportError("Failed to create XML Reader for "+pFile);
@@ -108,21 +108,21 @@ void OgreImporter::InternReadFile(const std::string &pFile, aiScene *pScene, Ass
DefaultLogger::get()->debug("Mesh File opened");
//Read root Node:
if(!(XmlRead(MeshFile) && string(MeshFile->getNodeName())=="mesh"))
if(!(XmlRead(MeshFile.get()) && string(MeshFile->getNodeName())=="mesh"))
{
throw DeadlyImportError("Root Node is not <mesh>! "+pFile+" "+MeshFile->getNodeName());
}
//eventually load shared geometry
XmlRead(MeshFile);//shared geometry is optional, so we need a reed for the next two if's
XmlRead(MeshFile.get());//shared geometry is optional, so we need a reed for the next two if's
if(MeshFile->getNodeName()==string("sharedgeometry"))
{
unsigned int NumVertices=GetAttribute<int>(MeshFile, "vertexcount");;
unsigned int NumVertices=GetAttribute<int>(MeshFile.get(), "vertexcount");;
XmlRead(MeshFile);
XmlRead(MeshFile.get());
while(MeshFile->getNodeName()==string("vertexbuffer"))
{
ReadVertexBuffer(m_SharedGeometry, MeshFile, NumVertices);
ReadVertexBuffer(m_SharedGeometry, MeshFile.get(), NumVertices);
}
}
@@ -136,13 +136,13 @@ void OgreImporter::InternReadFile(const std::string &pFile, aiScene *pScene, Ass
//-------------------Read the submeshs and materials:-----------------------
std::list<boost::shared_ptr<SubMesh> > SubMeshes;
vector<aiMaterial*> Materials;
XmlRead(MeshFile);
XmlRead(MeshFile.get());
while(MeshFile->getNodeName()==string("submesh"))
{
SubMesh* theSubMesh=new SubMesh();
theSubMesh->MaterialName=GetAttribute<string>(MeshFile, "material");
theSubMesh->MaterialName=GetAttribute<string>(MeshFile.get(), "material");
DefaultLogger::get()->debug("Loading Submehs with Material: "+theSubMesh->MaterialName);
ReadSubMesh(*theSubMesh, MeshFile);
ReadSubMesh(*theSubMesh, MeshFile.get());
//just a index in a array, we add a mesh in each loop cycle, so we get indicies like 0, 1, 2 ... n;
//so it is important to do this before pushing the mesh in the vector!
@@ -170,9 +170,9 @@ void OgreImporter::InternReadFile(const std::string &pFile, aiScene *pScene, Ass
vector<Animation> Animations;
if(MeshFile->getNodeName()==string("skeletonlink"))
{
string SkeletonFile=GetAttribute<string>(MeshFile, "name");
string SkeletonFile=GetAttribute<string>(MeshFile.get(), "name");
LoadSkeleton(SkeletonFile, Bones, Animations);
XmlRead(MeshFile);
XmlRead(MeshFile.get());
}
else
{
@@ -185,7 +185,7 @@ void OgreImporter::InternReadFile(const std::string &pFile, aiScene *pScene, Ass
//now there might be boneassignments for the shared geometry:
if(MeshFile->getNodeName()==string("boneassignments"))
{
ReadBoneWeights(m_SharedGeometry, MeshFile);
ReadBoneWeights(m_SharedGeometry, MeshFile.get());
}

View File

@@ -148,12 +148,22 @@ aiMaterial* OgreImporter::LoadMaterial(const std::string MaterialName) const
}
}
}
//Fill the stream
boost::scoped_ptr<IOStream> MaterialFile(MatFilePtr);
vector<char> FileData(MaterialFile->FileSize());
MaterialFile->Read(&FileData[0], MaterialFile->FileSize(), 1);
BaseImporter::ConvertToUTF8(FileData);
if(MaterialFile->FileSize()>0)
{
vector<char> FileData(MaterialFile->FileSize());
MaterialFile->Read(&FileData[0], MaterialFile->FileSize(), 1);
BaseImporter::ConvertToUTF8(FileData);
ss << &FileData[0];
FileData.push_back('\0');//terminate the string with zero, so that the ss can parse it correctly
ss << &FileData[0];
}
else
{
DefaultLogger::get()->warn("Material " + MaterialName + " seams to be empty");
return NULL;
}
}
//create the material

View File

@@ -640,6 +640,7 @@ bool Q3BSPFileImporter::importTextureFromArchive( const Q3BSP::Q3BSPModel *pMode
std::vector<std::string> supportedExtensions;
supportedExtensions.push_back( ".jpg" );
supportedExtensions.push_back( ".png" );
supportedExtensions.push_back( ".tga" );
if ( NULL == pArchive || NULL == pArchive || NULL == pMatHelper )
{
return false;
@@ -670,10 +671,10 @@ bool Q3BSPFileImporter::importTextureFromArchive( const Q3BSP::Q3BSPModel *pMode
(void)readSize;
ai_assert( readSize == pTexture->mWidth );
pTexture->pcData = reinterpret_cast<aiTexel*>( pData );
pTexture->achFormatHint[ 0 ] = ext[ 0 ];
pTexture->achFormatHint[ 1 ] = ext[ 1 ];
pTexture->achFormatHint[ 2 ] = ext[ 2 ];
pTexture->achFormatHint[ 2 ] = '\0';
pTexture->achFormatHint[ 0 ] = ext[ 1 ];
pTexture->achFormatHint[ 1 ] = ext[ 2 ];
pTexture->achFormatHint[ 2 ] = ext[ 3 ];
pTexture->achFormatHint[ 3 ] = '\0';
res = true;
aiString name;

View File

@@ -38,6 +38,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
#include "AssimpPCH.h"
#ifndef ASSIMP_BUILD_NO_Q3BSP_IMPORTER
#include "Q3BSPFileParser.h"
#include "DefaultIOSystem.h"
#include "Q3BSPFileData.h"
@@ -273,3 +276,5 @@ void Q3BSPFileParser::getEntities()
// ------------------------------------------------------------------------------------------------
} // Namespace Assimp
#endif // ASSIMP_BUILD_NO_Q3BSP_IMPORTER

View File

@@ -39,6 +39,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "AssimpPCH.h"
#ifndef ASSIMP_BUILD_NO_Q3BSP_IMPORTER
#include "Q3BSPZipArchive.h"
#include <algorithm>
#include <cassert>
@@ -194,3 +197,5 @@ bool Q3BSPZipArchive::mapArchive()
} // Namespace Q3BSP
} // Namespace Assimp
#endif // ASSIMP_BUILD_NO_Q3BSP_IMPORTER

View File

@@ -684,7 +684,7 @@ void SMDImporter::ParseFile()
const char* szCurrent = mBuffer;
// read line per line ...
while (true)
for ( ;; )
{
if(!SkipSpacesAndLineEnd(szCurrent,&szCurrent)) break;
@@ -750,7 +750,7 @@ unsigned int SMDImporter::GetTextureIndex(const std::string& filename)
void SMDImporter::ParseNodesSection(const char* szCurrent,
const char** szCurrentOut)
{
while (true)
for ( ;; )
{
// "end\n" - Ends the nodes section
if (0 == ASSIMP_strincmp(szCurrent,"end",3) &&
@@ -772,7 +772,7 @@ void SMDImporter::ParseTrianglesSection(const char* szCurrent,
{
// Parse a triangle, parse another triangle, parse the next triangle ...
// and so on until we reach a token that looks quite similar to "end"
while (true)
for ( ;; )
{
if(!SkipSpacesAndLineEnd(szCurrent,&szCurrent)) break;
@@ -790,7 +790,7 @@ void SMDImporter::ParseVASection(const char* szCurrent,
const char** szCurrentOut)
{
unsigned int iCurIndex = 0;
while (true)
for ( ;; )
{
if(!SkipSpacesAndLineEnd(szCurrent,&szCurrent)) break;
@@ -833,7 +833,7 @@ void SMDImporter::ParseSkeletonSection(const char* szCurrent,
const char** szCurrentOut)
{
int iTime = 0;
while (true)
for ( ;; )
{
if(!SkipSpacesAndLineEnd(szCurrent,&szCurrent)) break;
@@ -887,7 +887,7 @@ void SMDImporter::ParseNodeInfo(const char* szCurrent,
else ++szCurrent;
const char* szEnd = szCurrent;
while (true)
for ( ;; )
{
if (bQuota && '\"' == *szEnd)
{

View File

@@ -192,19 +192,19 @@ namespace STEP {
}
// utilities to deal with SELECT entities, which currently lack automatic
// conversion support.
template <typename T>
const T& ResolveSelect(const DB& db) const {
return Couple<T>(db).MustGetObject(To<EXPRESS::ENTITY>())->To<T>();
}
template <typename T>
const T* ResolveSelectPtr(const DB& db) const {
const EXPRESS::ENTITY* e = ToPtr<EXPRESS::ENTITY>();
return e?Couple<T>(db).MustGetObject(*e)->ToPtr<T>():(const T*)0;
}
public:
// conversion support.
template <typename T>
const T& ResolveSelect(const DB& db) const {
return Couple<T>(db).MustGetObject(To<EXPRESS::ENTITY>())->template To<T>();
}
template <typename T>
const T* ResolveSelectPtr(const DB& db) const {
const EXPRESS::ENTITY* e = ToPtr<EXPRESS::ENTITY>();
return e?Couple<T>(db).MustGetObject(*e)->template ToPtr<T>():(const T*)0;
}
public:
/** parse a variable from a string and set 'inout' to the character
* behind the last consumed character. An optional schema enables,

View File

@@ -160,6 +160,30 @@ STEP::DB* STEP::ReadFileHeader(boost::shared_ptr<IOStream> stream)
}
namespace {
// ------------------------------------------------------------------------------------------------
// check whether the given line contains an entity definition (i.e. starts with "#<number>=")
bool IsEntityDef(const std::string& snext)
{
if (snext[0] == '#') {
// it is only a new entity if it has a '=' after the
// entity ID.
for(std::string::const_iterator it = snext.begin()+1; it != snext.end(); ++it) {
if (*it == '=') {
return true;
}
if (*it < '0' || *it > '9') {
break;
}
}
}
return false;
}
}
// ------------------------------------------------------------------------------------------------
void STEP::ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme,
const char* const* types_to_track, size_t len,
@@ -171,8 +195,9 @@ void STEP::ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme,
const DB::ObjectMap& map = db.GetObjects();
LineSplitter& splitter = db.GetSplitter();
for(; splitter; ++splitter) {
const std::string& s = *splitter;
while (splitter) {
bool has_next = false;
std::string s = *splitter;
if (s == "ENDSEC;") {
break;
}
@@ -184,6 +209,7 @@ void STEP::ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme,
ai_assert(s.length());
if (s[0] != '#') {
DefaultLogger::get()->warn(AddLineNumber("expected token \'#\'",line));
++splitter;
continue;
}
@@ -195,25 +221,75 @@ void STEP::ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme,
const std::string::size_type n0 = s.find_first_of('=');
if (n0 == std::string::npos) {
DefaultLogger::get()->warn(AddLineNumber("expected token \'=\'",line));
++splitter;
continue;
}
const uint64_t id = strtoul10_64(s.substr(1,n0-1).c_str());
if (!id) {
DefaultLogger::get()->warn(AddLineNumber("expected positive, numeric entity id",line));
++splitter;
continue;
}
const std::string::size_type n1 = s.find_first_of('(',n0);
std::string::size_type n1 = s.find_first_of('(',n0);
if (n1 == std::string::npos) {
DefaultLogger::get()->warn(AddLineNumber("expected token \'(\'",line));
continue;
has_next = true;
bool ok = false;
for( ++splitter; splitter; ++splitter) {
const std::string& snext = *splitter;
if (snext.empty()) {
continue;
}
// the next line doesn't start an entity, so maybe it is
// just a continuation for this line, keep going
if (!IsEntityDef(snext)) {
s.append(snext);
n1 = s.find_first_of('(',n0);
ok = (n1 != std::string::npos);
}
else {
break;
}
}
if(!ok) {
DefaultLogger::get()->warn(AddLineNumber("expected token \'(\'",line));
continue;
}
}
const std::string::size_type n2 = s.find_last_of(')');
if (n2 == std::string::npos || n2 < n1) {
DefaultLogger::get()->warn(AddLineNumber("expected token \')\'",line));
continue;
std::string::size_type n2 = s.find_last_of(')');
if (n2 == std::string::npos || n2 < n1 || n2 == s.length() - 1 || s[n2 + 1] != ';') {
has_next = true;
bool ok = false;
for( ++splitter; splitter; ++splitter) {
const std::string& snext = *splitter;
if (snext.empty()) {
continue;
}
// the next line doesn't start an entity, so maybe it is
// just a continuation for this line, keep going
if (!IsEntityDef(snext)) {
s.append(snext);
n2 = s.find_last_of(')');
ok = !(n2 == std::string::npos || n2 < n1 || n2 == s.length() - 1 || s[n2 + 1] != ';');
}
else {
break;
}
}
if(!ok) {
DefaultLogger::get()->warn(AddLineNumber("expected token \')\'",line));
continue;
}
}
if (map.find(id) != map.end()) {
@@ -239,6 +315,10 @@ void STEP::ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme,
db.InternInsert(new LazyObject(db,id,line,sz,copysz));
}
if(!has_next) {
++splitter;
}
}
if (!splitter) {

View File

@@ -203,7 +203,7 @@ void STLImporter::LoadASCIIFile()
pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
unsigned int curFace = 0, curVertex = 3;
while (true)
for ( ;; )
{
// go to the next token
if(!SkipSpacesAndLineEnd(&sz))

View File

@@ -87,7 +87,7 @@ inline unsigned int ASSIMP_itoa10( char* out, unsigned int max, int32_t number)
// print all future zeroes from now
mustPrint = true;
*out++ = '0'+digit;
*out++ = '0'+static_cast<char>(digit);
++written;
number -= digit*cur;

View File

@@ -188,6 +188,8 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
FILE* fout = fopen(POLY_OUTPUT_FILE,"a");
#endif
const aiVector3D* verts = pMesh->mVertices;
// use boost::scoped_array to avoid slow std::vector<bool> specialiations
boost::scoped_array<bool> done(new bool[max_out]);
for( unsigned int a = 0; a < pMesh->mNumFaces; a++) {
@@ -216,24 +218,59 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
face.mIndices = NULL;
continue;
} /* does not handle concave quads
}
// optimized code for quadrilaterals
else if ( face.mNumIndices == 4) {
// quads can have at maximum one concave vertex. Determine
// this vertex (if it exists) and start tri-fanning from
// it.
unsigned int start_vertex = 0;
for (unsigned int i = 0; i < 4; ++i) {
const aiVector3D& v0 = verts[face.mIndices[(i+3) % 4]];
const aiVector3D& v1 = verts[face.mIndices[(i+2) % 4]];
const aiVector3D& v2 = verts[face.mIndices[(i+1) % 4]];
const aiVector3D& v = verts[face.mIndices[i]];
aiVector3D left = (v0-v);
aiVector3D diag = (v1-v);
aiVector3D right = (v2-v);
left.Normalize();
diag.Normalize();
right.Normalize();
const float angle = acos(left*diag) + acos(right*diag);
if (angle > AI_MATH_PI_F) {
// this is the concave point
start_vertex = i;
break;
}
}
const unsigned int temp[] = {face.mIndices[0], face.mIndices[1], face.mIndices[2], face.mIndices[3]};
aiFace& nface = *curOut++;
nface.mNumIndices = 3;
nface.mIndices = face.mIndices;
nface.mIndices[0] = temp[start_vertex];
nface.mIndices[1] = temp[(start_vertex + 1) % 4];
nface.mIndices[2] = temp[(start_vertex + 2) % 4];
aiFace& sface = *curOut++;
sface.mNumIndices = 3;
sface.mIndices = new unsigned int[3];
sface.mIndices[0] = face.mIndices[0];
sface.mIndices[1] = face.mIndices[2];
sface.mIndices[2] = face.mIndices[3];
sface.mIndices[0] = temp[start_vertex];
sface.mIndices[1] = temp[(start_vertex + 2) % 4];
sface.mIndices[2] = temp[(start_vertex + 3) % 4];
// prevent double deletion of the indices field
face.mIndices = NULL;
continue;
} */
}
else
{
// A polygon with more than 3 vertices can be either concave or convex.
@@ -246,7 +283,6 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
// We project it onto a plane to get a 2d triangle.
// Collect all vertices of of the polygon.
const aiVector3D* verts = pMesh->mVertices;
for (tmp = 0; tmp < max; ++tmp) {
temp_verts3d[tmp] = verts[idx[tmp]];
}

View File

@@ -52,7 +52,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace Assimp;
static const aiImporterDesc desc = {
"Collada Importer",
"Direct3D XFile Importer",
"",
"",
"",
@@ -594,8 +594,9 @@ void XFileImporter::ConvertMaterials( aiScene* pScene, const std::vector<XFile::
mat->AddProperty<int>( &shadeMode, 1, AI_MATKEY_SHADING_MODEL);
// material colours
// FIX: Setup this as ambient not as emissive color
mat->AddProperty( &oldMat.mEmissive, 1, AI_MATKEY_COLOR_AMBIENT);
// Unclear: there's no ambient colour, but emissive. What to put for ambient?
// Probably nothing at all, let the user select a suitable default.
mat->AddProperty( &oldMat.mEmissive, 1, AI_MATKEY_COLOR_EMISSIVE);
mat->AddProperty( &oldMat.mDiffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
mat->AddProperty( &oldMat.mSpecular, 1, AI_MATKEY_COLOR_SPECULAR);
mat->AddProperty( &oldMat.mSpecularExponent, 1, AI_MATKEY_SHININESS);

View File

@@ -460,7 +460,7 @@ void XFileParser::ParseDataObjectMesh( Mesh* pMesh)
Face& face = pMesh->mPosFaces[a];
for( unsigned int b = 0; b < numIndices; b++)
face.mIndices.push_back( ReadInt());
CheckForSeparator();
TestForSeparator();
}
// here, other data objects may follow
@@ -583,7 +583,7 @@ void XFileParser::ParseDataObjectMeshNormals( Mesh* pMesh)
for( unsigned int b = 0; b < numIndices; b++)
face.mIndices.push_back( ReadInt());
CheckForSeparator();
TestForSeparator();
}
CheckForClosingBrace();