Merge branch 'master' into patch-1
commit
4841ee05c5
|
@ -45,6 +45,10 @@ namespace Assimp {
|
|||
namespace D3MF {
|
||||
|
||||
namespace XmlTag {
|
||||
// Meta-data
|
||||
static const std::string meta = "metadata";
|
||||
static const std::string meta_name = "name";
|
||||
|
||||
// Model-data specific tags
|
||||
static const std::string model = "model";
|
||||
static const std::string model_unit = "unit";
|
||||
|
@ -74,6 +78,7 @@ namespace XmlTag {
|
|||
|
||||
// Material definitions
|
||||
static const std::string basematerials = "basematerials";
|
||||
static const std::string basematerials_id = "id";
|
||||
static const std::string basematerials_base = "base";
|
||||
static const std::string basematerials_name = "name";
|
||||
static const std::string basematerials_displaycolor = "displaycolor";
|
||||
|
|
|
@ -115,13 +115,12 @@ void BaseImporter::SetupProperties(const Importer* /*pImp*/)
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void BaseImporter::GetExtensionList(std::set<std::string>& extensions)
|
||||
{
|
||||
void BaseImporter::GetExtensionList(std::set<std::string>& extensions) {
|
||||
const aiImporterDesc* desc = GetInfo();
|
||||
ai_assert(desc != NULL);
|
||||
ai_assert(desc != nullptr);
|
||||
|
||||
const char* ext = desc->mFileExtensions;
|
||||
ai_assert(ext != NULL);
|
||||
ai_assert(ext != nullptr );
|
||||
|
||||
const char* last = ext;
|
||||
do {
|
||||
|
@ -145,12 +144,13 @@ void BaseImporter::GetExtensionList(std::set<std::string>& extensions)
|
|||
unsigned int searchBytes /* = 200 */,
|
||||
bool tokensSol /* false */)
|
||||
{
|
||||
ai_assert( NULL != tokens );
|
||||
ai_assert( nullptr != tokens );
|
||||
ai_assert( 0 != numTokens );
|
||||
ai_assert( 0 != searchBytes);
|
||||
|
||||
if (!pIOHandler)
|
||||
if ( nullptr == pIOHandler ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::unique_ptr<IOStream> pStream (pIOHandler->Open(pFile));
|
||||
if (pStream.get() ) {
|
||||
|
@ -179,9 +179,9 @@ void BaseImporter::GetExtensionList(std::set<std::string>& extensions)
|
|||
*cur2 = '\0';
|
||||
|
||||
std::string token;
|
||||
for (unsigned int i = 0; i < numTokens;++i) {
|
||||
for (unsigned int i = 0; i < numTokens; ++i ) {
|
||||
ai_assert( nullptr != tokens[i] );
|
||||
size_t len( strlen( tokens[ i ] ) );
|
||||
const size_t len( strlen( tokens[ i ] ) );
|
||||
token.clear();
|
||||
const char *ptr( tokens[ i ] );
|
||||
for ( size_t tokIdx = 0; tokIdx < len; ++tokIdx ) {
|
||||
|
|
|
@ -222,6 +222,7 @@ void ColladaParser::ReadStructure()
|
|||
}
|
||||
|
||||
PostProcessRootAnimations();
|
||||
PostProcessControllers();
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
@ -360,6 +361,21 @@ void ColladaParser::ReadAnimationClipLibrary()
|
|||
}
|
||||
}
|
||||
|
||||
void ColladaParser::PostProcessControllers()
|
||||
{
|
||||
for (ControllerLibrary::iterator it = mControllerLibrary.begin(); it != mControllerLibrary.end(); ++it)
|
||||
{
|
||||
std::string meshId = it->second.mMeshId;
|
||||
ControllerLibrary::iterator findItr = mControllerLibrary.find(meshId);
|
||||
while(findItr != mControllerLibrary.end()) {
|
||||
meshId = findItr->second.mMeshId;
|
||||
findItr = mControllerLibrary.find(meshId);
|
||||
}
|
||||
|
||||
it->second.mMeshId = meshId;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Re-build animations from animation clip library, if present, otherwise combine single-channel animations
|
||||
void ColladaParser::PostProcessRootAnimations()
|
||||
|
|
|
@ -87,6 +87,9 @@ namespace Assimp
|
|||
/** Reads the animation clip library */
|
||||
void ReadAnimationClipLibrary();
|
||||
|
||||
/** Unwrap controllers dependency hierarchy */
|
||||
void PostProcessControllers();
|
||||
|
||||
/** Re-build animations from animation clip library, if present, otherwise combine single-channel animations */
|
||||
void PostProcessRootAnimations();
|
||||
|
||||
|
|
|
@ -91,12 +91,14 @@ void MakeLeftHandedProcess::Execute( aiScene* pScene)
|
|||
ProcessNode( pScene->mRootNode, aiMatrix4x4());
|
||||
|
||||
// process the meshes accordingly
|
||||
for( unsigned int a = 0; a < pScene->mNumMeshes; ++a)
|
||||
ProcessMesh( pScene->mMeshes[a]);
|
||||
for ( unsigned int a = 0; a < pScene->mNumMeshes; ++a ) {
|
||||
ProcessMesh( pScene->mMeshes[ a ] );
|
||||
}
|
||||
|
||||
// process the materials accordingly
|
||||
for( unsigned int a = 0; a < pScene->mNumMaterials; ++a)
|
||||
ProcessMaterial( pScene->mMaterials[a]);
|
||||
for ( unsigned int a = 0; a < pScene->mNumMaterials; ++a ) {
|
||||
ProcessMaterial( pScene->mMaterials[ a ] );
|
||||
}
|
||||
|
||||
// transform all animation channels as well
|
||||
for( unsigned int a = 0; a < pScene->mNumAnimations; a++)
|
||||
|
@ -136,8 +138,11 @@ void MakeLeftHandedProcess::ProcessNode( aiNode* pNode, const aiMatrix4x4& pPare
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Converts a single mesh to left handed coordinates.
|
||||
void MakeLeftHandedProcess::ProcessMesh( aiMesh* pMesh)
|
||||
{
|
||||
void MakeLeftHandedProcess::ProcessMesh( aiMesh* pMesh) {
|
||||
if ( nullptr == pMesh ) {
|
||||
DefaultLogger::get()->error( "Nullptr to mesh found." );
|
||||
return;
|
||||
}
|
||||
// mirror positions, normals and stuff along the Z axis
|
||||
for( size_t a = 0; a < pMesh->mNumVertices; ++a)
|
||||
{
|
||||
|
@ -173,8 +178,12 @@ void MakeLeftHandedProcess::ProcessMesh( aiMesh* pMesh)
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Converts a single material to left handed coordinates.
|
||||
void MakeLeftHandedProcess::ProcessMaterial( aiMaterial* _mat)
|
||||
{
|
||||
void MakeLeftHandedProcess::ProcessMaterial( aiMaterial* _mat) {
|
||||
if ( nullptr == _mat ) {
|
||||
DefaultLogger::get()->error( "Nullptr to aiMaterial found." );
|
||||
return;
|
||||
}
|
||||
|
||||
aiMaterial* mat = (aiMaterial*)_mat;
|
||||
for (unsigned int a = 0; a < mat->mNumProperties;++a) {
|
||||
aiMaterialProperty* prop = mat->mProperties[a];
|
||||
|
@ -183,7 +192,6 @@ void MakeLeftHandedProcess::ProcessMaterial( aiMaterial* _mat)
|
|||
if (!::strcmp( prop->mKey.data, "$tex.mapaxis")) {
|
||||
ai_assert( prop->mDataLength >= sizeof(aiVector3D)); /* something is wrong with the validation if we end up here */
|
||||
aiVector3D* pff = (aiVector3D*)prop->mData;
|
||||
|
||||
pff->z *= -1.f;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,8 +49,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <assimp/IOStream.hpp>
|
||||
#include <assimp/Exporter.hpp>
|
||||
#include <assimp/DefaultLogger.hpp>
|
||||
|
||||
#include <assimp/StringUtils.h>
|
||||
#include <assimp/Exceptional.h>
|
||||
|
||||
#include "3MFXmlTags.h"
|
||||
#include "D3MFOpcPackage.h"
|
||||
|
||||
|
@ -126,7 +127,6 @@ bool D3MFExporter::exportArchive( const char *file ) {
|
|||
return ok;
|
||||
}
|
||||
|
||||
|
||||
bool D3MFExporter::exportContentTypes() {
|
||||
mContentOutput.clear();
|
||||
|
||||
|
@ -153,7 +153,11 @@ bool D3MFExporter::exportRelations() {
|
|||
mRelOutput << "<Relationships xmlns=\"http://schemas.openxmlformats.org/package/2006/relationships\">";
|
||||
|
||||
for ( size_t i = 0; i < mRelations.size(); ++i ) {
|
||||
mRelOutput << "<Relationship Target=\"/" << mRelations[ i ]->target << "\" ";
|
||||
if ( mRelations[ i ]->target[ 0 ] == '/' ) {
|
||||
mRelOutput << "<Relationship Target=\"" << mRelations[ i ]->target << "\" ";
|
||||
} else {
|
||||
mRelOutput << "<Relationship Target=\"/" << mRelations[ i ]->target << "\" ";
|
||||
}
|
||||
mRelOutput << "Id=\"" << mRelations[i]->id << "\" ";
|
||||
mRelOutput << "Type=\"" << mRelations[ i ]->type << "\" />";
|
||||
mRelOutput << std::endl;
|
||||
|
@ -177,6 +181,8 @@ bool D3MFExporter::export3DModel() {
|
|||
mModelOutput << "<" << XmlTag::resources << ">";
|
||||
mModelOutput << std::endl;
|
||||
|
||||
writeBaseMaterials();
|
||||
|
||||
writeObjects();
|
||||
|
||||
|
||||
|
@ -203,6 +209,40 @@ void D3MFExporter::writeHeader() {
|
|||
mModelOutput << std::endl;
|
||||
}
|
||||
|
||||
void D3MFExporter::writeBaseMaterials() {
|
||||
mModelOutput << "<basematerials id=\"1\">\n";
|
||||
for ( size_t i = 0; i < mScene->mNumMaterials; ++i ) {
|
||||
aiMaterial *mat = mScene->mMaterials[ i ];
|
||||
std::string strName;
|
||||
aiString name;
|
||||
if ( mat->Get( AI_MATKEY_NAME, name ) != aiReturn_SUCCESS ) {
|
||||
strName = "basemat_" + to_string( i );
|
||||
} else {
|
||||
strName = name.C_Str();
|
||||
}
|
||||
std::string hexDiffuseColor;
|
||||
aiColor4D color;
|
||||
if ( mat->Get( AI_MATKEY_COLOR_DIFFUSE, color ) == aiReturn_SUCCESS ) {
|
||||
hexDiffuseColor = "#";
|
||||
std::string tmp;
|
||||
|
||||
tmp = DecimalToHexa( color.r );
|
||||
hexDiffuseColor += tmp;
|
||||
tmp = DecimalToHexa( color.g );
|
||||
hexDiffuseColor += tmp;
|
||||
tmp = DecimalToHexa( color.b );
|
||||
hexDiffuseColor += tmp;
|
||||
tmp = DecimalToHexa( color.a );
|
||||
hexDiffuseColor += tmp;
|
||||
} else {
|
||||
hexDiffuseColor = "#FFFFFFFF";
|
||||
}
|
||||
|
||||
mModelOutput << "<base name=\""+strName+"\" "+" displaycolor=\""+hexDiffuseColor+"\" />\n";
|
||||
}
|
||||
mModelOutput << "</basematerials>\n";
|
||||
}
|
||||
|
||||
void D3MFExporter::writeObjects() {
|
||||
if ( nullptr == mScene->mRootNode ) {
|
||||
return;
|
||||
|
@ -242,7 +282,9 @@ void D3MFExporter::writeMesh( aiMesh *mesh ) {
|
|||
}
|
||||
mModelOutput << "</" << XmlTag::vertices << ">" << std::endl;
|
||||
|
||||
writeFaces( mesh );
|
||||
const unsigned int matIdx( mesh->mMaterialIndex );
|
||||
|
||||
writeFaces( mesh, matIdx );
|
||||
|
||||
mModelOutput << "</" << XmlTag::mesh << ">" << std::endl;
|
||||
}
|
||||
|
@ -252,7 +294,7 @@ void D3MFExporter::writeVertex( const aiVector3D &pos ) {
|
|||
mModelOutput << std::endl;
|
||||
}
|
||||
|
||||
void D3MFExporter::writeFaces( aiMesh *mesh ) {
|
||||
void D3MFExporter::writeFaces( aiMesh *mesh, unsigned int matIdx ) {
|
||||
if ( nullptr == mesh ) {
|
||||
return;
|
||||
}
|
||||
|
@ -264,7 +306,8 @@ void D3MFExporter::writeFaces( aiMesh *mesh ) {
|
|||
for ( unsigned int i = 0; i < mesh->mNumFaces; ++i ) {
|
||||
aiFace ¤tFace = mesh->mFaces[ i ];
|
||||
mModelOutput << "<" << XmlTag::triangle << " v1=\"" << currentFace.mIndices[ 0 ] << "\" v2=\""
|
||||
<< currentFace.mIndices[ 1 ] << "\" v3=\"" << currentFace.mIndices[ 2 ] << "\"/>";
|
||||
<< currentFace.mIndices[ 1 ] << "\" v3=\"" << currentFace.mIndices[ 2 ]
|
||||
<< "\" pid=\"1\" p1=\""+to_string(matIdx)+"\" />";
|
||||
mModelOutput << std::endl;
|
||||
}
|
||||
mModelOutput << "</" << XmlTag::triangles << ">";
|
||||
|
|
|
@ -76,10 +76,11 @@ public:
|
|||
|
||||
protected:
|
||||
void writeHeader();
|
||||
void writeBaseMaterials();
|
||||
void writeObjects();
|
||||
void writeMesh( aiMesh *mesh );
|
||||
void writeVertex( const aiVector3D &pos );
|
||||
void writeFaces( aiMesh *mesh );
|
||||
void writeFaces( aiMesh *mesh, unsigned int matIdx );
|
||||
void writeBuild();
|
||||
void exportContentTyp( const std::string &filename );
|
||||
void writeModelToArchive( const std::string &folder, const std::string &modelName );
|
||||
|
|
|
@ -70,9 +70,14 @@ namespace D3MF {
|
|||
|
||||
class XmlSerializer {
|
||||
public:
|
||||
using MatArray = std::vector<aiMaterial*>;
|
||||
using MatId2MatArray = std::map<unsigned int, std::vector<unsigned int>>;
|
||||
|
||||
XmlSerializer(XmlReader* xmlReader)
|
||||
: mMeshes()
|
||||
, mMaterials()
|
||||
, mMatArray()
|
||||
, mActiveMatGroup( 99999999 )
|
||||
, mMatId2MatArray()
|
||||
, xmlReader(xmlReader){
|
||||
// empty
|
||||
}
|
||||
|
@ -109,10 +114,10 @@ public:
|
|||
|
||||
std::copy( mMeshes.begin(), mMeshes.end(), scene->mMeshes);
|
||||
|
||||
scene->mNumMaterials = mMaterials.size();
|
||||
scene->mNumMaterials = static_cast<unsigned int>( mMatArray.size() );
|
||||
if ( 0 != scene->mNumMaterials ) {
|
||||
scene->mMaterials = new aiMaterial*[ scene->mNumMaterials ];
|
||||
std::copy( mMaterials.begin(), mMaterials.end(), scene->mMaterials );
|
||||
std::copy( mMatArray.begin(), mMatArray.end(), scene->mMaterials );
|
||||
}
|
||||
scene->mRootNode->mNumChildren = static_cast<unsigned int>(children.size());
|
||||
scene->mRootNode->mChildren = new aiNode*[scene->mRootNode->mNumChildren]();
|
||||
|
@ -128,11 +133,11 @@ private:
|
|||
|
||||
const char *attrib( nullptr );
|
||||
std::string name, type;
|
||||
attrib = xmlReader->getAttributeValue( D3MF::XmlTag::name.c_str() );
|
||||
attrib = xmlReader->getAttributeValue( D3MF::XmlTag::id.c_str() );
|
||||
if ( nullptr != attrib ) {
|
||||
name = attrib;
|
||||
}
|
||||
attrib = xmlReader->getAttributeValue( D3MF::XmlTag::name.c_str() );
|
||||
attrib = xmlReader->getAttributeValue( D3MF::XmlTag::type.c_str() );
|
||||
if ( nullptr != attrib ) {
|
||||
type = attrib;
|
||||
}
|
||||
|
@ -162,7 +167,7 @@ private:
|
|||
return node.release();
|
||||
}
|
||||
|
||||
aiMesh* ReadMesh() {
|
||||
aiMesh *ReadMesh() {
|
||||
aiMesh* mesh = new aiMesh();
|
||||
while(ReadToEndElement(D3MF::XmlTag::mesh)) {
|
||||
if(xmlReader->getNodeName() == D3MF::XmlTag::vertices) {
|
||||
|
@ -177,7 +182,6 @@ private:
|
|||
|
||||
void ImportVertices(aiMesh* mesh) {
|
||||
std::vector<aiVector3D> vertices;
|
||||
|
||||
while(ReadToEndElement(D3MF::XmlTag::vertices)) {
|
||||
if(xmlReader->getNodeName() == D3MF::XmlTag::vertex) {
|
||||
vertices.push_back(ReadVertex());
|
||||
|
@ -234,9 +238,27 @@ private:
|
|||
}
|
||||
|
||||
void ReadBaseMaterials() {
|
||||
std::vector<unsigned int> MatIdArray;
|
||||
const char *baseMaterialId( xmlReader->getAttributeValue( D3MF::XmlTag::basematerials_id.c_str() ) );
|
||||
if ( nullptr != baseMaterialId ) {
|
||||
unsigned int id = std::atoi( baseMaterialId );
|
||||
const size_t newMatIdx( mMatArray.size() );
|
||||
if ( id != mActiveMatGroup ) {
|
||||
mActiveMatGroup = id;
|
||||
MatId2MatArray::const_iterator it( mMatId2MatArray.find( id ) );
|
||||
if ( mMatId2MatArray.end() == it ) {
|
||||
MatIdArray.clear();
|
||||
mMatId2MatArray[ id ] = MatIdArray;
|
||||
} else {
|
||||
MatIdArray = it->second;
|
||||
}
|
||||
}
|
||||
MatIdArray.push_back( newMatIdx );
|
||||
mMatId2MatArray[ mActiveMatGroup ] = MatIdArray;
|
||||
}
|
||||
|
||||
while ( ReadToEndElement( D3MF::XmlTag::basematerials ) ) {
|
||||
mMaterials.push_back( readMaterialDef() );
|
||||
xmlReader->read();
|
||||
mMatArray.push_back( readMaterialDef() );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -285,24 +307,37 @@ private:
|
|||
return true;
|
||||
}
|
||||
|
||||
void assignDiffuseColor( aiMaterial *mat ) {
|
||||
const char *color = xmlReader->getAttributeValue( D3MF::XmlTag::basematerials_displaycolor.c_str() );
|
||||
aiColor4D diffuse;
|
||||
if ( parseColor( color, diffuse ) ) {
|
||||
mat->AddProperty<aiColor4D>( &diffuse, 1, AI_MATKEY_COLOR_DIFFUSE );
|
||||
}
|
||||
|
||||
}
|
||||
aiMaterial *readMaterialDef() {
|
||||
aiMaterial *mat( nullptr );
|
||||
const char *name( nullptr );
|
||||
const char *color( nullptr );
|
||||
const std::string nodeName( xmlReader->getNodeName() );
|
||||
if ( nodeName == D3MF::XmlTag::basematerials_base ) {
|
||||
name = xmlReader->getAttributeValue( D3MF::XmlTag::basematerials_name.c_str() );
|
||||
|
||||
std::string stdMatName;
|
||||
aiString matName;
|
||||
matName.Set( name );
|
||||
std::string strId( to_string( mActiveMatGroup ) );
|
||||
stdMatName += "id";
|
||||
stdMatName += strId;
|
||||
stdMatName += "_";
|
||||
if ( nullptr != name ) {
|
||||
stdMatName += std::string( name );
|
||||
} else {
|
||||
stdMatName += "basemat";
|
||||
}
|
||||
matName.Set( stdMatName );
|
||||
|
||||
mat = new aiMaterial;
|
||||
mat->AddProperty( &matName, AI_MATKEY_NAME );
|
||||
|
||||
color = xmlReader->getAttributeValue( D3MF::XmlTag::basematerials_displaycolor.c_str() );
|
||||
aiColor4D diffuse;
|
||||
if ( parseColor( color, diffuse ) ) {
|
||||
mat->AddProperty<aiColor4D>( &diffuse, 1, AI_MATKEY_COLOR_DIFFUSE );
|
||||
}
|
||||
assignDiffuseColor( mat );
|
||||
}
|
||||
|
||||
return mat;
|
||||
|
@ -339,7 +374,9 @@ private:
|
|||
|
||||
private:
|
||||
std::vector<aiMesh*> mMeshes;
|
||||
std::vector<aiMaterial*> mMaterials;
|
||||
MatArray mMatArray;
|
||||
unsigned int mActiveMatGroup;
|
||||
MatId2MatArray mMatId2MatArray;
|
||||
XmlReader* xmlReader;
|
||||
};
|
||||
|
||||
|
@ -360,7 +397,6 @@ static const aiImporterDesc desc = {
|
|||
Extension.c_str()
|
||||
};
|
||||
|
||||
|
||||
D3MFImporter::D3MFImporter()
|
||||
: BaseImporter() {
|
||||
// empty
|
||||
|
@ -370,14 +406,19 @@ D3MFImporter::~D3MFImporter() {
|
|||
// empty
|
||||
}
|
||||
|
||||
bool D3MFImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const {
|
||||
const std::string extension = GetExtension(pFile);
|
||||
bool D3MFImporter::CanRead(const std::string &filename, IOSystem *pIOHandler, bool checkSig) const {
|
||||
const std::string extension( GetExtension( filename ) );
|
||||
if(extension == Extension ) {
|
||||
return true;
|
||||
} else if ( !extension.length() || checkSig ) {
|
||||
if (nullptr == pIOHandler ) {
|
||||
return true;
|
||||
if ( nullptr == pIOHandler ) {
|
||||
return false;
|
||||
}
|
||||
if ( !D3MF::D3MFOpcPackage::isZipArchive( pIOHandler, filename ) ) {
|
||||
return false;
|
||||
}
|
||||
D3MF::D3MFOpcPackage opcPackage( pIOHandler, filename );
|
||||
return opcPackage.validate();
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -391,8 +432,8 @@ const aiImporterDesc *D3MFImporter::GetInfo() const {
|
|||
return &desc;
|
||||
}
|
||||
|
||||
void D3MFImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) {
|
||||
D3MF::D3MFOpcPackage opcPackage(pIOHandler, pFile);
|
||||
void D3MFImporter::InternReadFile( const std::string &filename, aiScene *pScene, IOSystem *pIOHandler ) {
|
||||
D3MF::D3MFOpcPackage opcPackage(pIOHandler, filename);
|
||||
|
||||
std::unique_ptr<CIrrXML_IOStreamReader> xmlStream(new CIrrXML_IOStreamReader(opcPackage.RootStream()));
|
||||
std::unique_ptr<D3MF::XmlReader> xmlReader(irr::io::createIrrXMLReader(xmlStream.get()));
|
||||
|
|
|
@ -247,13 +247,13 @@ private:
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
// Constructor.
|
||||
D3MFZipArchive::D3MFZipArchive(IOSystem* pIOHandler, const std::string& rFile)
|
||||
: m_ZipFileHandle(NULL)
|
||||
: m_ZipFileHandle( nullptr )
|
||||
, m_ArchiveMap() {
|
||||
if (! rFile.empty()) {
|
||||
zlib_filefunc_def mapping = IOSystem2Unzip::get(pIOHandler);
|
||||
|
||||
m_ZipFileHandle = unzOpen2(rFile.c_str(), &mapping);
|
||||
if(m_ZipFileHandle != NULL) {
|
||||
if(m_ZipFileHandle != nullptr ) {
|
||||
mapArchive();
|
||||
}
|
||||
}
|
||||
|
@ -267,32 +267,32 @@ D3MFZipArchive::~D3MFZipArchive() {
|
|||
}
|
||||
m_ArchiveMap.clear();
|
||||
|
||||
if(m_ZipFileHandle != NULL) {
|
||||
if(m_ZipFileHandle != nullptr) {
|
||||
unzClose(m_ZipFileHandle);
|
||||
m_ZipFileHandle = NULL;
|
||||
m_ZipFileHandle = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Returns true, if the archive is already open.
|
||||
bool D3MFZipArchive::isOpen() const {
|
||||
return (m_ZipFileHandle != NULL);
|
||||
return (m_ZipFileHandle != nullptr );
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Returns true, if the filename is part of the archive.
|
||||
bool D3MFZipArchive::Exists(const char* pFile) const {
|
||||
ai_assert(pFile != NULL);
|
||||
ai_assert(pFile != nullptr );
|
||||
|
||||
bool exist = false;
|
||||
if ( pFile == nullptr ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pFile != NULL) {
|
||||
std::string rFile(pFile);
|
||||
std::map<std::string, ZipFile*>::const_iterator it = m_ArchiveMap.find(rFile);
|
||||
|
||||
if(it != m_ArchiveMap.end()) {
|
||||
exist = true;
|
||||
}
|
||||
std::string rFile(pFile);
|
||||
std::map<std::string, ZipFile*>::const_iterator it = m_ArchiveMap.find(rFile);
|
||||
bool exist( false );
|
||||
if(it != m_ArchiveMap.end()) {
|
||||
exist = true;
|
||||
}
|
||||
|
||||
return exist;
|
||||
|
@ -434,8 +434,8 @@ public:
|
|||
|
||||
std::vector<OpcPackageRelationshipPtr> m_relationShips;
|
||||
};
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
D3MFOpcPackage::D3MFOpcPackage(IOSystem* pIOHandler, const std::string& rFile)
|
||||
: mRootStream(nullptr)
|
||||
, mZipArchive() {
|
||||
|
@ -460,7 +460,7 @@ D3MFOpcPackage::D3MFOpcPackage(IOSystem* pIOHandler, const std::string& rFile)
|
|||
if ( rootFile.size() > 0 && rootFile[ 0 ] == '/' ) {
|
||||
rootFile = rootFile.substr( 1 );
|
||||
if ( rootFile[ 0 ] == '/' ) {
|
||||
// deal with zipbug
|
||||
// deal with zip-bug
|
||||
rootFile = rootFile.substr( 1 );
|
||||
}
|
||||
}
|
||||
|
@ -470,18 +470,9 @@ D3MFOpcPackage::D3MFOpcPackage(IOSystem* pIOHandler, const std::string& rFile)
|
|||
mRootStream = mZipArchive->Open(rootFile.c_str());
|
||||
ai_assert( mRootStream != nullptr );
|
||||
if ( nullptr == mRootStream ) {
|
||||
throw DeadlyExportError( "Cannot open rootfile in archive : " + rootFile );
|
||||
throw DeadlyExportError( "Cannot open root-file in archive : " + rootFile );
|
||||
}
|
||||
|
||||
// const size_t size = zipArchive->FileSize();
|
||||
// m_Data.resize( size );
|
||||
|
||||
// const size_t readSize = pMapFile->Read( &m_Data[0], sizeof( char ), size );
|
||||
// if ( readSize != size )
|
||||
// {
|
||||
// m_Data.clear();
|
||||
// return false;
|
||||
// }
|
||||
mZipArchive->Close( fileStream );
|
||||
|
||||
} else if( file == D3MF::XmlTag::CONTENT_TYPES_ARCHIVE) {
|
||||
|
@ -498,6 +489,25 @@ IOStream* D3MFOpcPackage::RootStream() const {
|
|||
return mRootStream;
|
||||
}
|
||||
|
||||
static const std::string ModelRef = "3D/3dmodel.model";
|
||||
|
||||
bool D3MFOpcPackage::validate() {
|
||||
if ( nullptr == mRootStream || nullptr == mZipArchive ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return mZipArchive->Exists( ModelRef.c_str() );
|
||||
}
|
||||
|
||||
bool D3MFOpcPackage::isZipArchive( IOSystem* pIOHandler, const std::string& rFile ) {
|
||||
D3MF::D3MFZipArchive ar( pIOHandler, rFile );
|
||||
if ( !ar.isOpen() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string D3MFOpcPackage::ReadPackageRootRelationship(IOStream* stream) {
|
||||
std::unique_ptr<CIrrXML_IOStreamReader> xmlStream(new CIrrXML_IOStreamReader(stream));
|
||||
std::unique_ptr<XmlReader> xml(irr::io::createIrrXMLReader(xmlStream.get()));
|
||||
|
@ -508,14 +518,14 @@ std::string D3MFOpcPackage::ReadPackageRootRelationship(IOStream* stream) {
|
|||
return rel->type == XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE;
|
||||
});
|
||||
|
||||
if(itr == reader.m_relationShips.end())
|
||||
throw DeadlyImportError("Cannot find " + XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE);
|
||||
if ( itr == reader.m_relationShips.end() ) {
|
||||
throw DeadlyImportError( "Cannot find " + XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE );
|
||||
}
|
||||
|
||||
return (*itr)->target;
|
||||
}
|
||||
|
||||
} // Namespace D3MF
|
||||
|
||||
} // Namespace Assimp
|
||||
|
||||
#endif //ASSIMP_BUILD_NO_3MF_IMPORTER
|
||||
|
|
|
@ -51,8 +51,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
namespace Assimp {
|
||||
namespace D3MF {
|
||||
|
||||
typedef irr::io::IrrXMLReader XmlReader;
|
||||
typedef std::shared_ptr<XmlReader> XmlReaderPtr;
|
||||
using XmlReader = irr::io::IrrXMLReader ;
|
||||
using XmlReaderPtr = std::shared_ptr<XmlReader> ;
|
||||
|
||||
struct OpcPackageRelationship {
|
||||
std::string id;
|
||||
|
@ -64,9 +64,11 @@ class D3MFZipArchive;
|
|||
|
||||
class D3MFOpcPackage {
|
||||
public:
|
||||
D3MFOpcPackage(IOSystem* pIOHandler, const std::string& rFile);
|
||||
D3MFOpcPackage( IOSystem* pIOHandler, const std::string& rFile );
|
||||
~D3MFOpcPackage();
|
||||
IOStream* RootStream() const;
|
||||
bool validate();
|
||||
static bool isZipArchive( IOSystem* pIOHandler, const std::string& rFile );
|
||||
|
||||
protected:
|
||||
std::string ReadPackageRootRelationship(IOStream* stream);
|
||||
|
@ -76,7 +78,7 @@ private:
|
|||
std::unique_ptr<D3MFZipArchive> mZipArchive;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
} // Namespace D3MF
|
||||
} // Namespace Assimp
|
||||
|
||||
#endif // D3MFOPCPACKAGE_H
|
||||
|
|
|
@ -643,14 +643,14 @@ void Converter::GenerateTransformationNodeChain( const Model& model, std::vector
|
|||
if ( ok && PreRotation.SquareLength() > zero_epsilon ) {
|
||||
is_complex = true;
|
||||
|
||||
GetRotationMatrix( rot, PreRotation, chain[ TransformationComp_PreRotation ] );
|
||||
GetRotationMatrix( Model::RotOrder::RotOrder_EulerXYZ, PreRotation, chain[ TransformationComp_PreRotation ] );
|
||||
}
|
||||
|
||||
const aiVector3D& PostRotation = PropertyGet<aiVector3D>( props, "PostRotation", ok );
|
||||
if ( ok && PostRotation.SquareLength() > zero_epsilon ) {
|
||||
is_complex = true;
|
||||
|
||||
GetRotationMatrix( rot, PostRotation, chain[ TransformationComp_PostRotation ] );
|
||||
GetRotationMatrix( Model::RotOrder::RotOrder_EulerXYZ, PostRotation, chain[ TransformationComp_PostRotation ] );
|
||||
}
|
||||
|
||||
const aiVector3D& RotationPivot = PropertyGet<aiVector3D>( props, "RotationPivot", ok );
|
||||
|
|
|
@ -100,26 +100,22 @@ IRRImporter::~IRRImporter()
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Returns whether the class can handle the format of the given file.
|
||||
bool IRRImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
|
||||
{
|
||||
/* NOTE: A simple check for the file extension is not enough
|
||||
* here. Irrmesh and irr are easy, but xml is too generic
|
||||
* and could be collada, too. So we need to open the file and
|
||||
* search for typical tokens.
|
||||
*/
|
||||
bool IRRImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const {
|
||||
const std::string extension = GetExtension(pFile);
|
||||
|
||||
if (extension == "irr")return true;
|
||||
else if (extension == "xml" || checkSig)
|
||||
{
|
||||
if ( extension == "irr" ) {
|
||||
return true;
|
||||
} else if (extension == "xml" || checkSig) {
|
||||
/* If CanRead() is called in order to check whether we
|
||||
* support a specific file extension in general pIOHandler
|
||||
* might be NULL and it's our duty to return true here.
|
||||
*/
|
||||
if (!pIOHandler)return true;
|
||||
if ( nullptr == pIOHandler ) {
|
||||
return true;
|
||||
}
|
||||
const char* tokens[] = {"irr_scene"};
|
||||
return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -148,6 +148,17 @@ PlyExporter::PlyExporter(const char* _filename, const aiScene* pScene, bool bina
|
|||
<< aiGetVersionMajor() << '.' << aiGetVersionMinor() << '.'
|
||||
<< aiGetVersionRevision() << ")" << endl;
|
||||
|
||||
// Look through materials for a diffuse texture, and add it if found
|
||||
for ( unsigned int i = 0; i < pScene->mNumMaterials; ++i )
|
||||
{
|
||||
const aiMaterial* const mat = pScene->mMaterials[i];
|
||||
aiString s;
|
||||
if ( AI_SUCCESS == mat->Get( AI_MATKEY_TEXTURE_DIFFUSE( 0 ), s ) )
|
||||
{
|
||||
mOutput << "comment TextureFile " << s.data << endl;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: probably want to check here rather than just assume something
|
||||
// definitely not good to always write float even if we might have double precision
|
||||
|
||||
|
|
|
@ -55,7 +55,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
/// @return The number of written characters if the buffer size was big enough. If an encoding error occurs, a negative number is returned.
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
|
||||
inline int c99_ai_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap) {
|
||||
inline
|
||||
int c99_ai_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap) {
|
||||
int count(-1);
|
||||
if (0 != size) {
|
||||
count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap);
|
||||
|
@ -67,7 +68,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
return count;
|
||||
}
|
||||
|
||||
inline int ai_snprintf(char *outBuf, size_t size, const char *format, ...) {
|
||||
inline
|
||||
int ai_snprintf(char *outBuf, size_t size, const char *format, ...) {
|
||||
int count;
|
||||
va_list ap;
|
||||
|
||||
|
@ -82,14 +84,24 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
# define ai_snprintf snprintf
|
||||
#endif
|
||||
|
||||
/// @fn to_string
|
||||
/// @brief The portable version of to_string ( some gcc-versions on embedded devices are not supporting this).
|
||||
/// @param value The value to write into the std::string.
|
||||
/// @return The value as a std::string
|
||||
template <typename T>
|
||||
inline
|
||||
std::string to_string( T value ) {
|
||||
std::ostringstream os;
|
||||
os << value;
|
||||
|
||||
return os.str();
|
||||
}
|
||||
|
||||
/// @fn ai_strtof
|
||||
/// @brief The portable version of strtof.
|
||||
/// @param begin The first character of the string.
|
||||
/// @param end The last character
|
||||
/// @return The float value, 0.0f in cas of an error.
|
||||
inline
|
||||
float ai_strtof( const char *begin, const char *end ) {
|
||||
if ( nullptr == begin ) {
|
||||
|
@ -107,5 +119,23 @@ float ai_strtof( const char *begin, const char *end ) {
|
|||
return val;
|
||||
}
|
||||
|
||||
#endif // INCLUDED_AI_STRINGUTILS_H
|
||||
/// @fn DecimalToHexa
|
||||
/// @brief The portable to convert a decimal value into a hexadecimal string.
|
||||
/// @param toConvert Value to convert
|
||||
/// @return The hexadecimal string, is empty in case of an error.
|
||||
template<class T>
|
||||
inline
|
||||
std::string DecimalToHexa( T toConvert ) {
|
||||
std::string result;
|
||||
std::stringstream ss;
|
||||
ss << std::hex << toConvert;
|
||||
ss >> result;
|
||||
|
||||
for ( size_t i = 0; i < result.size(); ++i ) {
|
||||
result[ i ] = toupper( result[ i ] );
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // INCLUDED_AI_STRINGUTILS_H
|
||||
|
|
|
@ -146,7 +146,6 @@ uint8_t HexOctetToDecimal(const char* in) {
|
|||
return ((uint8_t)HexDigitToDecimal(in[0])<<4)+(uint8_t)HexDigitToDecimal(in[1]);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------
|
||||
// signed variant of strtoul10
|
||||
// ------------------------------------------------------------------------------------
|
||||
|
@ -353,7 +352,6 @@ ai_real fast_atof(const char* c) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
|
||||
inline
|
||||
ai_real fast_atof( const char* c, const char** cout) {
|
||||
ai_real ret(0.0);
|
||||
|
|
|
@ -45,7 +45,9 @@ INCLUDE_DIRECTORIES(
|
|||
${Assimp_SOURCE_DIR}/include
|
||||
${Assimp_SOURCE_DIR}/code
|
||||
)
|
||||
|
||||
if (MSVC)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING")
|
||||
endif()
|
||||
# Add the temporary output directories to the library path to make sure the
|
||||
# Assimp library can be found, even if it is not installed system-wide yet.
|
||||
LINK_DIRECTORIES( ${Assimp_BINARY_DIR} ${AssetImporter_BINARY_DIR}/lib )
|
||||
|
|
|
@ -86,4 +86,12 @@ TEST_F( utD3MFImporterExporter, export3MFtoMemTest ) {
|
|||
EXPECT_TRUE( exporterTest() );
|
||||
}
|
||||
|
||||
TEST_F( utD3MFImporterExporter, roundtrip3MFtoMemTest ) {
|
||||
EXPECT_TRUE( exporterTest() );
|
||||
|
||||
Assimp::Importer importer;
|
||||
const aiScene *scene = importer.ReadFile( "test.3mf", 0 );
|
||||
EXPECT_NE( nullptr, scene );
|
||||
}
|
||||
|
||||
#endif // ASSIMP_BUILD_NO_EXPORT
|
||||
|
|
Loading…
Reference in New Issue