commit
a58d0f57b3
|
@ -94,7 +94,11 @@ SET( ASSIMP_INCLUDE_INSTALL_DIR "include" CACHE PATH
|
|||
SET( ASSIMP_BIN_INSTALL_DIR "bin" CACHE PATH
|
||||
"Path the tool executables are installed to." )
|
||||
|
||||
SET(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "Debug Postfitx for lib, samples and tools")
|
||||
IF (CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
SET(CMAKE_DEBUG_POSTFIX "" CACHE STRING "Debug Postfix for lib, samples and tools")
|
||||
ELSE()
|
||||
SET(CMAKE_DEBUG_POSTFIX "d" CACHE STRING "Debug Postfix for lib, samples and tools")
|
||||
ENDIF()
|
||||
|
||||
# Only generate this target if no higher-level project already has
|
||||
IF (NOT TARGET uninstall)
|
||||
|
|
|
@ -89,6 +89,9 @@ static const aiImporterDesc desc = {
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
// read a string (may be enclosed in double quotation marks). buffer must point to "
|
||||
#define AI_AC_GET_STRING(out) \
|
||||
if (*buffer == '\0') { \
|
||||
throw DeadlyImportError("AC3D: Unexpected EOF in string"); \
|
||||
} \
|
||||
++buffer; \
|
||||
const char* sz = buffer; \
|
||||
while ('\"' != *buffer) \
|
||||
|
@ -293,7 +296,7 @@ void AC3DImporter::LoadObjectSection(std::vector<Object>& objects)
|
|||
SkipSpaces(&buffer);
|
||||
|
||||
unsigned int t = strtoul10(buffer,&buffer);
|
||||
if (t >= std::numeric_limits<int32_t>::max() / sizeof(aiVector3D)) {
|
||||
if (t >= AI_MAX_ALLOC(aiVector3D)) {
|
||||
throw DeadlyImportError("AC3D: Too many vertices, would run out of memory");
|
||||
}
|
||||
obj.vertices.reserve(t);
|
||||
|
@ -349,8 +352,7 @@ void AC3DImporter::LoadObjectSection(std::vector<Object>& objects)
|
|||
{
|
||||
if(!GetNextLine())
|
||||
{
|
||||
DefaultLogger::get()->error("AC3D: Unexpected EOF: surface is incomplete");
|
||||
break;
|
||||
throw DeadlyImportError("AC3D: Unexpected EOF: surface is incomplete");
|
||||
}
|
||||
if (TokenMatch(buffer,"mat",3))
|
||||
{
|
||||
|
@ -585,9 +587,19 @@ aiNode* AC3DImporter::ConvertObjectSection(Object& object,
|
|||
|
||||
// allocate storage for vertices and normals
|
||||
mesh->mNumFaces = (*cit).first;
|
||||
if (mesh->mNumFaces == 0) {
|
||||
throw DeadlyImportError("AC3D: No faces");
|
||||
} else if (mesh->mNumFaces > AI_MAX_ALLOC(aiFace)) {
|
||||
throw DeadlyImportError("AC3D: Too many faces, would run out of memory");
|
||||
}
|
||||
aiFace* faces = mesh->mFaces = new aiFace[mesh->mNumFaces];
|
||||
|
||||
mesh->mNumVertices = (*cit).second;
|
||||
if (mesh->mNumVertices == 0) {
|
||||
throw DeadlyImportError("AC3D: No vertices");
|
||||
} else if (mesh->mNumVertices > AI_MAX_ALLOC(aiVector3D)) {
|
||||
throw DeadlyImportError("AC3D: Too many vertices, would run out of memory");
|
||||
}
|
||||
aiVector3D* vertices = mesh->mVertices = new aiVector3D[mesh->mNumVertices];
|
||||
unsigned int cur = 0;
|
||||
|
||||
|
|
|
@ -103,7 +103,7 @@ struct Image;
|
|||
// -------------------------------------------------------------------------------
|
||||
struct ID : ElemBase {
|
||||
|
||||
char name[24] WARN;
|
||||
char name[1024] WARN;
|
||||
short flag;
|
||||
};
|
||||
|
||||
|
|
|
@ -47,6 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#ifndef ASSIMP_BUILD_NO_COLLADA_IMPORTER
|
||||
|
||||
#include <sstream>
|
||||
#include <stdarg.h>
|
||||
#include "ColladaParser.h"
|
||||
#include "fast_atof.h"
|
||||
#include "ParsingUtils.h"
|
||||
|
@ -1066,6 +1067,12 @@ void ColladaParser::ReadLight( Collada::Light& pLight)
|
|||
pLight.mFalloffAngle = ReadFloatFromTextContent();
|
||||
TestClosing("hotspot_beam");
|
||||
}
|
||||
// OpenCOLLADA extensions
|
||||
// -------------------------------------------------------
|
||||
else if (IsElement("decay_falloff")) {
|
||||
pLight.mOuterAngle = ReadFloatFromTextContent();
|
||||
TestClosing("decay_falloff");
|
||||
}
|
||||
}
|
||||
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END) {
|
||||
if( strcmp( mReader->getNodeName(), "light") == 0)
|
||||
|
@ -1998,7 +2005,8 @@ void ColladaParser::ReadIndexData( Mesh* pMesh)
|
|||
}
|
||||
|
||||
#ifdef ASSIMP_BUILD_DEBUG
|
||||
if (primType != Prim_TriFans && primType != Prim_TriStrips) {
|
||||
if (primType != Prim_TriFans && primType != Prim_TriStrips &&
|
||||
primType != Prim_Lines) { // this is ONLY to workaround a bug in SketchUp 15.3.331 where it writes the wrong 'count' when it writes out the 'lines'.
|
||||
ai_assert(actualPrimitives == numPrimitives);
|
||||
}
|
||||
#endif
|
||||
|
@ -2108,9 +2116,15 @@ size_t ColladaParser::ReadPrimitives( Mesh* pMesh, std::vector<InputChannel>& pP
|
|||
}
|
||||
|
||||
// complain if the index count doesn't fit
|
||||
if( expectedPointCount > 0 && indices.size() != expectedPointCount * numOffsets)
|
||||
if( expectedPointCount > 0 && indices.size() != expectedPointCount * numOffsets) {
|
||||
if (pPrimType == Prim_Lines) {
|
||||
// HACK: We just fix this number since SketchUp 15.3.331 writes the wrong 'count' for 'lines'
|
||||
ReportWarning( "Expected different index count in <p> element, %d instead of %d.", indices.size(), expectedPointCount * numOffsets);
|
||||
pNumPrimitives = (indices.size() / numOffsets) / 2;
|
||||
} else
|
||||
ThrowException( "Expected different index count in <p> element.");
|
||||
else if( expectedPointCount == 0 && (indices.size() % numOffsets) != 0)
|
||||
|
||||
} else if( expectedPointCount == 0 && (indices.size() % numOffsets) != 0)
|
||||
ThrowException( "Expected different index count in <p> element.");
|
||||
|
||||
// find the data for all sources
|
||||
|
@ -2712,6 +2726,21 @@ AI_WONT_RETURN void ColladaParser::ThrowException( const std::string& pError) co
|
|||
{
|
||||
throw DeadlyImportError( boost::str( boost::format( "Collada: %s - %s") % mFileName % pError));
|
||||
}
|
||||
void ColladaParser::ReportWarning(const char* msg,...)
|
||||
{
|
||||
ai_assert(NULL != msg);
|
||||
|
||||
va_list args;
|
||||
va_start(args,msg);
|
||||
|
||||
char szBuffer[3000];
|
||||
const int iLen = vsprintf(szBuffer,msg,args);
|
||||
ai_assert(iLen > 0);
|
||||
|
||||
va_end(args);
|
||||
DefaultLogger::get()->warn("Validation warning: " + std::string(szBuffer,iLen));
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Skips all data until the end node of the current element
|
||||
|
|
|
@ -215,6 +215,7 @@ protected:
|
|||
protected:
|
||||
/** Aborts the file reading with an exception */
|
||||
AI_WONT_RETURN void ThrowException( const std::string& pError) const AI_WONT_RETURN_SUFFIX;
|
||||
void ReportWarning(const char* msg,...);
|
||||
|
||||
/** Skips all data until the end node of the current element */
|
||||
void SkipElement();
|
||||
|
|
|
@ -152,8 +152,8 @@ bool FixInfacingNormalsProcess::ProcessMesh( aiMesh* pcMesh, unsigned int index)
|
|||
if (fDelta1_z < 0.05f * sqrtf( fDelta1_y * fDelta1_x ))return false;
|
||||
|
||||
// now compare the volumes of the bounding boxes
|
||||
if (std::fabs(fDelta0_x * fDelta1_yz) <
|
||||
std::fabs(fDelta1_x * fDelta1_y * fDelta1_z))
|
||||
if (std::fabs(fDelta0_x * fDelta0_y * fDelta0_z) <
|
||||
std::fabs(fDelta1_x * fDelta1_yz))
|
||||
{
|
||||
if (!DefaultLogger::isNullLogger())
|
||||
{
|
||||
|
|
|
@ -602,12 +602,12 @@ bool IntersectingLineSegments(const IfcVector2& n0, const IfcVector2& n1,
|
|||
const IfcVector2& m0, const IfcVector2& m1,
|
||||
IfcVector2& out0, IfcVector2& out1)
|
||||
{
|
||||
const IfcVector2& n0_to_n1 = n1 - n0;
|
||||
const IfcVector2 n0_to_n1 = n1 - n0;
|
||||
|
||||
const IfcVector2& n0_to_m0 = m0 - n0;
|
||||
const IfcVector2& n1_to_m1 = m1 - n1;
|
||||
const IfcVector2 n0_to_m0 = m0 - n0;
|
||||
const IfcVector2 n1_to_m1 = m1 - n1;
|
||||
|
||||
const IfcVector2& n0_to_m1 = m1 - n0;
|
||||
const IfcVector2 n0_to_m1 = m1 - n0;
|
||||
|
||||
const IfcFloat e = 1e-5f;
|
||||
const IfcFloat smalle = 1e-9f;
|
||||
|
@ -927,7 +927,7 @@ size_t CloseWindows(ContourVector& contours,
|
|||
IfcFloat best = static_cast<IfcFloat>(1e10);
|
||||
IfcVector3 bestv;
|
||||
|
||||
const IfcVector3& world_point = minv * IfcVector3(proj_point.x,proj_point.y,0.0f);
|
||||
const IfcVector3 world_point = minv * IfcVector3(proj_point.x,proj_point.y,0.0f);
|
||||
|
||||
BOOST_FOREACH(const TempOpening* opening, refs) {
|
||||
BOOST_FOREACH(const IfcVector3& other, opening->wallPoints) {
|
||||
|
@ -1066,7 +1066,7 @@ IfcMatrix4 ProjectOntoPlane(std::vector<IfcVector2>& out_contour, const TempMesh
|
|||
|
||||
// Project all points into the new coordinate system, collect min/max verts on the way
|
||||
BOOST_FOREACH(const IfcVector3& x, in_verts) {
|
||||
const IfcVector3& vv = m * x;
|
||||
const IfcVector3 vv = m * x;
|
||||
// keep Z offset in the plane coordinate system. Ignoring precision issues
|
||||
// (which are present, of course), this should be the same value for
|
||||
// all polygon vertices (assuming the polygon is planar).
|
||||
|
@ -1144,7 +1144,7 @@ bool GenerateOpenings(std::vector<TempOpening>& openings,
|
|||
std::vector<IfcVector2> contour_flat;
|
||||
|
||||
IfcVector3 nor;
|
||||
const IfcMatrix4& m = ProjectOntoPlane(contour_flat, curmesh, ok, nor);
|
||||
const IfcMatrix4 m = ProjectOntoPlane(contour_flat, curmesh, ok, nor);
|
||||
if(!ok) {
|
||||
return false;
|
||||
}
|
||||
|
@ -1227,7 +1227,7 @@ bool GenerateOpenings(std::vector<TempOpening>& openings,
|
|||
|
||||
bool side_flag = true;
|
||||
if (!is_2d_source) {
|
||||
const IfcVector3& face_nor = ((profile_verts[vi_total+2] - profile_verts[vi_total]) ^
|
||||
const IfcVector3 face_nor = ((profile_verts[vi_total+2] - profile_verts[vi_total]) ^
|
||||
(profile_verts[vi_total+1] - profile_verts[vi_total])).Normalize();
|
||||
|
||||
const IfcFloat abs_dot_face_nor = std::abs(nor * face_nor);
|
||||
|
@ -1242,7 +1242,7 @@ bool GenerateOpenings(std::vector<TempOpening>& openings,
|
|||
for (unsigned int vi = 0, vend = profile_vertcnts[f]; vi < vend; ++vi, ++vi_total) {
|
||||
const IfcVector3& x = profile_verts[vi_total];
|
||||
|
||||
const IfcVector3& v = m * x;
|
||||
const IfcVector3 v = m * x;
|
||||
IfcVector2 vv(v.x, v.y);
|
||||
|
||||
//if(check_intersection) {
|
||||
|
@ -1322,7 +1322,7 @@ bool GenerateOpenings(std::vector<TempOpening>& openings,
|
|||
MakeDisjunctWindowContours(other, temp_contour, poly);
|
||||
if(poly.size() == 1) {
|
||||
|
||||
const BoundingBox& newbb = GetBoundingBox(poly[0].outer);
|
||||
const BoundingBox newbb = GetBoundingBox(poly[0].outer);
|
||||
if (!BoundingBoxesOverlapping(ibb, newbb )) {
|
||||
// Good guy bounding box
|
||||
bb = newbb ;
|
||||
|
@ -1438,7 +1438,7 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,const std:
|
|||
// working coordinate system.
|
||||
bool ok;
|
||||
IfcVector3 nor;
|
||||
const IfcMatrix3& m = DerivePlaneCoordinateSpace(curmesh, ok, nor);
|
||||
const IfcMatrix3 m = DerivePlaneCoordinateSpace(curmesh, ok, nor);
|
||||
if (!ok) {
|
||||
return false;
|
||||
}
|
||||
|
@ -1686,13 +1686,13 @@ bool TryAddOpenings_Poly2Tri(const std::vector<TempOpening>& openings,const std:
|
|||
continue;
|
||||
}
|
||||
|
||||
const std::vector<p2t::Triangle*>& tris = cdt->GetTriangles();
|
||||
const std::vector<p2t::Triangle*> tris = cdt->GetTriangles();
|
||||
|
||||
// Collect the triangles we just produced
|
||||
BOOST_FOREACH(p2t::Triangle* tri, tris) {
|
||||
for(int i = 0; i < 3; ++i) {
|
||||
|
||||
const IfcVector2& v = IfcVector2(
|
||||
const IfcVector2 v = IfcVector2(
|
||||
static_cast<IfcFloat>( tri->GetPoint(i)->x ),
|
||||
static_cast<IfcFloat>( tri->GetPoint(i)->y )
|
||||
);
|
||||
|
|
|
@ -954,6 +954,9 @@ inline void LWOImporter::DoRecursiveVMAPAssignment(VMapEntry* base, unsigned int
|
|||
LWO::ReferrerList& refList = mCurLayer->mPointReferrers;
|
||||
unsigned int i;
|
||||
|
||||
if (idx >= base->abAssigned.size()) {
|
||||
throw DeadlyImportError("Bad index");
|
||||
}
|
||||
base->abAssigned[idx] = true;
|
||||
for (i = 0; i < numRead;++i) {
|
||||
base->rawData[idx*base->dims+i]= data[i];
|
||||
|
|
|
@ -783,6 +783,13 @@ void MD3Importer::InternReadFile( const std::string& pFile,
|
|||
|
||||
// Allocate output storage
|
||||
pScene->mNumMeshes = pcHeader->NUM_SURFACES;
|
||||
if (pcHeader->NUM_SURFACES == 0) {
|
||||
throw DeadlyImportError("MD3: No surfaces");
|
||||
} else if (pcHeader->NUM_SURFACES > AI_MAX_ALLOC(aiMesh)) {
|
||||
// We allocate pointers but check against the size of aiMesh
|
||||
// since those pointers will eventually have to point to real objects
|
||||
throw DeadlyImportError("MD3: Too many surfaces, would run out of memory");
|
||||
}
|
||||
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
|
||||
|
||||
pScene->mNumMaterials = pcHeader->NUM_SURFACES;
|
||||
|
|
|
@ -355,6 +355,9 @@ void MDLImporter::InternReadFile_Quake1( )
|
|||
for (unsigned int i = 0; i < (unsigned int)pcHeader->num_skins;++i)
|
||||
{
|
||||
union{BE_NCONST MDL::Skin* pcSkin;BE_NCONST MDL::GroupSkin* pcGroupSkin;};
|
||||
if (szCurrent + sizeof(MDL::Skin) > this->mBuffer + this->iFileSize) {
|
||||
throw DeadlyImportError("[Quake 1 MDL] Unexpected EOF");
|
||||
}
|
||||
pcSkin = (BE_NCONST MDL::Skin*)szCurrent;
|
||||
|
||||
AI_SWAP4( pcSkin->group );
|
||||
|
|
|
@ -133,15 +133,16 @@ void ObjFileImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
|
|||
TextFileToBuffer(file.get(),m_Buffer);
|
||||
|
||||
// Get the model name
|
||||
std::string strModelName;
|
||||
std::string modelName, folderName;
|
||||
std::string::size_type pos = pFile.find_last_of( "\\/" );
|
||||
if ( pos != std::string::npos )
|
||||
{
|
||||
strModelName = pFile.substr(pos+1, pFile.size() - pos - 1);
|
||||
if ( pos != std::string::npos ) {
|
||||
modelName = pFile.substr(pos+1, pFile.size() - pos - 1);
|
||||
folderName = pFile.substr( 0, pos );
|
||||
if ( folderName.empty() ) {
|
||||
pIOHandler->PushDirectory( folderName );
|
||||
}
|
||||
else
|
||||
{
|
||||
strModelName = pFile;
|
||||
} else {
|
||||
modelName = pFile;
|
||||
}
|
||||
|
||||
// process all '\'
|
||||
|
@ -161,13 +162,18 @@ void ObjFileImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
|
|||
}
|
||||
|
||||
// parse the file into a temporary representation
|
||||
ObjFileParser parser(m_Buffer, strModelName, pIOHandler);
|
||||
ObjFileParser parser(m_Buffer, modelName, pIOHandler);
|
||||
|
||||
// And create the proper return structures out of it
|
||||
CreateDataFromImport(parser.GetModel(), pScene);
|
||||
|
||||
// Clean up allocated storage for the next import
|
||||
m_Buffer.clear();
|
||||
|
||||
// Pop directory stack
|
||||
if ( pIOHandler->StackSize() > 0 ) {
|
||||
pIOHandler->PopDirectory();
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
@ -380,6 +386,11 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
|
|||
|
||||
// Copy vertices of this mesh instance
|
||||
pMesh->mNumVertices = numIndices;
|
||||
if (pMesh->mNumVertices == 0) {
|
||||
throw DeadlyImportError( "OBJ: no vertices" );
|
||||
} else if (pMesh->mNumVertices > AI_MAX_ALLOC(aiVector3D)) {
|
||||
throw DeadlyImportError( "OBJ: Too many vertices, would run out of memory" );
|
||||
}
|
||||
pMesh->mVertices = new aiVector3D[ pMesh->mNumVertices ];
|
||||
|
||||
// Allocate buffer for normal vectors
|
||||
|
|
|
@ -61,21 +61,21 @@ const std::string ObjFileParser::DEFAULT_MATERIAL = AI_DEFAULT_MATERIAL_NAME;
|
|||
|
||||
// -------------------------------------------------------------------
|
||||
// Constructor with loaded data and directories.
|
||||
ObjFileParser::ObjFileParser(std::vector<char> &Data,const std::string &strModelName, IOSystem *io ) :
|
||||
m_DataIt(Data.begin()),
|
||||
m_DataItEnd(Data.end()),
|
||||
ObjFileParser::ObjFileParser(std::vector<char> &data,const std::string &modelName, IOSystem *io ) :
|
||||
m_DataIt(data.begin()),
|
||||
m_DataItEnd(data.end()),
|
||||
m_pModel(NULL),
|
||||
m_uiLine(0),
|
||||
m_pIO( io )
|
||||
{
|
||||
std::fill_n(m_buffer,BUFFERSIZE,0);
|
||||
std::fill_n(m_buffer,Buffersize,0);
|
||||
|
||||
// Create the model instance to store all the data
|
||||
m_pModel = new ObjFile::Model();
|
||||
m_pModel->m_ModelName = strModelName;
|
||||
m_pModel->m_ModelName = modelName;
|
||||
|
||||
// create default material and store it
|
||||
m_pModel->m_pDefaultMaterial = new ObjFile::Material();
|
||||
m_pModel->m_pDefaultMaterial = new ObjFile::Material;
|
||||
m_pModel->m_pDefaultMaterial->MaterialName.Set( DEFAULT_MATERIAL );
|
||||
m_pModel->m_MaterialLib.push_back( DEFAULT_MATERIAL );
|
||||
m_pModel->m_MaterialMap[ DEFAULT_MATERIAL ] = m_pModel->m_pDefaultMaterial;
|
||||
|
@ -248,20 +248,20 @@ void ObjFileParser::getVector( std::vector<aiVector3D> &point3d_array ) {
|
|||
}
|
||||
float x, y, z;
|
||||
if( 2 == numComponents ) {
|
||||
copyNextWord( m_buffer, BUFFERSIZE );
|
||||
copyNextWord( m_buffer, Buffersize );
|
||||
x = ( float ) fast_atof( m_buffer );
|
||||
|
||||
copyNextWord( m_buffer, BUFFERSIZE );
|
||||
copyNextWord( m_buffer, Buffersize );
|
||||
y = ( float ) fast_atof( m_buffer );
|
||||
z = 0.0;
|
||||
} else if( 3 == numComponents ) {
|
||||
copyNextWord( m_buffer, BUFFERSIZE );
|
||||
copyNextWord( m_buffer, Buffersize );
|
||||
x = ( float ) fast_atof( m_buffer );
|
||||
|
||||
copyNextWord( m_buffer, BUFFERSIZE );
|
||||
copyNextWord( m_buffer, Buffersize );
|
||||
y = ( float ) fast_atof( m_buffer );
|
||||
|
||||
copyNextWord( m_buffer, BUFFERSIZE );
|
||||
copyNextWord( m_buffer, Buffersize );
|
||||
z = ( float ) fast_atof( m_buffer );
|
||||
} else {
|
||||
throw DeadlyImportError( "OBJ: Invalid number of components" );
|
||||
|
@ -274,13 +274,13 @@ void ObjFileParser::getVector( std::vector<aiVector3D> &point3d_array ) {
|
|||
// Get values for a new 3D vector instance
|
||||
void ObjFileParser::getVector3(std::vector<aiVector3D> &point3d_array) {
|
||||
float x, y, z;
|
||||
copyNextWord(m_buffer, BUFFERSIZE);
|
||||
copyNextWord(m_buffer, Buffersize);
|
||||
x = (float) fast_atof(m_buffer);
|
||||
|
||||
copyNextWord(m_buffer, BUFFERSIZE);
|
||||
copyNextWord(m_buffer, Buffersize);
|
||||
y = (float) fast_atof(m_buffer);
|
||||
|
||||
copyNextWord( m_buffer, BUFFERSIZE );
|
||||
copyNextWord( m_buffer, Buffersize );
|
||||
z = ( float ) fast_atof( m_buffer );
|
||||
|
||||
point3d_array.push_back( aiVector3D( x, y, z ) );
|
||||
|
@ -291,10 +291,10 @@ void ObjFileParser::getVector3(std::vector<aiVector3D> &point3d_array) {
|
|||
// Get values for a new 2D vector instance
|
||||
void ObjFileParser::getVector2( std::vector<aiVector2D> &point2d_array ) {
|
||||
float x, y;
|
||||
copyNextWord(m_buffer, BUFFERSIZE);
|
||||
copyNextWord(m_buffer, Buffersize);
|
||||
x = (float) fast_atof(m_buffer);
|
||||
|
||||
copyNextWord(m_buffer, BUFFERSIZE);
|
||||
copyNextWord(m_buffer, Buffersize);
|
||||
y = (float) fast_atof(m_buffer);
|
||||
|
||||
point2d_array.push_back(aiVector2D(x, y));
|
||||
|
@ -306,12 +306,12 @@ void ObjFileParser::getVector2( std::vector<aiVector2D> &point2d_array ) {
|
|||
// Get values for a new face instance
|
||||
void ObjFileParser::getFace(aiPrimitiveType type)
|
||||
{
|
||||
copyNextLine(m_buffer, BUFFERSIZE);
|
||||
copyNextLine(m_buffer, Buffersize);
|
||||
if (m_DataIt == m_DataItEnd)
|
||||
return;
|
||||
|
||||
char *pPtr = m_buffer;
|
||||
char *pEnd = &pPtr[BUFFERSIZE];
|
||||
char *pEnd = &pPtr[Buffersize];
|
||||
pPtr = getNextToken<char*>(pPtr, pEnd);
|
||||
if (pPtr == pEnd || *pPtr == '\0')
|
||||
return;
|
||||
|
@ -468,8 +468,9 @@ void ObjFileParser::getMaterialDesc()
|
|||
|
||||
// Get next data for material data
|
||||
m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
|
||||
if (m_DataIt == m_DataItEnd)
|
||||
if (m_DataIt == m_DataItEnd) {
|
||||
return;
|
||||
}
|
||||
|
||||
char *pStart = &(*m_DataIt);
|
||||
while( m_DataIt != m_DataItEnd && !IsLineEnd( *m_DataIt ) ) {
|
||||
|
@ -483,14 +484,11 @@ void ObjFileParser::getMaterialDesc()
|
|||
|
||||
// Search for material
|
||||
std::map<std::string, ObjFile::Material*>::iterator it = m_pModel->m_MaterialMap.find( strName );
|
||||
if ( it == m_pModel->m_MaterialMap.end() )
|
||||
{
|
||||
if ( it == m_pModel->m_MaterialMap.end() ) {
|
||||
// Not found, use default material
|
||||
m_pModel->m_pCurrentMaterial = m_pModel->m_pDefaultMaterial;
|
||||
DefaultLogger::get()->error("OBJ: failed to locate material " + strName + ", skipping");
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// Found, using detected material
|
||||
m_pModel->m_pCurrentMaterial = (*it).second;
|
||||
if ( needsNewMesh( strName ))
|
||||
|
@ -539,10 +537,16 @@ void ObjFileParser::getMaterialLib()
|
|||
|
||||
// Check for existence
|
||||
const std::string strMatName(pStart, &(*m_DataIt));
|
||||
IOStream *pFile = m_pIO->Open(strMatName);
|
||||
std::string absName;
|
||||
if ( m_pIO->StackSize() > 0 ) {
|
||||
const std::string &path = m_pIO->CurrentDirectory();
|
||||
absName = path + strMatName;
|
||||
} else {
|
||||
absName = strMatName;
|
||||
}
|
||||
IOStream *pFile = m_pIO->Open( absName );
|
||||
|
||||
if (!pFile )
|
||||
{
|
||||
if (!pFile ) {
|
||||
DefaultLogger::get()->error( "OBJ: Unable to locate material file " + strMatName );
|
||||
m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
|
||||
return;
|
||||
|
|
|
@ -62,10 +62,9 @@ class IOSystem;
|
|||
|
||||
/// \class ObjFileParser
|
||||
/// \brief Parser for a obj waveform file
|
||||
class ObjFileParser
|
||||
{
|
||||
class ObjFileParser {
|
||||
public:
|
||||
static const size_t BUFFERSIZE = 4096;
|
||||
static const size_t Buffersize = 4096;
|
||||
typedef std::vector<char> DataArray;
|
||||
typedef std::vector<char>::iterator DataArrayIt;
|
||||
typedef std::vector<char>::const_iterator ConstDataArrayIt;
|
||||
|
@ -137,9 +136,10 @@ private:
|
|||
//! Current line (for debugging)
|
||||
unsigned int m_uiLine;
|
||||
//! Helper buffer
|
||||
char m_buffer[BUFFERSIZE];
|
||||
char m_buffer[Buffersize];
|
||||
/// Pointer to IO system instance.
|
||||
IOSystem *m_pIO;
|
||||
/// Path to the current model
|
||||
};
|
||||
|
||||
} // Namespace Assimp
|
||||
|
|
|
@ -63,23 +63,23 @@ static const aiImporterDesc desc = {
|
|||
};
|
||||
|
||||
namespace Grammar {
|
||||
static const char *MetricType = "Metric";
|
||||
static const char *Metric_DistanceType = "distance";
|
||||
static const char *Metric_AngleType = "angle";
|
||||
static const char *Metric_TimeType = "time";
|
||||
static const char *Metric_UpType = "up";
|
||||
static const char *NameType = "Name";
|
||||
static const char *ObjectRefType = "ObjectRef";
|
||||
static const char *MaterialRefType = "MaterialRef";
|
||||
static const char *MetricKeyType = "key";
|
||||
static const char *GeometryNodeType = "GeometryNode";
|
||||
static const char *GeometryObjectType = "GeometryObject";
|
||||
static const char *TransformType = "Transform";
|
||||
static const char *MeshType = "Mesh";
|
||||
static const char *VertexArrayType = "VertexArray";
|
||||
static const char *IndexArrayType = "IndexArray";
|
||||
static const char *MaterialType = "Material";
|
||||
static const char *ColorType = "Color";
|
||||
static const std::string MetricType = "Metric";
|
||||
static const std::string Metric_DistanceType = "distance";
|
||||
static const std::string Metric_AngleType = "angle";
|
||||
static const std::string Metric_TimeType = "time";
|
||||
static const std::string Metric_UpType = "up";
|
||||
static const std::string NameType = "Name";
|
||||
static const std::string ObjectRefType = "ObjectRef";
|
||||
static const std::string MaterialRefType = "MaterialRef";
|
||||
static const std::string MetricKeyType = "key";
|
||||
static const std::string GeometryNodeType = "GeometryNode";
|
||||
static const std::string GeometryObjectType = "GeometryObject";
|
||||
static const std::string TransformType = "Transform";
|
||||
static const std::string MeshType = "Mesh";
|
||||
static const std::string VertexArrayType = "VertexArray";
|
||||
static const std::string IndexArrayType = "IndexArray";
|
||||
static const std::string MaterialType = "Material";
|
||||
static const std::string ColorType = "Color";
|
||||
static const std::string DiffuseColorToken = "diffuse";
|
||||
static const std::string SpecularColorToken = "specular";
|
||||
static const std::string EmissionColorToken = "emission";
|
||||
|
@ -112,7 +112,7 @@ namespace Grammar {
|
|||
TextureToken
|
||||
};
|
||||
|
||||
static const char *ValidMetricToken[ 4 ] = {
|
||||
static const std::string ValidMetricToken[ 4 ] = {
|
||||
Metric_DistanceType,
|
||||
Metric_AngleType,
|
||||
Metric_TimeType,
|
||||
|
@ -126,7 +126,7 @@ namespace Grammar {
|
|||
|
||||
int idx( -1 );
|
||||
for( size_t i = 0; i < 4; i++ ) {
|
||||
if( 0 == strncmp( ValidMetricToken[ i ], token, strlen( token ) ) ) {
|
||||
if( ValidMetricToken[ i ] == token ) {
|
||||
idx = (int) i;
|
||||
break;
|
||||
}
|
||||
|
@ -136,45 +136,33 @@ namespace Grammar {
|
|||
}
|
||||
|
||||
static TokenType matchTokenType( const char *tokenType ) {
|
||||
if( 0 == strncmp( MetricType, tokenType, strlen( MetricType ) ) ) {
|
||||
if( MetricType == tokenType ) {
|
||||
return MetricToken;
|
||||
} else if( 0 == strncmp( NameType, tokenType, strlen( NameType ) ) ) {
|
||||
} else if( NameType == tokenType ) {
|
||||
return NameToken;
|
||||
}
|
||||
else if( 0 == strncmp( ObjectRefType, tokenType, strlen( ObjectRefType ) ) ) {
|
||||
} else if( ObjectRefType == tokenType ) {
|
||||
return ObjectRefToken;
|
||||
}
|
||||
else if( 0 == strncmp( MaterialRefType, tokenType, strlen( MaterialRefType ) ) ) {
|
||||
} else if( MaterialRefType == tokenType ) {
|
||||
return MaterialRefToken;
|
||||
}
|
||||
else if( 0 == strncmp( MetricKeyType, tokenType, strlen( MetricKeyType ) ) ) {
|
||||
} else if( MetricKeyType == tokenType ) {
|
||||
return MetricKeyToken;
|
||||
}
|
||||
else if( 0 == strncmp( GeometryNodeType, tokenType, strlen( GeometryNodeType ) ) ) {
|
||||
} else if( GeometryNodeType == tokenType ) {
|
||||
return GeometryNodeToken;
|
||||
}
|
||||
else if( 0 == strncmp( GeometryObjectType, tokenType, strlen( GeometryObjectType ) ) ) {
|
||||
} else if( GeometryObjectType == tokenType ) {
|
||||
return GeometryObjectToken;
|
||||
}
|
||||
else if( 0 == strncmp( TransformType, tokenType, strlen( TransformType ) ) ) {
|
||||
} else if( TransformType == tokenType ) {
|
||||
return TransformToken;
|
||||
}
|
||||
else if( 0 == strncmp( MeshType, tokenType, strlen( MeshType ) ) ) {
|
||||
} else if( MeshType == tokenType ) {
|
||||
return MeshToken;
|
||||
}
|
||||
else if( 0 == strncmp( VertexArrayType, tokenType, strlen( VertexArrayType ) ) ) {
|
||||
} else if( VertexArrayType == tokenType ) {
|
||||
return VertexArrayToken;
|
||||
}
|
||||
else if( 0 == strncmp( IndexArrayType, tokenType, strlen( IndexArrayType ) ) ) {
|
||||
} else if( IndexArrayType == tokenType ) {
|
||||
return IndexArrayToken;
|
||||
}
|
||||
else if( 0 == strncmp( MaterialType, tokenType, strlen( MaterialType ) ) ) {
|
||||
} else if( MaterialType == tokenType ) {
|
||||
return MaterialToken;
|
||||
}
|
||||
else if( 0 == strncmp( ColorType, tokenType, strlen( ColorType ) ) ) {
|
||||
} else if( ColorType == tokenType ) {
|
||||
return ColorToken;
|
||||
}
|
||||
else if( 0 == strncmp( TextureType, tokenType, strlen( TextureType ) ) ) {
|
||||
} else if( TextureType == tokenType ) {
|
||||
return TextureToken;
|
||||
}
|
||||
|
||||
|
|
|
@ -189,7 +189,12 @@ PlyExporter::PlyExporter(const char* _filename, const aiScene* pScene, bool bina
|
|||
}
|
||||
|
||||
mOutput << "element face " << faces << endl;
|
||||
mOutput << "property list uint uint vertex_index" << endl;
|
||||
|
||||
// uchar seems to be the most common type for the number of indices per polygon and int seems to be most common for the vertex indices.
|
||||
// For instance, MeshLab fails to load meshes in which both types are uint. Houdini seems to have problems as well.
|
||||
// Obviously, using uchar will not work for meshes with polygons with more than 255 indices, but how realistic is this case?
|
||||
mOutput << "property list uchar int vertex_index" << endl;
|
||||
|
||||
mOutput << "end_header" << endl;
|
||||
|
||||
for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
|
||||
|
@ -342,16 +347,24 @@ void PlyExporter::WriteMeshIndices(const aiMesh* m, unsigned int offset)
|
|||
}
|
||||
}
|
||||
|
||||
void PlyExporter::WriteMeshIndicesBinary(const aiMesh* m, unsigned int offset)
|
||||
// Generic method in case we want to use different data types for the indices or make this configurable.
|
||||
template<typename NumIndicesType, typename IndexType>
|
||||
void WriteMeshIndicesBinary_Generic(const aiMesh* m, unsigned int offset, std::ostringstream& output)
|
||||
{
|
||||
for (unsigned int i = 0; i < m->mNumFaces; ++i) {
|
||||
const aiFace& f = m->mFaces[i];
|
||||
mOutput.write(reinterpret_cast<const char*>(&f.mNumIndices), 4);
|
||||
NumIndicesType numIndices = static_cast<NumIndicesType>(f.mNumIndices);
|
||||
output.write(reinterpret_cast<const char*>(&numIndices), sizeof(NumIndicesType));
|
||||
for (unsigned int c = 0; c < f.mNumIndices; ++c) {
|
||||
unsigned int index = f.mIndices[c] + offset;
|
||||
mOutput.write(reinterpret_cast<const char*>(&index), 4);
|
||||
IndexType index = f.mIndices[c] + offset;
|
||||
output.write(reinterpret_cast<const char*>(&index), sizeof(IndexType));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PlyExporter::WriteMeshIndicesBinary(const aiMesh* m, unsigned int offset)
|
||||
{
|
||||
WriteMeshIndicesBinary_Generic<unsigned char, int>(m, offset, mOutput);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -310,6 +310,10 @@ void PLYImporter::ConvertMeshes(std::vector<PLY::Face>* avFaces,
|
|||
iNum += (unsigned int)(*avFaces)[aiSplit[p][i]].mIndices.size();
|
||||
}
|
||||
p_pcOut->mNumVertices = iNum;
|
||||
if( 0 == iNum ) { // nothing to do
|
||||
delete[] aiSplit; // cleanup
|
||||
return;
|
||||
}
|
||||
p_pcOut->mVertices = new aiVector3D[iNum];
|
||||
|
||||
if (!avColors->empty())
|
||||
|
@ -335,20 +339,25 @@ void PLYImporter::ConvertMeshes(std::vector<PLY::Face>* avFaces,
|
|||
for (unsigned int q = 0; q < p_pcOut->mFaces[iNum].mNumIndices;++q)
|
||||
{
|
||||
p_pcOut->mFaces[iNum].mIndices[q] = iVertex;
|
||||
p_pcOut->mVertices[iVertex] = (*avPositions)[(*avFaces)[*i].mIndices[q]];
|
||||
const size_t idx = ( *avFaces )[ *i ].mIndices[ q ];
|
||||
if( idx >= ( *avPositions ).size() ) {
|
||||
// out of border
|
||||
continue;
|
||||
}
|
||||
p_pcOut->mVertices[ iVertex ] = ( *avPositions )[ idx ];
|
||||
|
||||
if (!avColors->empty())
|
||||
p_pcOut->mColors[0][iVertex] = (*avColors)[(*avFaces)[*i].mIndices[q]];
|
||||
p_pcOut->mColors[ 0 ][ iVertex ] = ( *avColors )[ idx ];
|
||||
|
||||
if (!avTexCoords->empty())
|
||||
{
|
||||
const aiVector2D& vec = (*avTexCoords)[(*avFaces)[*i].mIndices[q]];
|
||||
const aiVector2D& vec = ( *avTexCoords )[ idx ];
|
||||
p_pcOut->mTextureCoords[0][iVertex].x = vec.x;
|
||||
p_pcOut->mTextureCoords[0][iVertex].y = vec.y;
|
||||
}
|
||||
|
||||
if (!avNormals->empty())
|
||||
p_pcOut->mNormals[iVertex] = (*avNormals)[(*avFaces)[*i].mIndices[q]];
|
||||
p_pcOut->mNormals[ iVertex ] = ( *avNormals )[ idx ];
|
||||
iVertex++;
|
||||
}
|
||||
|
||||
|
|
|
@ -75,8 +75,9 @@ static const aiImporterDesc desc = {
|
|||
// 2) 4 byte face count
|
||||
// 3) 50 bytes per face
|
||||
bool IsBinarySTL(const char* buffer, unsigned int fileSize) {
|
||||
if (fileSize < 84)
|
||||
if( fileSize < 84 ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const uint32_t faceCount = *reinterpret_cast<const uint32_t*>(buffer + 80);
|
||||
const uint32_t expectedBinaryFileSize = faceCount * 50 + 84;
|
||||
|
@ -99,7 +100,20 @@ bool IsAsciiSTL(const char* buffer, unsigned int fileSize) {
|
|||
if (buffer + 5 >= bufferEnd)
|
||||
return false;
|
||||
|
||||
return strncmp(buffer, "solid", 5) == 0;
|
||||
bool isASCII( strncmp( buffer, "solid", 5 ) == 0 );
|
||||
if( isASCII ) {
|
||||
// A lot of importers are write solid even if the file is binary. So we have to check for ASCII-characters.
|
||||
if( fileSize >= 500 ) {
|
||||
isASCII = true;
|
||||
for( unsigned int i = 0; i < 500; i++ ) {
|
||||
if( buffer[ i ] > 127 ) {
|
||||
isASCII = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return isASCII;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
|
@ -122,23 +136,37 @@ bool STLImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool
|
|||
{
|
||||
const std::string extension = GetExtension(pFile);
|
||||
|
||||
if (extension == "stl")
|
||||
if( extension == "stl" ) {
|
||||
return true;
|
||||
else if (!extension.length() || checkSig) {
|
||||
if (!pIOHandler)
|
||||
} else if (!extension.length() || checkSig) {
|
||||
if( !pIOHandler ) {
|
||||
return true;
|
||||
}
|
||||
const char* tokens[] = {"STL","solid"};
|
||||
return SearchFileHeaderForToken(pIOHandler,pFile,tokens,2);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const aiImporterDesc* STLImporter::GetInfo () const
|
||||
{
|
||||
const aiImporterDesc* STLImporter::GetInfo () const {
|
||||
return &desc;
|
||||
}
|
||||
|
||||
void addFacesToMesh(aiMesh* pMesh)
|
||||
{
|
||||
pMesh->mFaces = new aiFace[pMesh->mNumFaces];
|
||||
for (unsigned int i = 0, p = 0; i < pMesh->mNumFaces;++i) {
|
||||
|
||||
aiFace& face = pMesh->mFaces[i];
|
||||
face.mIndices = new unsigned int[face.mNumIndices = 3];
|
||||
for (unsigned int o = 0; o < 3;++o,++p) {
|
||||
face.mIndices[o] = p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Imports the given file into the given scene structure.
|
||||
void STLImporter::InternReadFile( const std::string& pFile,
|
||||
|
@ -164,17 +192,8 @@ void STLImporter::InternReadFile( const std::string& pFile,
|
|||
// the default vertex color is light gray.
|
||||
clrColorDefault.r = clrColorDefault.g = clrColorDefault.b = clrColorDefault.a = 0.6f;
|
||||
|
||||
// allocate one mesh
|
||||
pScene->mNumMeshes = 1;
|
||||
pScene->mMeshes = new aiMesh*[1];
|
||||
aiMesh* pMesh = pScene->mMeshes[0] = new aiMesh();
|
||||
pMesh->mMaterialIndex = 0;
|
||||
|
||||
// allocate a single node
|
||||
pScene->mRootNode = new aiNode();
|
||||
pScene->mRootNode->mNumMeshes = 1;
|
||||
pScene->mRootNode->mMeshes = new unsigned int[1];
|
||||
pScene->mRootNode->mMeshes[0] = 0;
|
||||
|
||||
bool bMatClr = false;
|
||||
|
||||
|
@ -186,16 +205,11 @@ void STLImporter::InternReadFile( const std::string& pFile,
|
|||
throw DeadlyImportError( "Failed to determine STL storage representation for " + pFile + ".");
|
||||
}
|
||||
|
||||
// now copy faces
|
||||
pMesh->mFaces = new aiFace[pMesh->mNumFaces];
|
||||
for (unsigned int i = 0, p = 0; i < pMesh->mNumFaces;++i) {
|
||||
|
||||
aiFace& face = pMesh->mFaces[i];
|
||||
face.mIndices = new unsigned int[face.mNumIndices = 3];
|
||||
for (unsigned int o = 0; o < 3;++o,++p) {
|
||||
face.mIndices[o] = p;
|
||||
}
|
||||
}
|
||||
// add all created meshes to the single node
|
||||
pScene->mRootNode->mNumMeshes = pScene->mNumMeshes;
|
||||
pScene->mRootNode->mMeshes = new unsigned int[pScene->mNumMeshes];
|
||||
for (unsigned int i = 0; i < pScene->mNumMeshes; i++)
|
||||
pScene->mRootNode->mMeshes[i] = i;
|
||||
|
||||
// create a single default material, using a light gray diffuse color for consistency with
|
||||
// other geometric types (e.g., PLY).
|
||||
|
@ -221,9 +235,24 @@ void STLImporter::InternReadFile( const std::string& pFile,
|
|||
// Read an ASCII STL file
|
||||
void STLImporter::LoadASCIIFile()
|
||||
{
|
||||
aiMesh* pMesh = pScene->mMeshes[0];
|
||||
|
||||
std::vector<aiMesh*> meshes;
|
||||
const char* sz = mBuffer;
|
||||
const char* bufferEnd = mBuffer + fileSize;
|
||||
std::vector<aiVector3D> positionBuffer;
|
||||
std::vector<aiVector3D> normalBuffer;
|
||||
|
||||
// try to guess how many vertices we could have
|
||||
// assume we'll need 160 bytes for each face
|
||||
size_t sizeEstimate = std::max(1u, fileSize / 160u ) * 3;
|
||||
positionBuffer.reserve(sizeEstimate);
|
||||
normalBuffer.reserve(sizeEstimate);
|
||||
|
||||
while (IsAsciiSTL(sz, bufferEnd - sz))
|
||||
{
|
||||
aiMesh* pMesh = new aiMesh();
|
||||
pMesh->mMaterialIndex = 0;
|
||||
meshes.push_back(pMesh);
|
||||
|
||||
SkipSpaces(&sz);
|
||||
ai_assert(!IsLineEnd(sz));
|
||||
|
||||
|
@ -247,13 +276,7 @@ void STLImporter::LoadASCIIFile()
|
|||
}
|
||||
else pScene->mRootNode->mName.Set("<STL_ASCII>");
|
||||
|
||||
// try to guess how many vertices we could have
|
||||
// assume we'll need 160 bytes for each face
|
||||
pMesh->mNumVertices = ( pMesh->mNumFaces = std::max(1u,fileSize / 160u )) * 3;
|
||||
pMesh->mVertices = new aiVector3D[pMesh->mNumVertices];
|
||||
pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
|
||||
|
||||
unsigned int curFace = 0, curVertex = 3;
|
||||
unsigned int faceVertexCounter = 0;
|
||||
for ( ;; )
|
||||
{
|
||||
// go to the next token
|
||||
|
@ -264,42 +287,25 @@ void STLImporter::LoadASCIIFile()
|
|||
break;
|
||||
}
|
||||
// facet normal -0.13 -0.13 -0.98
|
||||
if (!strncmp(sz,"facet",5) && IsSpaceOrNewLine(*(sz+5))) {
|
||||
if (!strncmp(sz,"facet",5) && IsSpaceOrNewLine(*(sz+5)) && *(sz + 5) != '\0') {
|
||||
|
||||
if (3 != curVertex) {
|
||||
if (faceVertexCounter != 3) {
|
||||
DefaultLogger::get()->warn("STL: A new facet begins but the old is not yet complete");
|
||||
}
|
||||
if (pMesh->mNumFaces == curFace) {
|
||||
ai_assert(pMesh->mNumFaces != 0);
|
||||
|
||||
// need to resize the arrays, our size estimate was wrong
|
||||
unsigned int iNeededSize = (unsigned int)(sz-mBuffer) / pMesh->mNumFaces;
|
||||
if (iNeededSize <= 160)iNeededSize >>= 1; // prevent endless looping
|
||||
unsigned int add = (unsigned int)((mBuffer+fileSize)-sz) / iNeededSize;
|
||||
add += add >> 3; // add 12.5% as buffer
|
||||
iNeededSize = (pMesh->mNumFaces + add)*3;
|
||||
aiVector3D* pv = new aiVector3D[iNeededSize];
|
||||
memcpy(pv,pMesh->mVertices,pMesh->mNumVertices*sizeof(aiVector3D));
|
||||
delete[] pMesh->mVertices;
|
||||
pMesh->mVertices = pv;
|
||||
pv = new aiVector3D[iNeededSize];
|
||||
memcpy(pv,pMesh->mNormals,pMesh->mNumVertices*sizeof(aiVector3D));
|
||||
delete[] pMesh->mNormals;
|
||||
pMesh->mNormals = pv;
|
||||
|
||||
pMesh->mNumVertices = iNeededSize;
|
||||
pMesh->mNumFaces += add;
|
||||
}
|
||||
aiVector3D* vn = &pMesh->mNormals[curFace++*3];
|
||||
faceVertexCounter = 0;
|
||||
normalBuffer.push_back(aiVector3D());
|
||||
aiVector3D* vn = &normalBuffer.back();
|
||||
|
||||
sz += 6;
|
||||
curVertex = 0;
|
||||
SkipSpaces(&sz);
|
||||
if (strncmp(sz,"normal",6)) {
|
||||
DefaultLogger::get()->warn("STL: a facet normal vector was expected but not found");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sz[6] == '\0') {
|
||||
throw DeadlyImportError("STL: unexpected EOF while parsing facet");
|
||||
}
|
||||
sz += 7;
|
||||
SkipSpaces(&sz);
|
||||
sz = fast_atoreal_move<float>(sz, (float&)vn->x );
|
||||
|
@ -307,30 +313,39 @@ void STLImporter::LoadASCIIFile()
|
|||
sz = fast_atoreal_move<float>(sz, (float&)vn->y );
|
||||
SkipSpaces(&sz);
|
||||
sz = fast_atoreal_move<float>(sz, (float&)vn->z );
|
||||
*(vn+1) = *vn;
|
||||
*(vn+2) = *vn;
|
||||
normalBuffer.push_back(*vn);
|
||||
normalBuffer.push_back(*vn);
|
||||
}
|
||||
}
|
||||
// vertex 1.50000 1.50000 0.00000
|
||||
else if (!strncmp(sz,"vertex",6) && ::IsSpaceOrNewLine(*(sz+6)))
|
||||
{
|
||||
if (3 == curVertex) {
|
||||
if (faceVertexCounter >= 3) {
|
||||
DefaultLogger::get()->error("STL: a facet with more than 3 vertices has been found");
|
||||
++sz;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sz[6] == '\0') {
|
||||
throw DeadlyImportError("STL: unexpected EOF while parsing facet");
|
||||
}
|
||||
sz += 7;
|
||||
SkipSpaces(&sz);
|
||||
aiVector3D* vn = &pMesh->mVertices[(curFace-1)*3 + curVertex++];
|
||||
positionBuffer.push_back(aiVector3D());
|
||||
aiVector3D* vn = &positionBuffer.back();
|
||||
sz = fast_atoreal_move<float>(sz, (float&)vn->x );
|
||||
SkipSpaces(&sz);
|
||||
sz = fast_atoreal_move<float>(sz, (float&)vn->y );
|
||||
SkipSpaces(&sz);
|
||||
sz = fast_atoreal_move<float>(sz, (float&)vn->z );
|
||||
faceVertexCounter++;
|
||||
}
|
||||
}
|
||||
else if (!::strncmp(sz,"endsolid",8)) {
|
||||
do {
|
||||
++sz;
|
||||
} while (!::IsLineEnd(*sz));
|
||||
SkipSpacesAndLineEnd(&sz);
|
||||
// finished!
|
||||
break;
|
||||
}
|
||||
|
@ -342,19 +357,49 @@ void STLImporter::LoadASCIIFile()
|
|||
}
|
||||
}
|
||||
|
||||
if (!curFace) {
|
||||
if (positionBuffer.empty()) {
|
||||
pMesh->mNumFaces = 0;
|
||||
throw DeadlyImportError("STL: ASCII file is empty or invalid; no data loaded");
|
||||
}
|
||||
pMesh->mNumFaces = curFace;
|
||||
pMesh->mNumVertices = curFace*3;
|
||||
// we are finished!
|
||||
if (positionBuffer.size() % 3 != 0) {
|
||||
pMesh->mNumFaces = 0;
|
||||
throw DeadlyImportError("STL: Invalid number of vertices");
|
||||
}
|
||||
if (normalBuffer.size() != positionBuffer.size()) {
|
||||
pMesh->mNumFaces = 0;
|
||||
throw DeadlyImportError("Normal buffer size does not match position buffer size");
|
||||
}
|
||||
pMesh->mNumFaces = positionBuffer.size() / 3;
|
||||
pMesh->mNumVertices = positionBuffer.size();
|
||||
pMesh->mVertices = new aiVector3D[pMesh->mNumVertices];
|
||||
memcpy(pMesh->mVertices, &positionBuffer[0].x, pMesh->mNumVertices * sizeof(aiVector3D));
|
||||
positionBuffer.clear();
|
||||
pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
|
||||
memcpy(pMesh->mNormals, &normalBuffer[0].x, pMesh->mNumVertices * sizeof(aiVector3D));
|
||||
normalBuffer.clear();
|
||||
|
||||
// now copy faces
|
||||
addFacesToMesh(pMesh);
|
||||
}
|
||||
// now add the loaded meshes
|
||||
pScene->mNumMeshes = (unsigned int)meshes.size();
|
||||
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
|
||||
for (size_t i = 0; i < meshes.size(); i++)
|
||||
{
|
||||
pScene->mMeshes[i] = meshes[i];
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Read a binary STL file
|
||||
bool STLImporter::LoadBinaryFile()
|
||||
{
|
||||
// allocate one mesh
|
||||
pScene->mNumMeshes = 1;
|
||||
pScene->mMeshes = new aiMesh*[1];
|
||||
aiMesh* pMesh = pScene->mMeshes[0] = new aiMesh();
|
||||
pMesh->mMaterialIndex = 0;
|
||||
|
||||
// skip the first 80 bytes
|
||||
if (fileSize < 84) {
|
||||
throw DeadlyImportError("STL: file is too small for the header");
|
||||
|
@ -382,7 +427,6 @@ bool STLImporter::LoadBinaryFile()
|
|||
const unsigned char* sz = (const unsigned char*)mBuffer + 80;
|
||||
|
||||
// now read the number of facets
|
||||
aiMesh* pMesh = pScene->mMeshes[0];
|
||||
pScene->mRootNode->mName.Set("<STL_BINARY>");
|
||||
|
||||
pMesh->mNumFaces = *((uint32_t*)sz);
|
||||
|
@ -455,6 +499,10 @@ bool STLImporter::LoadBinaryFile()
|
|||
*(clr+2) = *clr;
|
||||
}
|
||||
}
|
||||
|
||||
// now copy faces
|
||||
addFacesToMesh(pMesh);
|
||||
|
||||
if (bIsMaterialise && !pMesh->mColors[0])
|
||||
{
|
||||
// use the color as diffuse material color
|
||||
|
|
|
@ -399,10 +399,14 @@ void CatmullClarkSubdivider::InternSubdivide (
|
|||
bool haveit = false;
|
||||
for (unsigned int i = 0; i < f.mNumIndices; ++i) {
|
||||
if (maptbl[FLATTEN_VERTEX_IDX(n,f.mIndices[i])]==(unsigned int)t) {
|
||||
haveit = true; break;
|
||||
haveit = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ai_assert(haveit);
|
||||
if (!haveit) {
|
||||
DefaultLogger::get()->debug("Catmull-Clark Subdivider: Index not used");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,6 +53,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#endif
|
||||
|
||||
#include "types.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace Assimp {
|
||||
class IOStream;
|
||||
|
||||
|
@ -102,18 +105,14 @@ public:
|
|||
* @param pFile Path to the file
|
||||
* @return true if there is a file with this path, else false.
|
||||
*/
|
||||
|
||||
virtual bool Exists( const char* pFile) const = 0;
|
||||
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief Returns the system specific directory separator
|
||||
* @return System specific directory separator
|
||||
*/
|
||||
virtual char getOsSeparator() const = 0;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief Open a new file with a given path.
|
||||
*
|
||||
|
@ -139,8 +138,6 @@ public:
|
|||
inline IOStream* Open(const std::string& pFile,
|
||||
const std::string& pMode = std::string("rb"));
|
||||
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief Closes the given file and releases all resources
|
||||
* associated with it.
|
||||
|
@ -170,10 +167,41 @@ public:
|
|||
*/
|
||||
inline bool ComparePaths (const std::string& one,
|
||||
const std::string& second) const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief Pushes a new directory onto the directory stack.
|
||||
* @param path Path to push onto the stack.
|
||||
* @return True, when push was successful, false if path is empty.
|
||||
*/
|
||||
virtual bool PushDirectory( const std::string &path );
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief Returns the top directory from the stack.
|
||||
* @return The directory on the top of the stack.
|
||||
* Returns empty when no directory was pushed to the stack.
|
||||
*/
|
||||
virtual const std::string &CurrentDirectory() const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief Returns the number of directories stored on the stack.
|
||||
* @return The number of directories of the stack.
|
||||
*/
|
||||
virtual size_t StackSize() const;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief Pops the top directory from the stack.
|
||||
* @return True, when a directory was on the stack. False if no
|
||||
* directory was on the stack.
|
||||
*/
|
||||
virtual bool PopDirectory();
|
||||
|
||||
private:
|
||||
std::vector<std::string> m_pathStack;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
AI_FORCE_INLINE IOSystem::IOSystem()
|
||||
AI_FORCE_INLINE IOSystem::IOSystem() :
|
||||
m_pathStack()
|
||||
{
|
||||
// empty
|
||||
}
|
||||
|
@ -220,6 +248,43 @@ inline bool IOSystem::ComparePaths (const std::string& one,
|
|||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
inline bool IOSystem::PushDirectory( const std::string &path ) {
|
||||
if ( path.empty() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_pathStack.push_back( path );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
inline const std::string &IOSystem::CurrentDirectory() const {
|
||||
if ( m_pathStack.empty() ) {
|
||||
static const std::string Dummy("");
|
||||
return Dummy;
|
||||
}
|
||||
return m_pathStack[ m_pathStack.size()-1 ];
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
inline size_t IOSystem::StackSize() const {
|
||||
return m_pathStack.size();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
inline bool IOSystem::PopDirectory() {
|
||||
if ( m_pathStack.empty() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_pathStack.pop_back();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
} //!ns Assimp
|
||||
|
||||
#endif //AI_IOSYSTEM_H_INC
|
||||
|
|
|
@ -276,4 +276,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
# define AI_BUILD_BIG_ENDIAN
|
||||
#endif
|
||||
|
||||
|
||||
/* To avoid running out of memory
|
||||
* This can be adjusted for specific use cases
|
||||
* It's NOT a total limit, just a limit for individual allocations
|
||||
*/
|
||||
#define AI_MAX_ALLOC(type) ((256U * 1024 * 1024) / sizeof(type))
|
||||
|
||||
|
||||
#endif // !! INCLUDED_AI_DEFINES_H
|
||||
|
|
|
@ -42,7 +42,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
/** @file Android extension of DefaultIOSystem using the standard C file functions */
|
||||
|
||||
|
||||
#include <code/AssimpPCH.h>
|
||||
#include <assimp/config.h>
|
||||
#include <android/api-level.h>
|
||||
#if __ANDROID__ and __ANDROID_API__ > 9 and defined(AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT)
|
||||
|
||||
#include <stdlib.h>
|
||||
|
@ -50,6 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <android/asset_manager.h>
|
||||
#include <android/asset_manager_jni.h>
|
||||
#include <android/native_activity.h>
|
||||
#include <assimp/ai_assert.h>
|
||||
#include <assimp/port/AndroidJNI/AndroidJNIIOSystem.h>
|
||||
#include <code/DefaultIOStream.h>
|
||||
#include <fstream>
|
||||
|
@ -114,7 +116,7 @@ bool AndroidJNIIOSystem::AndroidExtractAsset(std::string name)
|
|||
// Open file
|
||||
AAsset* asset = AAssetManager_open(mApkAssetManager, name.c_str(),
|
||||
AASSET_MODE_UNKNOWN);
|
||||
std::string assetContent;
|
||||
std::vector<char> assetContent;
|
||||
|
||||
if (asset != NULL) {
|
||||
// Find size
|
||||
|
@ -138,7 +140,7 @@ bool AndroidJNIIOSystem::AndroidExtractAsset(std::string name)
|
|||
}
|
||||
|
||||
// Write output buffer into a file
|
||||
assetExtracted.write(assetContent.c_str(), strlen(assetContent.c_str()));
|
||||
assetExtracted.write(&assetContent[0], assetContent.size());
|
||||
assetExtracted.close();
|
||||
|
||||
__android_log_print(ANDROID_LOG_DEFAULT, "Assimp", "Asset extracted");
|
||||
|
|
|
@ -20,6 +20,7 @@ additional_dirs, ext_whitelist = [],[]
|
|||
# populate search directories and lists of allowed file extensions
|
||||
# depending on the platform we're running on.
|
||||
if os.name=='posix':
|
||||
additional_dirs.append('./')
|
||||
additional_dirs.append('/usr/lib/')
|
||||
additional_dirs.append('/usr/local/lib/')
|
||||
|
||||
|
|
|
@ -68,7 +68,7 @@ class PyAssimp3DViewer:
|
|||
pygame.init()
|
||||
pygame.display.set_caption(self.base_name)
|
||||
pygame.display.set_mode((w,h), pygame.OPENGL | pygame.DOUBLEBUF)
|
||||
|
||||
glutInit()
|
||||
self.prepare_shaders()
|
||||
|
||||
self.cameras = [DefaultCamera(w,h,fov)]
|
||||
|
|
|
@ -24,6 +24,7 @@ SET( TEST_SRCS
|
|||
unit/utGenNormals.cpp
|
||||
unit/utImporter.cpp
|
||||
unit/utImproveCacheLocality.cpp
|
||||
unit/utIOSystem.cpp
|
||||
unit/utJoinVertices.cpp
|
||||
unit/utLimitBoneWeights.cpp
|
||||
unit/utMaterialSystem.cpp
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
---------------------------------------------------------------------------
|
||||
Open Asset Import Library (assimp)
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2014, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the following
|
||||
conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------
|
||||
*/
|
||||
#include "UnitTestPCH.h"
|
||||
|
||||
#include <assimp/IOSystem.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace Assimp;
|
||||
|
||||
static const string Sep = "/";
|
||||
class TestIOSystem : public IOSystem {
|
||||
public:
|
||||
TestIOSystem() : IOSystem() {}
|
||||
virtual ~TestIOSystem() {}
|
||||
virtual bool Exists( const char* ) const {
|
||||
return true;
|
||||
}
|
||||
virtual char getOsSeparator() const {
|
||||
return Sep[ 0 ];
|
||||
}
|
||||
|
||||
virtual IOStream* Open(const char* pFile, const char* pMode = "rb") {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
virtual void Close( IOStream* pFile) {
|
||||
// empty
|
||||
}
|
||||
};
|
||||
|
||||
class IOSystemTest : public ::testing::Test {
|
||||
public:
|
||||
virtual void SetUp() { pImp = new TestIOSystem(); }
|
||||
virtual void TearDown() { delete pImp; }
|
||||
|
||||
protected:
|
||||
TestIOSystem* pImp;
|
||||
};
|
||||
|
||||
/*
|
||||
virtual bool PushDirectory( const std::string &path );
|
||||
virtual const std::string &CurrentDirectory() const;
|
||||
virtual bool PopDirectory();
|
||||
*/
|
||||
|
||||
TEST_F( IOSystemTest, accessDirectoryStackTest ) {
|
||||
EXPECT_FALSE( pImp->PopDirectory() );
|
||||
EXPECT_EQ( 0, pImp->StackSize() );
|
||||
EXPECT_FALSE( pImp->PushDirectory( "" ) );
|
||||
std::string path = "test/";
|
||||
EXPECT_TRUE( pImp->PushDirectory( path ) );
|
||||
EXPECT_EQ( 1, pImp->StackSize() );
|
||||
EXPECT_EQ( path, pImp->CurrentDirectory() );
|
||||
EXPECT_TRUE( pImp->PopDirectory() );
|
||||
EXPECT_EQ( 0, pImp->StackSize() );
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:Assimp.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
|
@ -0,0 +1,80 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0700"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "7F79227F1AB43AC3005A8E5D"
|
||||
BuildableName = "libassimp.a"
|
||||
BlueprintName = "assimp"
|
||||
ReferencedContainer = "container:workspaces/xcode6/Assimp.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "7F79227F1AB43AC3005A8E5D"
|
||||
BuildableName = "libassimp.a"
|
||||
BlueprintName = "assimp"
|
||||
ReferencedContainer = "container:workspaces/xcode6/Assimp.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "7F79227F1AB43AC3005A8E5D"
|
||||
BuildableName = "libassimp.a"
|
||||
BlueprintName = "assimp"
|
||||
ReferencedContainer = "container:workspaces/xcode6/Assimp.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
Loading…
Reference in New Issue