Merge branch 'master' into md2orient
commit
7a3c8e5504
|
@ -527,12 +527,12 @@ ENDIF()
|
||||||
MARK_AS_ADVANCED ( ASSIMP_BUILD_ARCHITECTURE ASSIMP_BUILD_COMPILER )
|
MARK_AS_ADVANCED ( ASSIMP_BUILD_ARCHITECTURE ASSIMP_BUILD_COMPILER )
|
||||||
|
|
||||||
SET ( ASSIMP_BUILD_NONFREE_C4D_IMPORTER OFF CACHE BOOL
|
SET ( ASSIMP_BUILD_NONFREE_C4D_IMPORTER OFF CACHE BOOL
|
||||||
"Build the C4D importer, which relies on the non-free Melange SDK."
|
"Build the C4D importer, which relies on the non-free Cineware SDK."
|
||||||
)
|
)
|
||||||
|
|
||||||
IF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
|
IF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
|
||||||
IF ( MSVC )
|
IF ( MSVC )
|
||||||
SET(C4D_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/contrib/Melange/includes")
|
SET(C4D_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/contrib/Cineware/includes")
|
||||||
|
|
||||||
# pick the correct prebuilt library
|
# pick the correct prebuilt library
|
||||||
IF(MSVC15)
|
IF(MSVC15)
|
||||||
|
@ -551,22 +551,23 @@ IF (ASSIMP_BUILD_NONFREE_C4D_IMPORTER)
|
||||||
)
|
)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
SET(C4D_LIB_BASE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/contrib/Melange/libraries/win")
|
SET(C4D_LIB_BASE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/contrib/Cineware/libraries/win")
|
||||||
|
|
||||||
SET(C4D_DEBUG_LIBRARIES
|
SET(C4D_DEBUG_LIBRARIES
|
||||||
"${C4D_LIB_BASE_PATH}/melangelib${C4D_LIB_POSTFIX}/melangelib_debug.lib"
|
"${C4D_LIB_BASE_PATH}/cinewarelib${C4D_LIB_POSTFIX}/cinewarelib_debug.lib"
|
||||||
"${C4D_LIB_BASE_PATH}/jpeglib${C4D_LIB_POSTFIX}/jpeglib_debug.lib"
|
"${C4D_LIB_BASE_PATH}/jpeglib${C4D_LIB_POSTFIX}/jpeglib_debug.lib"
|
||||||
)
|
)
|
||||||
SET(C4D_RELEASE_LIBRARIES
|
SET(C4D_RELEASE_LIBRARIES
|
||||||
"${C4D_LIB_BASE_PATH}/melangelib${C4D_LIB_POSTFIX}/melangelib_release.lib"
|
"${C4D_LIB_BASE_PATH}/cinewarelib${C4D_LIB_POSTFIX}/cinewarelib_release.lib"
|
||||||
"${C4D_LIB_BASE_PATH}/jpeglib${C4D_LIB_POSTFIX}/jpeglib_release.lib"
|
"${C4D_LIB_BASE_PATH}/jpeglib${C4D_LIB_POSTFIX}/jpeglib_release.lib"
|
||||||
)
|
)
|
||||||
|
|
||||||
# winsock and winmm are necessary dependencies of melange (this is undocumented, but true.)
|
# winsock and winmm are necessary (and undocumented) dependencies of Cineware SDK because
|
||||||
|
# it can be used to communicate with a running Cinema 4D instance
|
||||||
SET(C4D_EXTRA_LIBRARIES WSock32.lib Winmm.lib)
|
SET(C4D_EXTRA_LIBRARIES WSock32.lib Winmm.lib)
|
||||||
ELSE ()
|
ELSE ()
|
||||||
MESSAGE( FATAL_ERROR
|
MESSAGE( FATAL_ERROR
|
||||||
"C4D is currently only available on Windows with melange SDK installed in contrib/Melange"
|
"C4D is currently only available on Windows with Cineware SDK installed in contrib/Cineware"
|
||||||
)
|
)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
ELSE ()
|
ELSE ()
|
||||||
|
|
|
@ -69,7 +69,7 @@ void Discreet3DSImporter::ReplaceDefaultMaterial() {
|
||||||
for (unsigned int i = 0; i < mScene->mMaterials.size(); ++i) {
|
for (unsigned int i = 0; i < mScene->mMaterials.size(); ++i) {
|
||||||
std::string s = mScene->mMaterials[i].mName;
|
std::string s = mScene->mMaterials[i].mName;
|
||||||
for (std::string::iterator it = s.begin(); it != s.end(); ++it) {
|
for (std::string::iterator it = s.begin(); it != s.end(); ++it) {
|
||||||
*it = static_cast<char>(::tolower(*it));
|
*it = static_cast<char>(::tolower(static_cast<unsigned char>(*it)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (std::string::npos == s.find("default")) continue;
|
if (std::string::npos == s.find("default")) continue;
|
||||||
|
@ -212,7 +212,7 @@ void Discreet3DSImporter::ConvertMaterial(D3DS::Material &oldMat,
|
||||||
mat.AddProperty(&tex, AI_MATKEY_GLOBAL_BACKGROUND_IMAGE);
|
mat.AddProperty(&tex, AI_MATKEY_GLOBAL_BACKGROUND_IMAGE);
|
||||||
|
|
||||||
// Be sure this is only done for the first material
|
// Be sure this is only done for the first material
|
||||||
mBackgroundImage = std::string("");
|
mBackgroundImage = std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
// At first add the base ambient color of the scene to the material
|
// At first add the base ambient color of the scene to the material
|
||||||
|
|
|
@ -102,13 +102,14 @@ private:
|
||||||
// preserves the mesh's given name if it has one. |index| is the index
|
// preserves the mesh's given name if it has one. |index| is the index
|
||||||
// of the mesh in |aiScene::mMeshes|.
|
// of the mesh in |aiScene::mMeshes|.
|
||||||
std::string GetMeshName(const aiMesh &mesh, unsigned int index, const aiNode &node) {
|
std::string GetMeshName(const aiMesh &mesh, unsigned int index, const aiNode &node) {
|
||||||
static const std::string underscore = "_";
|
static const char underscore = '_';
|
||||||
char postfix[10] = { 0 };
|
char postfix[10] = { 0 };
|
||||||
ASSIMP_itoa10(postfix, index);
|
ASSIMP_itoa10(postfix, index);
|
||||||
|
|
||||||
std::string result = node.mName.C_Str();
|
std::string result = node.mName.C_Str();
|
||||||
if (mesh.mName.length > 0) {
|
if (mesh.mName.length > 0) {
|
||||||
result += underscore + mesh.mName.C_Str();
|
result += underscore;
|
||||||
|
result += mesh.mName.C_Str();
|
||||||
}
|
}
|
||||||
return result + underscore + postfix;
|
return result + underscore + postfix;
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,20 +61,10 @@ namespace D3DS {
|
||||||
#include <assimp/Compiler/pushpack1.h>
|
#include <assimp/Compiler/pushpack1.h>
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** Discreet3DS class: Helper class for loading 3ds files. Defines chunks
|
/** Defines chunks and data structures.
|
||||||
* and data structures.
|
|
||||||
*/
|
*/
|
||||||
class Discreet3DS {
|
namespace Discreet3DS {
|
||||||
private:
|
|
||||||
Discreet3DS() AI_NO_EXCEPT {
|
|
||||||
// empty
|
|
||||||
}
|
|
||||||
|
|
||||||
~Discreet3DS() {
|
|
||||||
// empty
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
//! data structure for a single chunk in a .3ds file
|
//! data structure for a single chunk in a .3ds file
|
||||||
struct Chunk {
|
struct Chunk {
|
||||||
uint16_t Flag;
|
uint16_t Flag;
|
||||||
|
@ -314,7 +304,7 @@ public:
|
||||||
// camera sub-chunks
|
// camera sub-chunks
|
||||||
CHUNK_CAM_RANGES = 0x4720
|
CHUNK_CAM_RANGES = 0x4720
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** Helper structure representing a 3ds mesh face */
|
/** Helper structure representing a 3ds mesh face */
|
||||||
|
|
|
@ -143,7 +143,13 @@ void Discreet3DSImporter::SetupProperties(const Importer * /*pImp*/) {
|
||||||
// Imports the given file into the given scene structure.
|
// Imports the given file into the given scene structure.
|
||||||
void Discreet3DSImporter::InternReadFile(const std::string &pFile,
|
void Discreet3DSImporter::InternReadFile(const std::string &pFile,
|
||||||
aiScene *pScene, IOSystem *pIOHandler) {
|
aiScene *pScene, IOSystem *pIOHandler) {
|
||||||
StreamReaderLE theStream(pIOHandler->Open(pFile, "rb"));
|
|
||||||
|
auto theFile = pIOHandler->Open(pFile, "rb");
|
||||||
|
if (!theFile) {
|
||||||
|
throw DeadlyImportError("3DS: Could not open ", pFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
StreamReaderLE theStream(theFile);
|
||||||
|
|
||||||
// We should have at least one chunk
|
// We should have at least one chunk
|
||||||
if (theStream.GetRemainingSize() < 16) {
|
if (theStream.GetRemainingSize() < 16) {
|
||||||
|
@ -164,7 +170,7 @@ void Discreet3DSImporter::InternReadFile(const std::string &pFile,
|
||||||
mRootNode->mHierarchyIndex = -1;
|
mRootNode->mHierarchyIndex = -1;
|
||||||
mRootNode->mParent = nullptr;
|
mRootNode->mParent = nullptr;
|
||||||
mMasterScale = 1.0f;
|
mMasterScale = 1.0f;
|
||||||
mBackgroundImage = "";
|
mBackgroundImage = std::string();
|
||||||
bHasBG = false;
|
bHasBG = false;
|
||||||
bIsPrj = false;
|
bIsPrj = false;
|
||||||
|
|
||||||
|
@ -981,9 +987,9 @@ void Discreet3DSImporter::ParseMeshChunk() {
|
||||||
mMesh.mMat.a3 = stream->GetF4();
|
mMesh.mMat.a3 = stream->GetF4();
|
||||||
mMesh.mMat.b3 = stream->GetF4();
|
mMesh.mMat.b3 = stream->GetF4();
|
||||||
mMesh.mMat.c3 = stream->GetF4();
|
mMesh.mMat.c3 = stream->GetF4();
|
||||||
mMesh.mMat.d1 = stream->GetF4();
|
mMesh.mMat.a4 = stream->GetF4();
|
||||||
mMesh.mMat.d2 = stream->GetF4();
|
mMesh.mMat.b4 = stream->GetF4();
|
||||||
mMesh.mMat.d3 = stream->GetF4();
|
mMesh.mMat.c4 = stream->GetF4();
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Discreet3DS::CHUNK_MAPLIST: {
|
case Discreet3DS::CHUNK_MAPLIST: {
|
||||||
|
|
|
@ -44,63 +44,66 @@ namespace Assimp {
|
||||||
namespace D3MF {
|
namespace D3MF {
|
||||||
|
|
||||||
namespace XmlTag {
|
namespace XmlTag {
|
||||||
|
// Root tag
|
||||||
|
const char* const RootTag = "3MF";
|
||||||
|
|
||||||
// Meta-data
|
// Meta-data
|
||||||
static const std::string meta = "metadata";
|
const char* const meta = "metadata";
|
||||||
static const std::string meta_name = "name";
|
const char* const meta_name = "name";
|
||||||
|
|
||||||
// Model-data specific tags
|
// Model-data specific tags
|
||||||
static const std::string model = "model";
|
const char* const model = "model";
|
||||||
static const std::string model_unit = "unit";
|
const char* const model_unit = "unit";
|
||||||
static const std::string metadata = "metadata";
|
const char* const metadata = "metadata";
|
||||||
static const std::string resources = "resources";
|
const char* const resources = "resources";
|
||||||
static const std::string object = "object";
|
const char* const object = "object";
|
||||||
static const std::string mesh = "mesh";
|
const char* const mesh = "mesh";
|
||||||
static const std::string components = "components";
|
const char* const components = "components";
|
||||||
static const std::string component = "component";
|
const char* const component = "component";
|
||||||
static const std::string vertices = "vertices";
|
const char* const vertices = "vertices";
|
||||||
static const std::string vertex = "vertex";
|
const char* const vertex = "vertex";
|
||||||
static const std::string triangles = "triangles";
|
const char* const triangles = "triangles";
|
||||||
static const std::string triangle = "triangle";
|
const char* const triangle = "triangle";
|
||||||
static const std::string x = "x";
|
const char* const x = "x";
|
||||||
static const std::string y = "y";
|
const char* const y = "y";
|
||||||
static const std::string z = "z";
|
const char* const z = "z";
|
||||||
static const std::string v1 = "v1";
|
const char* const v1 = "v1";
|
||||||
static const std::string v2 = "v2";
|
const char* const v2 = "v2";
|
||||||
static const std::string v3 = "v3";
|
const char* const v3 = "v3";
|
||||||
static const std::string id = "id";
|
const char* const id = "id";
|
||||||
static const std::string pid = "pid";
|
const char* const pid = "pid";
|
||||||
static const std::string pindex = "pindex";
|
const char* const pindex = "pindex";
|
||||||
static const std::string p1 = "p1";
|
const char* const p1 = "p1";
|
||||||
static const std::string name = "name";
|
const char* const name = "name";
|
||||||
static const std::string type = "type";
|
const char* const type = "type";
|
||||||
static const std::string build = "build";
|
const char* const build = "build";
|
||||||
static const std::string item = "item";
|
const char* const item = "item";
|
||||||
static const std::string objectid = "objectid";
|
const char* const objectid = "objectid";
|
||||||
static const std::string transform = "transform";
|
const char* const transform = "transform";
|
||||||
|
|
||||||
// Material definitions
|
// Material definitions
|
||||||
static const std::string basematerials = "basematerials";
|
const char* const basematerials = "basematerials";
|
||||||
static const std::string basematerials_id = "id";
|
const char* const basematerials_id = "id";
|
||||||
static const std::string basematerials_base = "base";
|
const char* const basematerials_base = "base";
|
||||||
static const std::string basematerials_name = "name";
|
const char* const basematerials_name = "name";
|
||||||
static const std::string basematerials_displaycolor = "displaycolor";
|
const char* const basematerials_displaycolor = "displaycolor";
|
||||||
|
|
||||||
// Meta info tags
|
// Meta info tags
|
||||||
static const std::string CONTENT_TYPES_ARCHIVE = "[Content_Types].xml";
|
const char* const CONTENT_TYPES_ARCHIVE = "[Content_Types].xml";
|
||||||
static const std::string ROOT_RELATIONSHIPS_ARCHIVE = "_rels/.rels";
|
const char* const ROOT_RELATIONSHIPS_ARCHIVE = "_rels/.rels";
|
||||||
static const std::string SCHEMA_CONTENTTYPES = "http://schemas.openxmlformats.org/package/2006/content-types";
|
const char* const SCHEMA_CONTENTTYPES = "http://schemas.openxmlformats.org/package/2006/content-types";
|
||||||
static const std::string SCHEMA_RELATIONSHIPS = "http://schemas.openxmlformats.org/package/2006/relationships";
|
const char* const SCHEMA_RELATIONSHIPS = "http://schemas.openxmlformats.org/package/2006/relationships";
|
||||||
static const std::string RELS_RELATIONSHIP_CONTAINER = "Relationships";
|
const char* const RELS_RELATIONSHIP_CONTAINER = "Relationships";
|
||||||
static const std::string RELS_RELATIONSHIP_NODE = "Relationship";
|
const char* const RELS_RELATIONSHIP_NODE = "Relationship";
|
||||||
static const std::string RELS_ATTRIB_TARGET = "Target";
|
const char* const RELS_ATTRIB_TARGET = "Target";
|
||||||
static const std::string RELS_ATTRIB_TYPE = "Type";
|
const char* const RELS_ATTRIB_TYPE = "Type";
|
||||||
static const std::string RELS_ATTRIB_ID = "Id";
|
const char* const RELS_ATTRIB_ID = "Id";
|
||||||
static const std::string PACKAGE_START_PART_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dmodel";
|
const char* const PACKAGE_START_PART_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dmodel";
|
||||||
static const std::string PACKAGE_PRINT_TICKET_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/printticket";
|
const char* const PACKAGE_PRINT_TICKET_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/printticket";
|
||||||
static const std::string PACKAGE_TEXTURE_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dtexture";
|
const char* const PACKAGE_TEXTURE_RELATIONSHIP_TYPE = "http://schemas.microsoft.com/3dmanufacturing/2013/01/3dtexture";
|
||||||
static const std::string PACKAGE_CORE_PROPERTIES_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties";
|
const char* const PACKAGE_CORE_PROPERTIES_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties";
|
||||||
static const std::string PACKAGE_THUMBNAIL_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail";
|
const char* const PACKAGE_THUMBNAIL_RELATIONSHIP_TYPE = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/thumbnail";
|
||||||
}
|
}
|
||||||
|
|
||||||
} // Namespace D3MF
|
} // Namespace D3MF
|
||||||
} // Namespace Assimp
|
} // Namespace Assimp
|
||||||
|
|
|
@ -307,18 +307,26 @@ void D3MFExporter::writeMesh(aiMesh *mesh) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mModelOutput << "<" << XmlTag::mesh << ">" << std::endl;
|
mModelOutput << "<"
|
||||||
mModelOutput << "<" << XmlTag::vertices << ">" << std::endl;
|
<< XmlTag::mesh
|
||||||
|
<< ">" << "\n";
|
||||||
|
mModelOutput << "<"
|
||||||
|
<< XmlTag::vertices
|
||||||
|
<< ">" << "\n";
|
||||||
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
|
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
|
||||||
writeVertex(mesh->mVertices[i]);
|
writeVertex(mesh->mVertices[i]);
|
||||||
}
|
}
|
||||||
mModelOutput << "</" << XmlTag::vertices << ">" << std::endl;
|
mModelOutput << "</"
|
||||||
|
<< XmlTag::vertices << ">"
|
||||||
|
<< "\n";
|
||||||
|
|
||||||
const unsigned int matIdx(mesh->mMaterialIndex);
|
const unsigned int matIdx(mesh->mMaterialIndex);
|
||||||
|
|
||||||
writeFaces(mesh, matIdx);
|
writeFaces(mesh, matIdx);
|
||||||
|
|
||||||
mModelOutput << "</" << XmlTag::mesh << ">" << std::endl;
|
mModelOutput << "</"
|
||||||
|
<< XmlTag::mesh << ">"
|
||||||
|
<< "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3MFExporter::writeVertex(const aiVector3D &pos) {
|
void D3MFExporter::writeVertex(const aiVector3D &pos) {
|
||||||
|
@ -334,27 +342,34 @@ void D3MFExporter::writeFaces(aiMesh *mesh, unsigned int matIdx) {
|
||||||
if (!mesh->HasFaces()) {
|
if (!mesh->HasFaces()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mModelOutput << "<" << XmlTag::triangles << ">" << std::endl;
|
mModelOutput << "<"
|
||||||
|
<< XmlTag::triangles << ">"
|
||||||
|
<< "\n";
|
||||||
for (unsigned int i = 0; i < mesh->mNumFaces; ++i) {
|
for (unsigned int i = 0; i < mesh->mNumFaces; ++i) {
|
||||||
aiFace ¤tFace = mesh->mFaces[i];
|
aiFace ¤tFace = mesh->mFaces[i];
|
||||||
mModelOutput << "<" << XmlTag::triangle << " v1=\"" << currentFace.mIndices[0] << "\" v2=\""
|
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=\"" + ai_to_string(matIdx) + "\" />";
|
<< "\" pid=\"1\" p1=\"" + ai_to_string(matIdx) + "\" />";
|
||||||
mModelOutput << std::endl;
|
mModelOutput << "\n";
|
||||||
}
|
}
|
||||||
mModelOutput << "</" << XmlTag::triangles << ">";
|
mModelOutput << "</"
|
||||||
mModelOutput << std::endl;
|
<< XmlTag::triangles
|
||||||
|
<< ">";
|
||||||
|
mModelOutput << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3MFExporter::writeBuild() {
|
void D3MFExporter::writeBuild() {
|
||||||
mModelOutput << "<" << XmlTag::build << ">" << std::endl;
|
mModelOutput << "<"
|
||||||
|
<< XmlTag::build
|
||||||
|
<< ">"
|
||||||
|
<< "\n";
|
||||||
|
|
||||||
for (size_t i = 0; i < mBuildItems.size(); ++i) {
|
for (size_t i = 0; i < mBuildItems.size(); ++i) {
|
||||||
mModelOutput << "<" << XmlTag::item << " objectid=\"" << i + 2 << "\"/>";
|
mModelOutput << "<" << XmlTag::item << " objectid=\"" << i + 2 << "\"/>";
|
||||||
mModelOutput << std::endl;
|
mModelOutput << "\n";
|
||||||
}
|
}
|
||||||
mModelOutput << "</" << XmlTag::build << ">";
|
mModelOutput << "</" << XmlTag::build << ">";
|
||||||
mModelOutput << std::endl;
|
mModelOutput << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3MFExporter::zipContentType(const std::string &filename) {
|
void D3MFExporter::zipContentType(const std::string &filename) {
|
||||||
|
|
|
@ -42,6 +42,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef ASSIMP_BUILD_NO_3MF_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_3MF_IMPORTER
|
||||||
|
|
||||||
#include "D3MFImporter.h"
|
#include "D3MFImporter.h"
|
||||||
|
#include "3MFXmlTags.h"
|
||||||
|
#include "D3MFOpcPackage.h"
|
||||||
|
|
||||||
#include <assimp/StringComparison.h>
|
#include <assimp/StringComparison.h>
|
||||||
#include <assimp/StringUtils.h>
|
#include <assimp/StringUtils.h>
|
||||||
|
@ -51,17 +53,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
#include <assimp/DefaultLogger.hpp>
|
#include <assimp/DefaultLogger.hpp>
|
||||||
#include <assimp/IOSystem.hpp>
|
#include <assimp/IOSystem.hpp>
|
||||||
|
#include <assimp/fast_atof.h>
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "3MFXmlTags.h"
|
|
||||||
#include "D3MFOpcPackage.h"
|
|
||||||
#include <assimp/fast_atof.h>
|
|
||||||
|
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
namespace D3MF {
|
namespace D3MF {
|
||||||
|
@ -72,32 +72,39 @@ enum class ResourceType {
|
||||||
RT_Unknown
|
RT_Unknown
|
||||||
}; // To be extended with other resource types (eg. material extension resources like Texture2d, Texture2dGroup...)
|
}; // To be extended with other resource types (eg. material extension resources like Texture2d, Texture2dGroup...)
|
||||||
|
|
||||||
class Resource
|
class Resource {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
Resource(int id) :
|
|
||||||
mId(id) {}
|
|
||||||
|
|
||||||
virtual ~Resource() {}
|
|
||||||
|
|
||||||
int mId;
|
int mId;
|
||||||
|
|
||||||
virtual ResourceType getType() {
|
Resource(int id) :
|
||||||
|
mId(id) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~Resource() {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ResourceType getType() const {
|
||||||
return ResourceType::RT_Unknown;
|
return ResourceType::RT_Unknown;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class BaseMaterials : public Resource {
|
class BaseMaterials : public Resource {
|
||||||
public:
|
public:
|
||||||
BaseMaterials(int id) :
|
|
||||||
Resource(id),
|
|
||||||
mMaterials(),
|
|
||||||
mMaterialIndex() {}
|
|
||||||
|
|
||||||
std::vector<aiMaterial *> mMaterials;
|
std::vector<aiMaterial *> mMaterials;
|
||||||
std::vector<unsigned int> mMaterialIndex;
|
std::vector<unsigned int> mMaterialIndex;
|
||||||
|
|
||||||
virtual ResourceType getType() {
|
BaseMaterials(int id) :
|
||||||
|
Resource(id),
|
||||||
|
mMaterials(),
|
||||||
|
mMaterialIndex() {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
|
~BaseMaterials() = default;
|
||||||
|
|
||||||
|
ResourceType getType() const override {
|
||||||
return ResourceType::RT_BaseMaterials;
|
return ResourceType::RT_BaseMaterials;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -109,24 +116,26 @@ struct Component {
|
||||||
|
|
||||||
class Object : public Resource {
|
class Object : public Resource {
|
||||||
public:
|
public:
|
||||||
std::vector<aiMesh*> mMeshes;
|
std::vector<aiMesh *> mMeshes;
|
||||||
std::vector<unsigned int> mMeshIndex;
|
std::vector<unsigned int> mMeshIndex;
|
||||||
std::vector<Component> mComponents;
|
std::vector<Component> mComponents;
|
||||||
std::string mName;
|
std::string mName;
|
||||||
|
|
||||||
Object(int id) :
|
Object(int id) :
|
||||||
Resource(id),
|
Resource(id),
|
||||||
mName(std::string("Object_") + ai_to_string(id)) {}
|
mName(std::string("Object_") + ai_to_string(id)) {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
virtual ResourceType getType() {
|
~Object() = default;
|
||||||
|
|
||||||
|
ResourceType getType() const override {
|
||||||
return ResourceType::RT_Object;
|
return ResourceType::RT_Object;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class XmlSerializer {
|
class XmlSerializer {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
XmlSerializer(XmlParser *xmlParser) :
|
XmlSerializer(XmlParser *xmlParser) :
|
||||||
mResourcesDictionnary(),
|
mResourcesDictionnary(),
|
||||||
mMaterialCount(0),
|
mMaterialCount(0),
|
||||||
|
@ -136,7 +145,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
~XmlSerializer() {
|
~XmlSerializer() {
|
||||||
for (auto it = mResourcesDictionnary.begin(); it != mResourcesDictionnary.end(); it++) {
|
for (auto it = mResourcesDictionnary.begin(); it != mResourcesDictionnary.end(); ++it ) {
|
||||||
delete it->second;
|
delete it->second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -146,28 +155,28 @@ public:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
scene->mRootNode = new aiNode("3MF");
|
scene->mRootNode = new aiNode(XmlTag::RootTag);
|
||||||
|
|
||||||
XmlNode node = mXmlParser->getRootNode().child("model");
|
XmlNode node = mXmlParser->getRootNode().child(XmlTag::model);
|
||||||
if (node.empty()) {
|
if (node.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
XmlNode resNode = node.child("resources");
|
XmlNode resNode = node.child(XmlTag::resources);
|
||||||
for (XmlNode currentNode = resNode.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
|
for (auto ¤tNode : resNode.children()) {
|
||||||
const std::string ¤tNodeName = currentNode.name();
|
const std::string currentNodeName = currentNode.name();
|
||||||
if (currentNodeName == D3MF::XmlTag::object) {
|
if (currentNodeName == XmlTag::object) {
|
||||||
ReadObject(currentNode);;
|
ReadObject(currentNode);
|
||||||
} else if (currentNodeName == D3MF::XmlTag::basematerials) {
|
} else if (currentNodeName == XmlTag::basematerials) {
|
||||||
ReadBaseMaterials(currentNode);
|
ReadBaseMaterials(currentNode);
|
||||||
} else if (currentNodeName == D3MF::XmlTag::meta) {
|
} else if (currentNodeName == XmlTag::meta) {
|
||||||
ReadMetadata(currentNode);
|
ReadMetadata(currentNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
XmlNode buildNode = node.child("build");
|
XmlNode buildNode = node.child(XmlTag::build);
|
||||||
for (XmlNode currentNode = buildNode.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
|
for (auto ¤tNode : buildNode.children()) {
|
||||||
const std::string ¤tNodeName = currentNode.name();
|
const std::string currentNodeName = currentNode.name();
|
||||||
if (currentNodeName == D3MF::XmlTag::item) {
|
if (currentNodeName == XmlTag::item) {
|
||||||
int objectId = -1;
|
int objectId = -1;
|
||||||
std::string transformationMatrixStr;
|
std::string transformationMatrixStr;
|
||||||
aiMatrix4x4 transformationMatrix;
|
aiMatrix4x4 transformationMatrix;
|
||||||
|
@ -186,10 +195,9 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// import the metadata
|
// import the metadata
|
||||||
if (!mMetaData.empty()) {
|
if (!mMetaData.empty()) {
|
||||||
const size_t numMeta(mMetaData.size());
|
const size_t numMeta = mMetaData.size();
|
||||||
scene->mMetaData = aiMetadata::Alloc(static_cast<unsigned int>(numMeta));
|
scene->mMetaData = aiMetadata::Alloc(static_cast<unsigned int>(numMeta));
|
||||||
for (size_t i = 0; i < numMeta; ++i) {
|
for (size_t i = 0; i < numMeta; ++i) {
|
||||||
aiString val(mMetaData[i].value);
|
aiString val(mMetaData[i].value);
|
||||||
|
@ -201,22 +209,22 @@ public:
|
||||||
scene->mNumMeshes = static_cast<unsigned int>(mMeshCount);
|
scene->mNumMeshes = static_cast<unsigned int>(mMeshCount);
|
||||||
if (scene->mNumMeshes != 0) {
|
if (scene->mNumMeshes != 0) {
|
||||||
scene->mMeshes = new aiMesh *[scene->mNumMeshes]();
|
scene->mMeshes = new aiMesh *[scene->mNumMeshes]();
|
||||||
for (auto it = mResourcesDictionnary.begin(); it != mResourcesDictionnary.end(); it++) {
|
for (auto it = mResourcesDictionnary.begin(); it != mResourcesDictionnary.end(); ++it) {
|
||||||
if (it->second->getType() == ResourceType::RT_Object) {
|
if (it->second->getType() == ResourceType::RT_Object) {
|
||||||
Object *obj = static_cast<Object*>(it->second);
|
Object *obj = static_cast<Object *>(it->second);
|
||||||
|
ai_assert(nullptr != obj);
|
||||||
for (unsigned int i = 0; i < obj->mMeshes.size(); ++i) {
|
for (unsigned int i = 0; i < obj->mMeshes.size(); ++i) {
|
||||||
scene->mMeshes[obj->mMeshIndex[i]] = obj->mMeshes[i];
|
scene->mMeshes[obj->mMeshIndex[i]] = obj->mMeshes[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// import the materials
|
// import the materials
|
||||||
scene->mNumMaterials = static_cast<unsigned int>(mMaterialCount);
|
scene->mNumMaterials = mMaterialCount;
|
||||||
if (scene->mNumMaterials != 0) {
|
if (scene->mNumMaterials != 0) {
|
||||||
scene->mMaterials = new aiMaterial *[scene->mNumMaterials];
|
scene->mMaterials = new aiMaterial *[scene->mNumMaterials];
|
||||||
for (auto it = mResourcesDictionnary.begin(); it != mResourcesDictionnary.end(); it++) {
|
for (auto it = mResourcesDictionnary.begin(); it != mResourcesDictionnary.end(); ++it) {
|
||||||
if (it->second->getType() == ResourceType::RT_BaseMaterials) {
|
if (it->second->getType() == ResourceType::RT_BaseMaterials) {
|
||||||
BaseMaterials *baseMaterials = static_cast<BaseMaterials *>(it->second);
|
BaseMaterials *baseMaterials = static_cast<BaseMaterials *>(it->second);
|
||||||
for (unsigned int i = 0; i < baseMaterials->mMaterials.size(); ++i) {
|
for (unsigned int i = 0; i < baseMaterials->mMaterials.size(); ++i) {
|
||||||
|
@ -228,35 +236,36 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void addObjectToNode(aiNode *parent, Object *obj, aiMatrix4x4 nodeTransform) {
|
||||||
|
ai_assert(nullptr != obj);
|
||||||
|
|
||||||
void addObjectToNode(aiNode* parent, Object* obj, aiMatrix4x4 nodeTransform) {
|
|
||||||
aiNode *sceneNode = new aiNode(obj->mName);
|
aiNode *sceneNode = new aiNode(obj->mName);
|
||||||
sceneNode->mNumMeshes = static_cast<unsigned int>(obj->mMeshes.size());
|
sceneNode->mNumMeshes = static_cast<unsigned int>(obj->mMeshes.size());
|
||||||
sceneNode->mMeshes = new unsigned int[sceneNode->mNumMeshes];
|
sceneNode->mMeshes = new unsigned int[sceneNode->mNumMeshes];
|
||||||
std::copy(obj->mMeshIndex.begin(), obj->mMeshIndex.end(), sceneNode->mMeshes);
|
std::copy(obj->mMeshIndex.begin(), obj->mMeshIndex.end(), sceneNode->mMeshes);
|
||||||
|
|
||||||
sceneNode->mTransformation = nodeTransform;
|
sceneNode->mTransformation = nodeTransform;
|
||||||
|
if (nullptr != parent) {
|
||||||
parent->addChildren(1, &sceneNode);
|
parent->addChildren(1, &sceneNode);
|
||||||
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < obj->mComponents.size(); ++i) {
|
for (size_t i = 0; i < obj->mComponents.size(); ++i) {
|
||||||
Component c = obj->mComponents[i];
|
Component c = obj->mComponents[i];
|
||||||
auto it = mResourcesDictionnary.find(c.mObjectId);
|
auto it = mResourcesDictionnary.find(c.mObjectId);
|
||||||
if (it != mResourcesDictionnary.end() && it->second->getType() == ResourceType::RT_Object) {
|
if (it != mResourcesDictionnary.end() && it->second->getType() == ResourceType::RT_Object) {
|
||||||
addObjectToNode(sceneNode, static_cast<Object*>(it->second), c.mTransformation);
|
addObjectToNode(sceneNode, static_cast<Object *>(it->second), c.mTransformation);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool getNodeAttribute(const XmlNode& node, const std::string& attribute, std::string& value) {
|
bool getNodeAttribute(const XmlNode &node, const std::string &attribute, std::string &value) {
|
||||||
pugi::xml_attribute objectAttribute = node.attribute(attribute.c_str());
|
pugi::xml_attribute objectAttribute = node.attribute(attribute.c_str());
|
||||||
if (!objectAttribute.empty()) {
|
if (!objectAttribute.empty()) {
|
||||||
value = objectAttribute.as_string();
|
value = objectAttribute.as_string();
|
||||||
return true;
|
return true;
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool getNodeAttribute(const XmlNode &node, const std::string &attribute, int &value) {
|
bool getNodeAttribute(const XmlNode &node, const std::string &attribute, int &value) {
|
||||||
|
@ -265,9 +274,9 @@ private:
|
||||||
if (ret) {
|
if (ret) {
|
||||||
value = std::atoi(strValue.c_str());
|
value = std::atoi(strValue.c_str());
|
||||||
return true;
|
return true;
|
||||||
} else {
|
}
|
||||||
return false;
|
|
||||||
}
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
aiMatrix4x4 parseTransformMatrix(std::string matrixStr) {
|
aiMatrix4x4 parseTransformMatrix(std::string matrixStr) {
|
||||||
|
@ -287,7 +296,7 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (currentNumber.size() > 0) {
|
if (currentNumber.size() > 0) {
|
||||||
float f = std::stof(currentNumber);
|
const float f = std::stof(currentNumber);
|
||||||
numbers.push_back(f);
|
numbers.push_back(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,29 +320,26 @@ private:
|
||||||
transformMatrix.b4 = numbers[10];
|
transformMatrix.b4 = numbers[10];
|
||||||
transformMatrix.c4 = numbers[11];
|
transformMatrix.c4 = numbers[11];
|
||||||
transformMatrix.d4 = 1;
|
transformMatrix.d4 = 1;
|
||||||
|
|
||||||
return transformMatrix;
|
return transformMatrix;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReadObject(XmlNode &node) {
|
void ReadObject(XmlNode &node) {
|
||||||
int id = -1, pid = -1, pindex = -1;
|
int id = -1, pid = -1, pindex = -1;
|
||||||
bool hasId = getNodeAttribute(node, D3MF::XmlTag::id, id);
|
bool hasId = getNodeAttribute(node, XmlTag::id, id);
|
||||||
//bool hasType = getNodeAttribute(node, D3MF::XmlTag::type, type); not used currently
|
bool hasPid = getNodeAttribute(node, XmlTag::pid, pid);
|
||||||
bool hasPid = getNodeAttribute(node, D3MF::XmlTag::pid, pid);
|
bool hasPindex = getNodeAttribute(node, XmlTag::pindex, pindex);
|
||||||
bool hasPindex = getNodeAttribute(node, D3MF::XmlTag::pindex, pindex);
|
|
||||||
|
|
||||||
std::string idStr = ai_to_string(id);
|
|
||||||
|
|
||||||
if (!hasId) {
|
if (!hasId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Object *obj = new Object(id);
|
Object *obj = new Object(id);
|
||||||
|
|
||||||
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
|
for (XmlNode ¤tNode : node.children()) {
|
||||||
const std::string ¤tName = currentNode.name();
|
const std::string ¤tName = currentNode.name();
|
||||||
if (currentName == D3MF::XmlTag::mesh) {
|
if (currentName == D3MF::XmlTag::mesh) {
|
||||||
auto mesh = ReadMesh(currentNode);
|
auto mesh = ReadMesh(currentNode);
|
||||||
mesh->mName.Set(idStr);
|
mesh->mName.Set(ai_to_string(id));
|
||||||
|
|
||||||
if (hasPid) {
|
if (hasPid) {
|
||||||
auto it = mResourcesDictionnary.find(pid);
|
auto it = mResourcesDictionnary.find(pid);
|
||||||
|
@ -347,8 +353,9 @@ private:
|
||||||
obj->mMeshIndex.push_back(mMeshCount);
|
obj->mMeshIndex.push_back(mMeshCount);
|
||||||
mMeshCount++;
|
mMeshCount++;
|
||||||
} else if (currentName == D3MF::XmlTag::components) {
|
} else if (currentName == D3MF::XmlTag::components) {
|
||||||
for (XmlNode currentSubNode = currentNode.first_child(); currentSubNode; currentSubNode = currentSubNode.next_sibling()) {
|
for (XmlNode ¤tSubNode : currentNode.children()) {
|
||||||
if (currentSubNode.name() == D3MF::XmlTag::component) {
|
const std::string subNodeName = currentSubNode.name();
|
||||||
|
if (subNodeName == D3MF::XmlTag::component) {
|
||||||
int objectId = -1;
|
int objectId = -1;
|
||||||
std::string componentTransformStr;
|
std::string componentTransformStr;
|
||||||
aiMatrix4x4 componentTransform;
|
aiMatrix4x4 componentTransform;
|
||||||
|
@ -356,8 +363,9 @@ private:
|
||||||
componentTransform = parseTransformMatrix(componentTransformStr);
|
componentTransform = parseTransformMatrix(componentTransformStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getNodeAttribute(currentSubNode, D3MF::XmlTag::objectid, objectId))
|
if (getNodeAttribute(currentSubNode, D3MF::XmlTag::objectid, objectId)) {
|
||||||
obj->mComponents.push_back({ objectId, componentTransform });
|
obj->mComponents.push_back({ objectId, componentTransform });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -369,21 +377,20 @@ private:
|
||||||
aiMesh *ReadMesh(XmlNode &node) {
|
aiMesh *ReadMesh(XmlNode &node) {
|
||||||
aiMesh *mesh = new aiMesh();
|
aiMesh *mesh = new aiMesh();
|
||||||
|
|
||||||
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
|
for (XmlNode ¤tNode : node.children()) {
|
||||||
const std::string ¤tName = currentNode.name();
|
const std::string currentName = currentNode.name();
|
||||||
if (currentName == D3MF::XmlTag::vertices) {
|
if (currentName == XmlTag::vertices) {
|
||||||
ImportVertices(currentNode, mesh);
|
ImportVertices(currentNode, mesh);
|
||||||
} else if (currentName == D3MF::XmlTag::triangles) {
|
} else if (currentName == XmlTag::triangles) {
|
||||||
ImportTriangles(currentNode, mesh);
|
ImportTriangles(currentNode, mesh);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return mesh;
|
return mesh;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReadMetadata(XmlNode &node) {
|
void ReadMetadata(XmlNode &node) {
|
||||||
pugi::xml_attribute attribute = node.attribute(D3MF::XmlTag::meta_name.c_str());
|
pugi::xml_attribute attribute = node.attribute(D3MF::XmlTag::meta_name);
|
||||||
const std::string name = attribute.as_string();
|
const std::string name = attribute.as_string();
|
||||||
const std::string value = node.value();
|
const std::string value = node.value();
|
||||||
if (name.empty()) {
|
if (name.empty()) {
|
||||||
|
@ -398,9 +405,9 @@ private:
|
||||||
|
|
||||||
void ImportVertices(XmlNode &node, aiMesh *mesh) {
|
void ImportVertices(XmlNode &node, aiMesh *mesh) {
|
||||||
std::vector<aiVector3D> vertices;
|
std::vector<aiVector3D> vertices;
|
||||||
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
|
for (XmlNode ¤tNode : node.children()) {
|
||||||
const std::string ¤tName = currentNode.name();
|
const std::string currentName = currentNode.name();
|
||||||
if (currentName == D3MF::XmlTag::vertex) {
|
if (currentName == XmlTag::vertex) {
|
||||||
vertices.push_back(ReadVertex(currentNode));
|
vertices.push_back(ReadVertex(currentNode));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -412,29 +419,28 @@ private:
|
||||||
|
|
||||||
aiVector3D ReadVertex(XmlNode &node) {
|
aiVector3D ReadVertex(XmlNode &node) {
|
||||||
aiVector3D vertex;
|
aiVector3D vertex;
|
||||||
vertex.x = ai_strtof(node.attribute(D3MF::XmlTag::x.c_str()).as_string(), nullptr);
|
vertex.x = ai_strtof(node.attribute(XmlTag::x).as_string(), nullptr);
|
||||||
vertex.y = ai_strtof(node.attribute(D3MF::XmlTag::y.c_str()).as_string(), nullptr);
|
vertex.y = ai_strtof(node.attribute(XmlTag::y).as_string(), nullptr);
|
||||||
vertex.z = ai_strtof(node.attribute(D3MF::XmlTag::z.c_str()).as_string(), nullptr);
|
vertex.z = ai_strtof(node.attribute(XmlTag::z).as_string(), nullptr);
|
||||||
|
|
||||||
return vertex;
|
return vertex;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImportTriangles(XmlNode &node, aiMesh *mesh) {
|
void ImportTriangles(XmlNode &node, aiMesh *mesh) {
|
||||||
std::vector<aiFace> faces;
|
std::vector<aiFace> faces;
|
||||||
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
|
for (XmlNode ¤tNode : node.children()) {
|
||||||
const std::string ¤tName = currentNode.name();
|
const std::string currentName = currentNode.name();
|
||||||
if (currentName == D3MF::XmlTag::triangle) {
|
if (currentName == XmlTag::triangle) {
|
||||||
aiFace face = ReadTriangle(currentNode);
|
aiFace face = ReadTriangle(currentNode);
|
||||||
faces.push_back(face);
|
faces.push_back(face);
|
||||||
|
|
||||||
int pid = 0, p1;
|
int pid = 0, p1 = 0;
|
||||||
bool hasPid = getNodeAttribute(currentNode, D3MF::XmlTag::pid, pid);
|
bool hasPid = getNodeAttribute(currentNode, D3MF::XmlTag::pid, pid);
|
||||||
bool hasP1 = getNodeAttribute(currentNode, D3MF::XmlTag::p1, p1);
|
bool hasP1 = getNodeAttribute(currentNode, D3MF::XmlTag::p1, p1);
|
||||||
|
|
||||||
if (hasPid && hasP1) {
|
if (hasPid && hasP1) {
|
||||||
auto it = mResourcesDictionnary.find(pid);
|
auto it = mResourcesDictionnary.find(pid);
|
||||||
if (it != mResourcesDictionnary.end())
|
if (it != mResourcesDictionnary.end()) {
|
||||||
{
|
|
||||||
if (it->second->getType() == ResourceType::RT_BaseMaterials) {
|
if (it->second->getType() == ResourceType::RT_BaseMaterials) {
|
||||||
BaseMaterials *baseMaterials = static_cast<BaseMaterials *>(it->second);
|
BaseMaterials *baseMaterials = static_cast<BaseMaterials *>(it->second);
|
||||||
mesh->mMaterialIndex = baseMaterials->mMaterialIndex[p1];
|
mesh->mMaterialIndex = baseMaterials->mMaterialIndex[p1];
|
||||||
|
@ -457,9 +463,9 @@ private:
|
||||||
|
|
||||||
face.mNumIndices = 3;
|
face.mNumIndices = 3;
|
||||||
face.mIndices = new unsigned int[face.mNumIndices];
|
face.mIndices = new unsigned int[face.mNumIndices];
|
||||||
face.mIndices[0] = static_cast<unsigned int>(std::atoi(node.attribute(D3MF::XmlTag::v1.c_str()).as_string()));
|
face.mIndices[0] = static_cast<unsigned int>(std::atoi(node.attribute(XmlTag::v1).as_string()));
|
||||||
face.mIndices[1] = static_cast<unsigned int>(std::atoi(node.attribute(D3MF::XmlTag::v2.c_str()).as_string()));
|
face.mIndices[1] = static_cast<unsigned int>(std::atoi(node.attribute(XmlTag::v2).as_string()));
|
||||||
face.mIndices[2] = static_cast<unsigned int>(std::atoi(node.attribute(D3MF::XmlTag::v3.c_str()).as_string()));
|
face.mIndices[2] = static_cast<unsigned int>(std::atoi(node.attribute(XmlTag::v3).as_string()));
|
||||||
|
|
||||||
return face;
|
return face;
|
||||||
}
|
}
|
||||||
|
@ -467,14 +473,14 @@ private:
|
||||||
void ReadBaseMaterials(XmlNode &node) {
|
void ReadBaseMaterials(XmlNode &node) {
|
||||||
int id = -1;
|
int id = -1;
|
||||||
if (getNodeAttribute(node, D3MF::XmlTag::basematerials_id, id)) {
|
if (getNodeAttribute(node, D3MF::XmlTag::basematerials_id, id)) {
|
||||||
BaseMaterials* baseMaterials = new BaseMaterials(id);
|
BaseMaterials *baseMaterials = new BaseMaterials(id);
|
||||||
|
|
||||||
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling())
|
for (XmlNode ¤tNode : node.children()) {
|
||||||
{
|
const std::string currentName = currentNode.name();
|
||||||
if (currentNode.name() == D3MF::XmlTag::basematerials_base) {
|
if (currentName == XmlTag::basematerials_base) {
|
||||||
baseMaterials->mMaterialIndex.push_back(mMaterialCount);
|
baseMaterials->mMaterialIndex.push_back(mMaterialCount);
|
||||||
baseMaterials->mMaterials.push_back(readMaterialDef(currentNode, id));
|
baseMaterials->mMaterials.push_back(readMaterialDef(currentNode, id));
|
||||||
mMaterialCount++;
|
++mMaterialCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -488,7 +494,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
//format of the color string: #RRGGBBAA or #RRGGBB (3MF Core chapter 5.1.1)
|
//format of the color string: #RRGGBBAA or #RRGGBB (3MF Core chapter 5.1.1)
|
||||||
const size_t len(strlen(color));
|
const size_t len = strlen(color);
|
||||||
if (9 != len && 7 != len) {
|
if (9 != len && 7 != len) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -517,7 +523,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void assignDiffuseColor(XmlNode &node, aiMaterial *mat) {
|
void assignDiffuseColor(XmlNode &node, aiMaterial *mat) {
|
||||||
const char *color = node.attribute(D3MF::XmlTag::basematerials_displaycolor.c_str()).as_string();
|
const char *color = node.attribute(XmlTag::basematerials_displaycolor).as_string();
|
||||||
aiColor4D diffuse;
|
aiColor4D diffuse;
|
||||||
if (parseColor(color, diffuse)) {
|
if (parseColor(color, diffuse)) {
|
||||||
mat->AddProperty<aiColor4D>(&diffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
|
mat->AddProperty<aiColor4D>(&diffuse, 1, AI_MATKEY_COLOR_DIFFUSE);
|
||||||
|
@ -531,7 +537,7 @@ private:
|
||||||
bool hasName = getNodeAttribute(node, D3MF::XmlTag::basematerials_name, name);
|
bool hasName = getNodeAttribute(node, D3MF::XmlTag::basematerials_name, name);
|
||||||
|
|
||||||
std::string stdMaterialName;
|
std::string stdMaterialName;
|
||||||
std::string strId(ai_to_string(basematerialsId));
|
const std::string strId(ai_to_string(basematerialsId));
|
||||||
stdMaterialName += "id";
|
stdMaterialName += "id";
|
||||||
stdMaterialName += strId;
|
stdMaterialName += strId;
|
||||||
stdMaterialName += "_";
|
stdMaterialName += "_";
|
||||||
|
@ -556,13 +562,15 @@ private:
|
||||||
std::string value;
|
std::string value;
|
||||||
};
|
};
|
||||||
std::vector<MetaEntry> mMetaData;
|
std::vector<MetaEntry> mMetaData;
|
||||||
std::map<unsigned int, Resource*> mResourcesDictionnary;
|
std::map<unsigned int, Resource *> mResourcesDictionnary;
|
||||||
unsigned int mMaterialCount, mMeshCount;
|
unsigned int mMaterialCount, mMeshCount;
|
||||||
XmlParser *mXmlParser;
|
XmlParser *mXmlParser;
|
||||||
};
|
};
|
||||||
|
|
||||||
} //namespace D3MF
|
} //namespace D3MF
|
||||||
|
|
||||||
|
using namespace D3MF;
|
||||||
|
|
||||||
static const aiImporterDesc desc = {
|
static const aiImporterDesc desc = {
|
||||||
"3mf Importer",
|
"3mf Importer",
|
||||||
"",
|
"",
|
||||||
|
@ -596,7 +604,7 @@ bool D3MFImporter::CanRead(const std::string &filename, IOSystem *pIOHandler, bo
|
||||||
if (!ZipArchiveIOSystem::isZipArchive(pIOHandler, filename)) {
|
if (!ZipArchiveIOSystem::isZipArchive(pIOHandler, filename)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
D3MF::D3MFOpcPackage opcPackage(pIOHandler, filename);
|
D3MFOpcPackage opcPackage(pIOHandler, filename);
|
||||||
return opcPackage.validate();
|
return opcPackage.validate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -612,11 +620,11 @@ const aiImporterDesc *D3MFImporter::GetInfo() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void D3MFImporter::InternReadFile(const std::string &filename, aiScene *pScene, IOSystem *pIOHandler) {
|
void D3MFImporter::InternReadFile(const std::string &filename, aiScene *pScene, IOSystem *pIOHandler) {
|
||||||
D3MF::D3MFOpcPackage opcPackage(pIOHandler, filename);
|
D3MFOpcPackage opcPackage(pIOHandler, filename);
|
||||||
|
|
||||||
XmlParser xmlParser;
|
XmlParser xmlParser;
|
||||||
if (xmlParser.parse(opcPackage.RootStream())) {
|
if (xmlParser.parse(opcPackage.RootStream())) {
|
||||||
D3MF::XmlSerializer xmlSerializer(&xmlParser);
|
XmlSerializer xmlSerializer(&xmlParser);
|
||||||
xmlSerializer.ImportXml(pScene);
|
xmlSerializer.ImportXml(pScene);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,9 +47,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
|
/// @brief The 3MF-importer class.
|
||||||
class D3MFImporter : public BaseImporter {
|
class D3MFImporter : public BaseImporter {
|
||||||
public:
|
public:
|
||||||
// BaseImporter interface
|
|
||||||
D3MFImporter();
|
D3MFImporter();
|
||||||
~D3MFImporter();
|
~D3MFImporter();
|
||||||
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const;
|
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const;
|
||||||
|
|
|
@ -103,9 +103,9 @@ public:
|
||||||
std::string name = currentNode.name();
|
std::string name = currentNode.name();
|
||||||
if (name == "Relationship") {
|
if (name == "Relationship") {
|
||||||
OpcPackageRelationshipPtr relPtr(new OpcPackageRelationship());
|
OpcPackageRelationshipPtr relPtr(new OpcPackageRelationship());
|
||||||
relPtr->id = currentNode.attribute(XmlTag::RELS_ATTRIB_ID.c_str()).as_string();
|
relPtr->id = currentNode.attribute(XmlTag::RELS_ATTRIB_ID).as_string();
|
||||||
relPtr->type = currentNode.attribute(XmlTag::RELS_ATTRIB_TYPE.c_str()).as_string();
|
relPtr->type = currentNode.attribute(XmlTag::RELS_ATTRIB_TYPE).as_string();
|
||||||
relPtr->target = currentNode.attribute(XmlTag::RELS_ATTRIB_TARGET.c_str()).as_string();
|
relPtr->target = currentNode.attribute(XmlTag::RELS_ATTRIB_TARGET).as_string();
|
||||||
if (validateRels(relPtr)) {
|
if (validateRels(relPtr)) {
|
||||||
m_relationShips.push_back(relPtr);
|
m_relationShips.push_back(relPtr);
|
||||||
}
|
}
|
||||||
|
@ -188,7 +188,7 @@ bool D3MFOpcPackage::validate() {
|
||||||
std::string D3MFOpcPackage::ReadPackageRootRelationship(IOStream *stream) {
|
std::string D3MFOpcPackage::ReadPackageRootRelationship(IOStream *stream) {
|
||||||
XmlParser xmlParser;
|
XmlParser xmlParser;
|
||||||
if (!xmlParser.parse(stream)) {
|
if (!xmlParser.parse(stream)) {
|
||||||
return "";
|
return std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
OpcPackageRelationshipReader reader(xmlParser);
|
OpcPackageRelationshipReader reader(xmlParser);
|
||||||
|
|
|
@ -123,9 +123,9 @@ public:
|
||||||
struct Object {
|
struct Object {
|
||||||
Object() :
|
Object() :
|
||||||
type(World),
|
type(World),
|
||||||
name(""),
|
name(),
|
||||||
children(),
|
children(),
|
||||||
texture(""),
|
texture(),
|
||||||
texRepeat(1.f, 1.f),
|
texRepeat(1.f, 1.f),
|
||||||
texOffset(0.0f, 0.0f),
|
texOffset(0.0f, 0.0f),
|
||||||
rotation(),
|
rotation(),
|
||||||
|
|
|
@ -205,7 +205,7 @@ void AMFImporter::ParseHelper_FixTruncatedFloatString(const char *pInStr, std::s
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ParseHelper_Decode_Base64_IsBase64(const char pChar) {
|
static bool ParseHelper_Decode_Base64_IsBase64(const char pChar) {
|
||||||
return (isalnum(pChar) || (pChar == '+') || (pChar == '/'));
|
return (isalnum((unsigned char)pChar) || (pChar == '+') || (pChar == '/'));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AMFImporter::ParseHelper_Decode_Base64(const std::string &pInputBase64, std::vector<uint8_t> &pOutputData) const {
|
void AMFImporter::ParseHelper_Decode_Base64(const std::string &pInputBase64, std::vector<uint8_t> &pOutputData) const {
|
||||||
|
@ -268,7 +268,8 @@ void AMFImporter::ParseFile(const std::string &pFile, IOSystem *pIOHandler) {
|
||||||
mXmlParser = new XmlParser();
|
mXmlParser = new XmlParser();
|
||||||
if (!mXmlParser->parse(file.get())) {
|
if (!mXmlParser->parse(file.get())) {
|
||||||
delete mXmlParser;
|
delete mXmlParser;
|
||||||
throw DeadlyImportError("Failed to create XML reader for file" + pFile + ".");
|
mXmlParser = nullptr;
|
||||||
|
throw DeadlyImportError("Failed to create XML reader for file ", pFile, ".");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start reading, search for root tag <amf>
|
// Start reading, search for root tag <amf>
|
||||||
|
@ -517,10 +518,6 @@ bool AMFImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool p
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AMFImporter::GetExtensionList(std::set<std::string> &pExtensionList) {
|
|
||||||
pExtensionList.insert("amf");
|
|
||||||
}
|
|
||||||
|
|
||||||
const aiImporterDesc *AMFImporter::GetInfo() const {
|
const aiImporterDesc *AMFImporter::GetInfo() const {
|
||||||
return &Description;
|
return &Description;
|
||||||
}
|
}
|
||||||
|
|
|
@ -277,7 +277,6 @@ public:
|
||||||
void ParseHelper_Node_Enter(AMFNodeElementBase *child);
|
void ParseHelper_Node_Enter(AMFNodeElementBase *child);
|
||||||
void ParseHelper_Node_Exit();
|
void ParseHelper_Node_Exit();
|
||||||
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool pCheckSig) const;
|
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool pCheckSig) const;
|
||||||
void GetExtensionList(std::set<std::string> &pExtensionList);
|
|
||||||
void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler);
|
void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler);
|
||||||
const aiImporterDesc *GetInfo() const;
|
const aiImporterDesc *GetInfo() const;
|
||||||
bool Find_NodeElement(const std::string &pID, const AMFNodeElementBase::EType pType, AMFNodeElementBase **pNodeElement) const;
|
bool Find_NodeElement(const std::string &pID, const AMFNodeElementBase::EType pType, AMFNodeElementBase **pNodeElement) const;
|
||||||
|
|
|
@ -428,10 +428,10 @@ void AMFImporter::Postprocess_BuildMeshSet(const AMFMesh &pNodeElement, const st
|
||||||
|
|
||||||
if (pBiggerThan != nullptr) {
|
if (pBiggerThan != nullptr) {
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
const size_t biggerThan = *pBiggerThan;
|
||||||
for (const SComplexFace &face : pFaceList) {
|
for (const SComplexFace &face : pFaceList) {
|
||||||
for (size_t idx_vert = 0; idx_vert < face.Face.mNumIndices; idx_vert++) {
|
for (size_t idx_vert = 0; idx_vert < face.Face.mNumIndices; idx_vert++) {
|
||||||
if (face.Face.mIndices[idx_vert] > *pBiggerThan) {
|
if (face.Face.mIndices[idx_vert] > biggerThan) {
|
||||||
rv = face.Face.mIndices[idx_vert];
|
rv = face.Face.mIndices[idx_vert];
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -498,6 +498,12 @@ void Parser::ParseLV1MaterialListBlock() {
|
||||||
ParseLV2MaterialBlock(sMat);
|
ParseLV2MaterialBlock(sMat);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if( iDepth == 1 ){
|
||||||
|
// CRUDE HACK: support missing brace after "Ascii Scene Exporter v2.51"
|
||||||
|
LogWarning("Missing closing brace in material list");
|
||||||
|
--filePtr;
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
AI_ASE_HANDLE_TOP_LEVEL_SECTION();
|
AI_ASE_HANDLE_TOP_LEVEL_SECTION();
|
||||||
}
|
}
|
||||||
|
@ -685,7 +691,7 @@ void Parser::ParseLV3MapBlock(Texture &map) {
|
||||||
// Files with 'None' as map name are produced by
|
// Files with 'None' as map name are produced by
|
||||||
// an Maja to ASE exporter which name I forgot ..
|
// an Maja to ASE exporter which name I forgot ..
|
||||||
ASSIMP_LOG_WARN("ASE: Skipping invalid map entry");
|
ASSIMP_LOG_WARN("ASE: Skipping invalid map entry");
|
||||||
map.mMapName = "";
|
map.mMapName = std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -671,7 +671,7 @@ void AssbinImporter::ReadBinaryScene(IOStream *stream, aiScene *scene) {
|
||||||
void AssbinImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) {
|
void AssbinImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) {
|
||||||
IOStream *stream = pIOHandler->Open(pFile, "rb");
|
IOStream *stream = pIOHandler->Open(pFile, "rb");
|
||||||
if (nullptr == stream) {
|
if (nullptr == stream) {
|
||||||
return;
|
throw DeadlyImportError("ASSBIN: Could not open ", pFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
// signature
|
// signature
|
||||||
|
|
|
@ -359,7 +359,7 @@ void BVHLoader::ReadMotion(aiScene * /*pScene*/) {
|
||||||
std::string BVHLoader::GetNextToken() {
|
std::string BVHLoader::GetNextToken() {
|
||||||
// skip any preceding whitespace
|
// skip any preceding whitespace
|
||||||
while (mReader != mBuffer.end()) {
|
while (mReader != mBuffer.end()) {
|
||||||
if (!isspace(*mReader))
|
if (!isspace((unsigned char)*mReader))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// count lines
|
// count lines
|
||||||
|
@ -372,7 +372,7 @@ std::string BVHLoader::GetNextToken() {
|
||||||
// collect all chars till the next whitespace. BVH is easy in respect to that.
|
// collect all chars till the next whitespace. BVH is easy in respect to that.
|
||||||
std::string token;
|
std::string token;
|
||||||
while (mReader != mBuffer.end()) {
|
while (mReader != mBuffer.end()) {
|
||||||
if (isspace(*mReader))
|
if (isspace((unsigned char)*mReader))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
token.push_back(*mReader);
|
token.push_back(*mReader);
|
||||||
|
|
|
@ -132,12 +132,6 @@ bool BlenderImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bo
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
// List all extensions handled by this loader
|
|
||||||
void BlenderImporter::GetExtensionList(std::set<std::string> &app) {
|
|
||||||
app.insert("blend");
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Loader registry entry
|
// Loader registry entry
|
||||||
const aiImporterDesc *BlenderImporter::GetInfo() const {
|
const aiImporterDesc *BlenderImporter::GetInfo() const {
|
||||||
|
@ -426,9 +420,9 @@ void BlenderImporter::ResolveImage(aiMaterial *out, const Material *mat, const M
|
||||||
--s;
|
--s;
|
||||||
}
|
}
|
||||||
|
|
||||||
curTex->achFormatHint[0] = s + 1 > e ? '\0' : (char)::tolower(s[1]);
|
curTex->achFormatHint[0] = s + 1 > e ? '\0' : (char)::tolower((unsigned char)s[1]);
|
||||||
curTex->achFormatHint[1] = s + 2 > e ? '\0' : (char)::tolower(s[2]);
|
curTex->achFormatHint[1] = s + 2 > e ? '\0' : (char)::tolower((unsigned char)s[2]);
|
||||||
curTex->achFormatHint[2] = s + 3 > e ? '\0' : (char)::tolower(s[3]);
|
curTex->achFormatHint[2] = s + 3 > e ? '\0' : (char)::tolower((unsigned char)s[3]);
|
||||||
curTex->achFormatHint[3] = '\0';
|
curTex->achFormatHint[3] = '\0';
|
||||||
|
|
||||||
// tex->mHeight = 0;
|
// tex->mHeight = 0;
|
||||||
|
|
|
@ -110,7 +110,6 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const aiImporterDesc* GetInfo () const;
|
const aiImporterDesc* GetInfo () const;
|
||||||
void GetExtensionList(std::set<std::string>& app);
|
|
||||||
void SetupProperties(const Importer* pImp);
|
void SetupProperties(const Importer* pImp);
|
||||||
void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
|
void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
|
||||||
void ParseBlendFile(Blender::FileDatabase& out, std::shared_ptr<IOStream> stream);
|
void ParseBlendFile(Blender::FileDatabase& out, std::shared_ptr<IOStream> stream);
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2020, assimp team
|
Copyright (c) 2006-2021, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -51,7 +51,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "C4DImporter.h"
|
#include "C4DImporter.h"
|
||||||
#include <assimp/TinyFormatter.h>
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <assimp/IOSystem.hpp>
|
#include <assimp/IOSystem.hpp>
|
||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
|
@ -65,7 +64,19 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "c4d_file.h"
|
#include "c4d_file.h"
|
||||||
#include "default_alien_overloads.h"
|
#include "default_alien_overloads.h"
|
||||||
|
|
||||||
using namespace melange;
|
namespace {
|
||||||
|
|
||||||
|
aiString aiStringFrom(cineware::String const & cinestring) {
|
||||||
|
aiString result;
|
||||||
|
cinestring.GetCString(result.data, MAXLEN-1);
|
||||||
|
result.length = static_cast<ai_uint32>(cinestring.GetLength());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
using namespace Assimp;
|
||||||
|
using namespace cineware;
|
||||||
|
|
||||||
// overload this function and fill in your own unique data
|
// overload this function and fill in your own unique data
|
||||||
void GetWriterInfo(int &id, String &appname) {
|
void GetWriterInfo(int &id, String &appname) {
|
||||||
|
@ -73,9 +84,6 @@ void GetWriterInfo(int &id, String &appname) {
|
||||||
appname = "Open Asset Import Library";
|
appname = "Open Asset Import Library";
|
||||||
}
|
}
|
||||||
|
|
||||||
using namespace Assimp;
|
|
||||||
using namespace Assimp::Formatter;
|
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
template<> const char* LogFunctions<C4DImporter>::Prefix() {
|
template<> const char* LogFunctions<C4DImporter>::Prefix() {
|
||||||
static auto prefix = "C4D: ";
|
static auto prefix = "C4D: ";
|
||||||
|
@ -97,17 +105,6 @@ static const aiImporterDesc desc = {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
C4DImporter::C4DImporter()
|
|
||||||
: BaseImporter() {
|
|
||||||
// empty
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
C4DImporter::~C4DImporter() {
|
|
||||||
// empty
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
bool C4DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const {
|
bool C4DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const {
|
||||||
const std::string& extension = GetExtension(pFile);
|
const std::string& extension = GetExtension(pFile);
|
||||||
|
@ -125,11 +122,6 @@ const aiImporterDesc* C4DImporter::GetInfo () const {
|
||||||
return &desc;
|
return &desc;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
|
||||||
void C4DImporter::SetupProperties(const Importer* /*pImp*/) {
|
|
||||||
// nothing to be done for the moment
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Imports the given file into the given scene structure.
|
// Imports the given file into the given scene structure.
|
||||||
|
@ -199,8 +191,8 @@ void C4DImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
bool C4DImporter::ReadShader(aiMaterial* out, melange::BaseShader* shader) {
|
bool C4DImporter::ReadShader(aiMaterial* out, BaseShader* shader) {
|
||||||
// based on Melange sample code (C4DImportExport.cpp)
|
// based on Cineware sample code (C4DImportExport.cpp)
|
||||||
while(shader) {
|
while(shader) {
|
||||||
if(shader->GetType() == Xlayer) {
|
if(shader->GetType() == Xlayer) {
|
||||||
BaseContainer* container = shader->GetDataInstance();
|
BaseContainer* container = shader->GetDataInstance();
|
||||||
|
@ -242,9 +234,7 @@ bool C4DImporter::ReadShader(aiMaterial* out, melange::BaseShader* shader) {
|
||||||
lsl = lsl->GetNext();
|
lsl = lsl->GetNext();
|
||||||
}
|
}
|
||||||
} else if ( shader->GetType() == Xbitmap ) {
|
} else if ( shader->GetType() == Xbitmap ) {
|
||||||
aiString path;
|
auto const path = aiStringFrom(shader->GetFileName().GetString());
|
||||||
shader->GetFileName().GetString().GetCString(path.data, MAXLEN-1);
|
|
||||||
path.length = ::strlen(path.data);
|
|
||||||
out->AddProperty(&path, AI_MATKEY_TEXTURE_DIFFUSE(0));
|
out->AddProperty(&path, AI_MATKEY_TEXTURE_DIFFUSE(0));
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
@ -257,18 +247,15 @@ bool C4DImporter::ReadShader(aiMaterial* out, melange::BaseShader* shader) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void C4DImporter::ReadMaterials(melange::BaseMaterial* mat) {
|
void C4DImporter::ReadMaterials(BaseMaterial* mat) {
|
||||||
// based on Melange sample code
|
// based on Cineware sample code
|
||||||
while (mat) {
|
while (mat) {
|
||||||
const String& name = mat->GetName();
|
|
||||||
if (mat->GetType() == Mmaterial) {
|
if (mat->GetType() == Mmaterial) {
|
||||||
aiMaterial* out = new aiMaterial();
|
aiMaterial* out = new aiMaterial();
|
||||||
material_mapping[mat] = static_cast<unsigned int>(materials.size());
|
material_mapping[mat] = static_cast<unsigned int>(materials.size());
|
||||||
materials.push_back(out);
|
materials.push_back(out);
|
||||||
|
|
||||||
aiString ai_name;
|
auto const ai_name = aiStringFrom(mat->GetName());
|
||||||
name.GetCString(ai_name.data, MAXLEN-1);
|
|
||||||
ai_name.length = ::strlen(ai_name.data);
|
|
||||||
out->AddProperty(&ai_name, AI_MATKEY_NAME);
|
out->AddProperty(&ai_name, AI_MATKEY_NAME);
|
||||||
|
|
||||||
Material& m = dynamic_cast<Material&>(*mat);
|
Material& m = dynamic_cast<Material&>(*mat);
|
||||||
|
@ -305,19 +292,15 @@ void C4DImporter::RecurseHierarchy(BaseObject* object, aiNode* parent) {
|
||||||
ai_assert(parent != nullptr );
|
ai_assert(parent != nullptr );
|
||||||
std::vector<aiNode*> nodes;
|
std::vector<aiNode*> nodes;
|
||||||
|
|
||||||
// based on Melange sample code
|
// based on Cineware sample code
|
||||||
while (object) {
|
while (object) {
|
||||||
const String& name = object->GetName();
|
|
||||||
const LONG type = object->GetType();
|
const LONG type = object->GetType();
|
||||||
const Matrix& ml = object->GetMl();
|
const Matrix& ml = object->GetMl();
|
||||||
|
|
||||||
aiString string;
|
|
||||||
name.GetCString(string.data, MAXLEN-1);
|
|
||||||
string.length = ::strlen(string.data);
|
|
||||||
aiNode* const nd = new aiNode();
|
aiNode* const nd = new aiNode();
|
||||||
|
|
||||||
nd->mParent = parent;
|
nd->mParent = parent;
|
||||||
nd->mName = string;
|
nd->mName = aiStringFrom(object->GetName());
|
||||||
|
|
||||||
nd->mTransformation.a1 = ml.v1.x;
|
nd->mTransformation.a1 = ml.v1.x;
|
||||||
nd->mTransformation.b1 = ml.v1.y;
|
nd->mTransformation.b1 = ml.v1.y;
|
||||||
|
@ -370,7 +353,7 @@ aiMesh* C4DImporter::ReadMesh(BaseObject* object) {
|
||||||
ai_assert(object != nullptr);
|
ai_assert(object != nullptr);
|
||||||
ai_assert( object->GetType() == Opolygon );
|
ai_assert( object->GetType() == Opolygon );
|
||||||
|
|
||||||
// based on Melange sample code
|
// based on Cineware sample code
|
||||||
PolygonObject* const polyObject = dynamic_cast<PolygonObject*>(object);
|
PolygonObject* const polyObject = dynamic_cast<PolygonObject*>(object);
|
||||||
ai_assert(polyObject != nullptr);
|
ai_assert(polyObject != nullptr);
|
||||||
|
|
||||||
|
@ -618,4 +601,3 @@ unsigned int C4DImporter::ResolveMaterial(PolygonObject* obj) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // ASSIMP_BUILD_NO_C4D_IMPORTER
|
#endif // ASSIMP_BUILD_NO_C4D_IMPORTER
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Open Asset Import Library (assimp)
|
Open Asset Import Library (assimp)
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright (c) 2006-2020, assimp team
|
Copyright (c) 2006-2021, assimp team
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -56,8 +56,8 @@ struct aiMaterial;
|
||||||
|
|
||||||
struct aiImporterDesc;
|
struct aiImporterDesc;
|
||||||
|
|
||||||
namespace melange {
|
namespace cineware {
|
||||||
class BaseObject; // c4d_file.h
|
class BaseObject;
|
||||||
class PolygonObject;
|
class PolygonObject;
|
||||||
class BaseMaterial;
|
class BaseMaterial;
|
||||||
class BaseShader;
|
class BaseShader;
|
||||||
|
@ -71,43 +71,34 @@ namespace Assimp {
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------
|
||||||
/** Importer class to load Cinema4D files using the Melange library to be obtained from
|
/** Importer class to load Cinema4D files using the Cineware library to be obtained from
|
||||||
* www.plugincafe.com
|
* https://developers.maxon.net
|
||||||
*
|
*
|
||||||
* Note that Melange is not free software. */
|
* Note that Cineware is not free software. */
|
||||||
// -------------------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------------------
|
||||||
class C4DImporter : public BaseImporter, public LogFunctions<C4DImporter> {
|
class C4DImporter : public BaseImporter, public LogFunctions<C4DImporter> {
|
||||||
public:
|
public:
|
||||||
C4DImporter();
|
bool CanRead( const std::string& pFile, IOSystem*, bool checkSig) const override;
|
||||||
~C4DImporter();
|
|
||||||
bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
|
|
||||||
bool checkSig) const;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// --------------------
|
const aiImporterDesc* GetInfo () const override;
|
||||||
const aiImporterDesc* GetInfo () const;
|
|
||||||
|
|
||||||
// --------------------
|
void InternReadFile( const std::string& pFile, aiScene*, IOSystem* ) override;
|
||||||
void SetupProperties(const Importer* pImp);
|
|
||||||
|
|
||||||
// --------------------
|
|
||||||
void InternReadFile( const std::string& pFile, aiScene* pScene,
|
|
||||||
IOSystem* pIOHandler);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void ReadMaterials(melange::BaseMaterial* mat);
|
void ReadMaterials(cineware::BaseMaterial* mat);
|
||||||
void RecurseHierarchy(melange::BaseObject* object, aiNode* parent);
|
void RecurseHierarchy(cineware::BaseObject* object, aiNode* parent);
|
||||||
aiMesh* ReadMesh(melange::BaseObject* object);
|
aiMesh* ReadMesh(cineware::BaseObject* object);
|
||||||
unsigned int ResolveMaterial(melange::PolygonObject* obj);
|
unsigned int ResolveMaterial(cineware::PolygonObject* obj);
|
||||||
|
|
||||||
bool ReadShader(aiMaterial* out, melange::BaseShader* shader);
|
bool ReadShader(aiMaterial* out, cineware::BaseShader* shader);
|
||||||
|
|
||||||
std::vector<aiMesh*> meshes;
|
std::vector<aiMesh*> meshes;
|
||||||
std::vector<aiMaterial*> materials;
|
std::vector<aiMaterial*> materials;
|
||||||
|
|
||||||
typedef std::map<melange::BaseMaterial*, unsigned int> MaterialMap;
|
typedef std::map<cineware::BaseMaterial*, unsigned int> MaterialMap;
|
||||||
MaterialMap material_mapping;
|
MaterialMap material_mapping;
|
||||||
|
|
||||||
}; // !class C4DImporter
|
}; // !class C4DImporter
|
||||||
|
|
|
@ -137,7 +137,13 @@ void COBImporter::SetupProperties(const Importer * /*pImp*/) {
|
||||||
// Imports the given file into the given scene structure.
|
// Imports the given file into the given scene structure.
|
||||||
void COBImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) {
|
void COBImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) {
|
||||||
COB::Scene scene;
|
COB::Scene scene;
|
||||||
std::unique_ptr<StreamReaderLE> stream(new StreamReaderLE(pIOHandler->Open(pFile, "rb")));
|
|
||||||
|
auto file = pIOHandler->Open(pFile, "rb");
|
||||||
|
if (!file) {
|
||||||
|
ThrowException("Could not open " + pFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<StreamReaderLE> stream(new StreamReaderLE(file));
|
||||||
|
|
||||||
// check header
|
// check header
|
||||||
char head[32];
|
char head[32];
|
||||||
|
|
|
@ -75,7 +75,7 @@ static const aiImporterDesc desc = {
|
||||||
3,
|
3,
|
||||||
1,
|
1,
|
||||||
5,
|
5,
|
||||||
"dae zae"
|
"dae xml zae"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const float kMillisecondsFromSeconds = 1000.f;
|
static const float kMillisecondsFromSeconds = 1000.f;
|
||||||
|
@ -1241,7 +1241,7 @@ void ColladaLoader::CreateAnimation(aiScene *pScene, const ColladaParser &pParse
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
entry.mTargetId = entry.mTransformId;
|
entry.mTargetId = entry.mTransformId;
|
||||||
entry.mTransformId = "";
|
entry.mTransformId = std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
entry.mChannel = &(*cit);
|
entry.mChannel = &(*cit);
|
||||||
|
|
|
@ -234,7 +234,7 @@ void ColladaParser::UriDecodePath(aiString &ss) {
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
if (ss.data[0] == '/' && isalpha((unsigned char)ss.data[1]) && ss.data[2] == ':') {
|
if (ss.data[0] == '/' && isalpha((unsigned char)ss.data[1]) && ss.data[2] == ':') {
|
||||||
#else
|
#else
|
||||||
if (ss.data[0] == '/' && isalpha(ss.data[1]) && ss.data[2] == ':') {
|
if (ss.data[0] == '/' && isalpha((unsigned char)ss.data[1]) && ss.data[2] == ':') {
|
||||||
#endif
|
#endif
|
||||||
--ss.length;
|
--ss.length;
|
||||||
::memmove(ss.data, ss.data + 1, ss.length);
|
::memmove(ss.data, ss.data + 1, ss.length);
|
||||||
|
|
|
@ -1789,13 +1789,13 @@ void FBXExporter::WriteObjects ()
|
||||||
blendchannel_uid, blendshape_name + FBX::SEPARATOR + "SubDeformer", "BlendShapeChannel"
|
blendchannel_uid, blendshape_name + FBX::SEPARATOR + "SubDeformer", "BlendShapeChannel"
|
||||||
);
|
);
|
||||||
sdnode.AddChild("Version", int32_t(100));
|
sdnode.AddChild("Version", int32_t(100));
|
||||||
sdnode.AddChild("DeformPercent", int32_t(100));
|
sdnode.AddChild("DeformPercent", float_t(0.0));
|
||||||
FBX::Node p("Properties70");
|
FBX::Node p("Properties70");
|
||||||
p.AddP70numberA("DeformPercent", 100.);
|
p.AddP70numberA("DeformPercent", 0.0);
|
||||||
sdnode.AddChild(p);
|
sdnode.AddChild(p);
|
||||||
// TODO: Normally just one weight per channel, adding stub for later development
|
// TODO: Normally just one weight per channel, adding stub for later development
|
||||||
std::vector<float>fFullWeights;
|
std::vector<float>fFullWeights;
|
||||||
fFullWeights.push_back(0.);
|
fFullWeights.push_back(100.);
|
||||||
sdnode.AddChild("FullWeights", fFullWeights);
|
sdnode.AddChild("FullWeights", fFullWeights);
|
||||||
sdnode.Dump(outstream, binary, indent);
|
sdnode.Dump(outstream, binary, indent);
|
||||||
|
|
||||||
|
|
|
@ -82,7 +82,7 @@ Material::Material(uint64_t id, const Element& element, const Document& doc, con
|
||||||
|
|
||||||
// lower-case shading because Blender (for example) writes "Phong"
|
// lower-case shading because Blender (for example) writes "Phong"
|
||||||
for (size_t i = 0; i < shading.length(); ++i) {
|
for (size_t i = 0; i < shading.length(); ++i) {
|
||||||
shading[i] = static_cast<char>(tolower(shading[i]));
|
shading[i] = static_cast<char>(tolower(static_cast<unsigned char>(shading[i])));
|
||||||
}
|
}
|
||||||
std::string templateName;
|
std::string templateName;
|
||||||
if(shading == "phong") {
|
if(shading == "phong") {
|
||||||
|
|
|
@ -330,7 +330,7 @@ void MeshGeometry::ReadVertexData(const std::string& type, int index, const Scop
|
||||||
}
|
}
|
||||||
|
|
||||||
const Element* Name = source["Name"];
|
const Element* Name = source["Name"];
|
||||||
m_uvNames[index] = "";
|
m_uvNames[index] = std::string();
|
||||||
if(Name) {
|
if(Name) {
|
||||||
m_uvNames[index] = ParseTokenAsString(GetRequiredToken(*Name,0));
|
m_uvNames[index] = ParseTokenAsString(GetRequiredToken(*Name,0));
|
||||||
}
|
}
|
||||||
|
|
|
@ -462,7 +462,7 @@ std::string ParseTokenAsString(const Token& t, const char*& err_out)
|
||||||
|
|
||||||
if (t.Type() != TokenType_DATA) {
|
if (t.Type() != TokenType_DATA) {
|
||||||
err_out = "expected TOK_DATA token";
|
err_out = "expected TOK_DATA token";
|
||||||
return "";
|
return std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(t.IsBinary())
|
if(t.IsBinary())
|
||||||
|
@ -470,7 +470,7 @@ std::string ParseTokenAsString(const Token& t, const char*& err_out)
|
||||||
const char* data = t.begin();
|
const char* data = t.begin();
|
||||||
if (data[0] != 'S') {
|
if (data[0] != 'S') {
|
||||||
err_out = "failed to parse S(tring), unexpected data type (binary)";
|
err_out = "failed to parse S(tring), unexpected data type (binary)";
|
||||||
return "";
|
return std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
// read string length
|
// read string length
|
||||||
|
@ -484,13 +484,13 @@ std::string ParseTokenAsString(const Token& t, const char*& err_out)
|
||||||
const size_t length = static_cast<size_t>(t.end() - t.begin());
|
const size_t length = static_cast<size_t>(t.end() - t.begin());
|
||||||
if(length < 2) {
|
if(length < 2) {
|
||||||
err_out = "token is too short to hold a string";
|
err_out = "token is too short to hold a string";
|
||||||
return "";
|
return std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* s = t.begin(), *e = t.end() - 1;
|
const char* s = t.begin(), *e = t.end() - 1;
|
||||||
if (*s != '\"' || *e != '\"') {
|
if (*s != '\"' || *e != '\"') {
|
||||||
err_out = "expected double quoted string";
|
err_out = "expected double quoted string";
|
||||||
return "";
|
return std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
return std::string(s+1,length-2);
|
return std::string(s+1,length-2);
|
||||||
|
|
|
@ -155,7 +155,7 @@ std::string PeekPropertyName(const Element& element)
|
||||||
ai_assert(element.KeyToken().StringContents() == "P");
|
ai_assert(element.KeyToken().StringContents() == "P");
|
||||||
const TokenList& tok = element.Tokens();
|
const TokenList& tok = element.Tokens();
|
||||||
if(tok.size() < 4) {
|
if(tok.size() < 4) {
|
||||||
return "";
|
return std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ParseTokenAsString(*tok[0]);
|
return ParseTokenAsString(*tok[0]);
|
||||||
|
|
|
@ -47,6 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "AssetLib/HMP/HMPLoader.h"
|
#include "AssetLib/HMP/HMPLoader.h"
|
||||||
#include "AssetLib/MD2/MD2FileData.h"
|
#include "AssetLib/MD2/MD2FileData.h"
|
||||||
|
|
||||||
|
#include <assimp/StringUtils.h>
|
||||||
#include <assimp/importerdesc.h>
|
#include <assimp/importerdesc.h>
|
||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
#include <assimp/DefaultLogger.hpp>
|
#include <assimp/DefaultLogger.hpp>
|
||||||
|
@ -151,12 +152,7 @@ void HMPImporter::InternReadFile(const std::string &pFile,
|
||||||
InternReadFile_HMP7();
|
InternReadFile_HMP7();
|
||||||
} else {
|
} else {
|
||||||
// Print the magic word to the logger
|
// Print the magic word to the logger
|
||||||
char szBuffer[5];
|
std::string szBuffer = ai_str_toprintable((const char *)&iMagic, sizeof(iMagic));
|
||||||
szBuffer[0] = ((char *)&iMagic)[0];
|
|
||||||
szBuffer[1] = ((char *)&iMagic)[1];
|
|
||||||
szBuffer[2] = ((char *)&iMagic)[2];
|
|
||||||
szBuffer[3] = ((char *)&iMagic)[3];
|
|
||||||
szBuffer[4] = '\0';
|
|
||||||
|
|
||||||
delete[] mBuffer;
|
delete[] mBuffer;
|
||||||
mBuffer = nullptr;
|
mBuffer = nullptr;
|
||||||
|
|
|
@ -115,7 +115,7 @@ static const aiImporterDesc desc = {
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
"ifc ifczip stp"
|
"ifc ifczip step stp"
|
||||||
};
|
};
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -567,7 +567,7 @@ typedef std::map<std::string, std::string> Metadata;
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void ProcessMetadata(const Schema_2x3::ListOf<Schema_2x3::Lazy<Schema_2x3::IfcProperty>, 1, 0> &set, ConversionData &conv, Metadata &properties,
|
void ProcessMetadata(const Schema_2x3::ListOf<Schema_2x3::Lazy<Schema_2x3::IfcProperty>, 1, 0> &set, ConversionData &conv, Metadata &properties,
|
||||||
const std::string &prefix = "",
|
const std::string &prefix = std::string(),
|
||||||
unsigned int nest = 0) {
|
unsigned int nest = 0) {
|
||||||
for (const Schema_2x3::IfcProperty &property : set) {
|
for (const Schema_2x3::IfcProperty &property : set) {
|
||||||
const std::string &key = prefix.length() > 0 ? (prefix + "." + property.Name) : property.Name;
|
const std::string &key = prefix.length() > 0 ? (prefix + "." + property.Name) : property.Name;
|
||||||
|
@ -618,7 +618,7 @@ void ProcessMetadata(const Schema_2x3::ListOf<Schema_2x3::Lazy<Schema_2x3::IfcPr
|
||||||
ProcessMetadata(complexProp->HasProperties, conv, properties, key, nest + 1);
|
ProcessMetadata(complexProp->HasProperties, conv, properties, key, nest + 1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
properties[key] = "";
|
properties[key] = std::string();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -859,13 +859,13 @@ void IRRImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
||||||
|
|
||||||
// Check whether we can read from the file
|
// Check whether we can read from the file
|
||||||
if (file.get() == nullptr) {
|
if (file.get() == nullptr) {
|
||||||
throw DeadlyImportError("Failed to open IRR file " + pFile + "");
|
throw DeadlyImportError("Failed to open IRR file ", pFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Construct the irrXML parser
|
// Construct the irrXML parser
|
||||||
XmlParser st;
|
XmlParser st;
|
||||||
if (!st.parse( file.get() )) {
|
if (!st.parse( file.get() )) {
|
||||||
return;
|
throw DeadlyImportError("XML parse error while loading IRR file ", pFile);
|
||||||
}
|
}
|
||||||
pugi::xml_node rootElement = st.getRootNode();
|
pugi::xml_node rootElement = st.getRootNode();
|
||||||
|
|
||||||
|
|
|
@ -135,12 +135,12 @@ void IRRMeshImporter::InternReadFile(const std::string &pFile,
|
||||||
|
|
||||||
// Check whether we can read from the file
|
// Check whether we can read from the file
|
||||||
if (file.get() == NULL)
|
if (file.get() == NULL)
|
||||||
throw DeadlyImportError("Failed to open IRRMESH file " + pFile + "");
|
throw DeadlyImportError("Failed to open IRRMESH file ", pFile);
|
||||||
|
|
||||||
// Construct the irrXML parser
|
// Construct the irrXML parser
|
||||||
XmlParser parser;
|
XmlParser parser;
|
||||||
if (!parser.parse( file.get() )) {
|
if (!parser.parse( file.get() )) {
|
||||||
return;
|
throw DeadlyImportError("XML parse error while loading IRRMESH file ", pFile);
|
||||||
}
|
}
|
||||||
XmlNode root = parser.getRootNode();
|
XmlNode root = parser.getRootNode();
|
||||||
|
|
||||||
|
|
|
@ -502,7 +502,7 @@ struct Surface {
|
||||||
Surface() :
|
Surface() :
|
||||||
mColor(0.78431f, 0.78431f, 0.78431f), bDoubleSided(false), mDiffuseValue(1.f), mSpecularValue(0.f), mTransparency(0.f), mGlossiness(0.4f), mLuminosity(0.f), mColorHighlights(0.f), mMaximumSmoothAngle(0.f) // 0 == not specified, no smoothing
|
mColor(0.78431f, 0.78431f, 0.78431f), bDoubleSided(false), mDiffuseValue(1.f), mSpecularValue(0.f), mTransparency(0.f), mGlossiness(0.4f), mLuminosity(0.f), mColorHighlights(0.f), mMaximumSmoothAngle(0.f) // 0 == not specified, no smoothing
|
||||||
,
|
,
|
||||||
mVCMap(""),
|
mVCMap(),
|
||||||
mVCMapType(AI_LWO_RGBA),
|
mVCMapType(AI_LWO_RGBA),
|
||||||
mIOR(1.f) // vakuum
|
mIOR(1.f) // vakuum
|
||||||
,
|
,
|
||||||
|
|
|
@ -88,7 +88,7 @@ struct NodeDesc {
|
||||||
id(),
|
id(),
|
||||||
number(0),
|
number(0),
|
||||||
parent(0),
|
parent(0),
|
||||||
name(""),
|
name(),
|
||||||
isPivotSet(false),
|
isPivotSet(false),
|
||||||
lightColor(1.f, 1.f, 1.f),
|
lightColor(1.f, 1.f, 1.f),
|
||||||
lightIntensity(1.f),
|
lightIntensity(1.f),
|
||||||
|
|
|
@ -95,10 +95,9 @@ static const aiImporterDesc desc = {
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
#ifdef M3D_ASCII
|
|
||||||
"m3d a3d"
|
|
||||||
#else
|
|
||||||
"m3d"
|
"m3d"
|
||||||
|
#ifdef M3D_ASCII
|
||||||
|
" a3d"
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -137,7 +136,7 @@ bool M3DImporter::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool c
|
||||||
*/
|
*/
|
||||||
std::unique_ptr<IOStream> pStream(pIOHandler->Open(pFile, "rb"));
|
std::unique_ptr<IOStream> pStream(pIOHandler->Open(pFile, "rb"));
|
||||||
unsigned char data[4];
|
unsigned char data[4];
|
||||||
if (4 != pStream->Read(data, 1, 4)) {
|
if (!pStream || 4 != pStream->Read(data, 1, 4)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return !memcmp(data, "3DMO", 4) /* bin */
|
return !memcmp(data, "3DMO", 4) /* bin */
|
||||||
|
|
|
@ -53,6 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/IOSystem.hpp>
|
#include <assimp/IOSystem.hpp>
|
||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
#include <assimp/importerdesc.h>
|
#include <assimp/importerdesc.h>
|
||||||
|
#include <assimp/StringUtils.h>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
@ -148,46 +149,39 @@ void MD2Importer::ValidateHeader( )
|
||||||
if (m_pcHeader->magic != AI_MD2_MAGIC_NUMBER_BE &&
|
if (m_pcHeader->magic != AI_MD2_MAGIC_NUMBER_BE &&
|
||||||
m_pcHeader->magic != AI_MD2_MAGIC_NUMBER_LE)
|
m_pcHeader->magic != AI_MD2_MAGIC_NUMBER_LE)
|
||||||
{
|
{
|
||||||
char szBuffer[5];
|
throw DeadlyImportError("Invalid MD2 magic word: expected IDP2, found ",
|
||||||
szBuffer[0] = ((char*)&m_pcHeader->magic)[0];
|
ai_str_toprintable((char *)&m_pcHeader->magic, 4));
|
||||||
szBuffer[1] = ((char*)&m_pcHeader->magic)[1];
|
|
||||||
szBuffer[2] = ((char*)&m_pcHeader->magic)[2];
|
|
||||||
szBuffer[3] = ((char*)&m_pcHeader->magic)[3];
|
|
||||||
szBuffer[4] = '\0';
|
|
||||||
|
|
||||||
throw DeadlyImportError("Invalid MD2 magic word: should be IDP2, the "
|
|
||||||
"magic word found is " + std::string(szBuffer));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// check file format version
|
// check file format version
|
||||||
if (m_pcHeader->version != 8)
|
if (m_pcHeader->version != 8)
|
||||||
ASSIMP_LOG_WARN( "Unsupported md2 file version. Continuing happily ...");
|
ASSIMP_LOG_WARN( "Unsupported MD2 file version. Continuing happily ...");
|
||||||
|
|
||||||
// check some values whether they are valid
|
// check some values whether they are valid
|
||||||
if (0 == m_pcHeader->numFrames)
|
if (0 == m_pcHeader->numFrames)
|
||||||
throw DeadlyImportError( "Invalid md2 file: NUM_FRAMES is 0");
|
throw DeadlyImportError( "Invalid MD2 file: NUM_FRAMES is 0");
|
||||||
|
|
||||||
if (m_pcHeader->offsetEnd > (uint32_t)fileSize)
|
if (m_pcHeader->offsetEnd > (uint32_t)fileSize)
|
||||||
throw DeadlyImportError( "Invalid md2 file: File is too small");
|
throw DeadlyImportError( "Invalid MD2 file: File is too small");
|
||||||
|
|
||||||
if (m_pcHeader->numSkins > AI_MAX_ALLOC(MD2::Skin)) {
|
if (m_pcHeader->numSkins > AI_MAX_ALLOC(MD2::Skin)) {
|
||||||
throw DeadlyImportError("Invalid MD2 header: too many skins, would overflow");
|
throw DeadlyImportError("Invalid MD2 header: Too many skins, would overflow");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_pcHeader->numVertices > AI_MAX_ALLOC(MD2::Vertex)) {
|
if (m_pcHeader->numVertices > AI_MAX_ALLOC(MD2::Vertex)) {
|
||||||
throw DeadlyImportError("Invalid MD2 header: too many vertices, would overflow");
|
throw DeadlyImportError("Invalid MD2 header: Too many vertices, would overflow");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_pcHeader->numTexCoords > AI_MAX_ALLOC(MD2::TexCoord)) {
|
if (m_pcHeader->numTexCoords > AI_MAX_ALLOC(MD2::TexCoord)) {
|
||||||
throw DeadlyImportError("Invalid MD2 header: too many texcoords, would overflow");
|
throw DeadlyImportError("Invalid MD2 header: Too many texcoords, would overflow");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_pcHeader->numTriangles > AI_MAX_ALLOC(MD2::Triangle)) {
|
if (m_pcHeader->numTriangles > AI_MAX_ALLOC(MD2::Triangle)) {
|
||||||
throw DeadlyImportError("Invalid MD2 header: too many triangles, would overflow");
|
throw DeadlyImportError("Invalid MD2 header: Too many triangles, would overflow");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_pcHeader->numFrames > AI_MAX_ALLOC(MD2::Frame)) {
|
if (m_pcHeader->numFrames > AI_MAX_ALLOC(MD2::Frame)) {
|
||||||
throw DeadlyImportError("Invalid MD2 header: too many frames, would overflow");
|
throw DeadlyImportError("Invalid MD2 header: Too many frames, would overflow");
|
||||||
}
|
}
|
||||||
|
|
||||||
// -1 because Frame already contains one
|
// -1 because Frame already contains one
|
||||||
|
@ -199,7 +193,7 @@ void MD2Importer::ValidateHeader( )
|
||||||
m_pcHeader->offsetFrames + m_pcHeader->numFrames * frameSize >= fileSize ||
|
m_pcHeader->offsetFrames + m_pcHeader->numFrames * frameSize >= fileSize ||
|
||||||
m_pcHeader->offsetEnd > fileSize)
|
m_pcHeader->offsetEnd > fileSize)
|
||||||
{
|
{
|
||||||
throw DeadlyImportError("Invalid MD2 header: some offsets are outside the file");
|
throw DeadlyImportError("Invalid MD2 header: Some offsets are outside the file");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_pcHeader->numSkins > AI_MD2_MAX_SKINS)
|
if (m_pcHeader->numSkins > AI_MD2_MAX_SKINS)
|
||||||
|
@ -210,7 +204,7 @@ void MD2Importer::ValidateHeader( )
|
||||||
ASSIMP_LOG_WARN("The model contains more vertices than Quake 2 supports");
|
ASSIMP_LOG_WARN("The model contains more vertices than Quake 2 supports");
|
||||||
|
|
||||||
if (m_pcHeader->numFrames <= configFrameID )
|
if (m_pcHeader->numFrames <= configFrameID )
|
||||||
throw DeadlyImportError("The requested frame is not existing the file");
|
throw DeadlyImportError("MD2: The requested frame (", configFrameID, ") does not exist in the file");
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -51,7 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#define AI_MDL_NORMALTABLE_H_INC
|
#define AI_MDL_NORMALTABLE_H_INC
|
||||||
|
|
||||||
|
|
||||||
float g_avNormals[162][3] = {
|
const float g_avNormals[162][3] = {
|
||||||
{ -0.525731f, 0.000000f, 0.850651f },
|
{ -0.525731f, 0.000000f, 0.850651f },
|
||||||
{ -0.442863f, 0.238856f, 0.864188f },
|
{ -0.442863f, 0.238856f, 0.864188f },
|
||||||
{ -0.295242f, 0.000000f, 0.955423f },
|
{ -0.295242f, 0.000000f, 0.955423f },
|
||||||
|
|
|
@ -702,7 +702,7 @@ void MD3Importer::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
||||||
}
|
}
|
||||||
filename = mFile.substr(s), path = mFile.substr(0, s);
|
filename = mFile.substr(s), path = mFile.substr(0, s);
|
||||||
for (std::string::iterator it = filename.begin(); it != filename.end(); ++it) {
|
for (std::string::iterator it = filename.begin(); it != filename.end(); ++it) {
|
||||||
*it = static_cast<char>(tolower(*it));
|
*it = static_cast<char>(tolower(static_cast<unsigned char>(*it)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load multi-part model file, if necessary
|
// Load multi-part model file, if necessary
|
||||||
|
|
|
@ -53,6 +53,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/DefaultLogger.hpp>
|
#include <assimp/DefaultLogger.hpp>
|
||||||
#include <assimp/IOSystem.hpp>
|
#include <assimp/IOSystem.hpp>
|
||||||
#include <assimp/Importer.hpp>
|
#include <assimp/Importer.hpp>
|
||||||
|
#include <assimp/StringUtils.h>
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
@ -143,16 +144,8 @@ void MDCImporter::ValidateHeader() {
|
||||||
|
|
||||||
if (pcHeader->ulIdent != AI_MDC_MAGIC_NUMBER_BE &&
|
if (pcHeader->ulIdent != AI_MDC_MAGIC_NUMBER_BE &&
|
||||||
pcHeader->ulIdent != AI_MDC_MAGIC_NUMBER_LE) {
|
pcHeader->ulIdent != AI_MDC_MAGIC_NUMBER_LE) {
|
||||||
char szBuffer[5];
|
throw DeadlyImportError("Invalid MDC magic word: expected IDPC, found ",
|
||||||
szBuffer[0] = ((char *)&pcHeader->ulIdent)[0];
|
ai_str_toprintable((char *)&pcHeader->ulIdent, 4));
|
||||||
szBuffer[1] = ((char *)&pcHeader->ulIdent)[1];
|
|
||||||
szBuffer[2] = ((char *)&pcHeader->ulIdent)[2];
|
|
||||||
szBuffer[3] = ((char *)&pcHeader->ulIdent)[3];
|
|
||||||
szBuffer[4] = '\0';
|
|
||||||
|
|
||||||
throw DeadlyImportError("Invalid MDC magic word: should be IDPC, the "
|
|
||||||
"magic word found is " +
|
|
||||||
std::string(szBuffer));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pcHeader->ulVersion != AI_MDC_VERSION) {
|
if (pcHeader->ulVersion != AI_MDC_VERSION) {
|
||||||
|
@ -465,6 +458,13 @@ void MDCImporter::InternReadFile(
|
||||||
pcMat->AddProperty(&path, AI_MATKEY_TEXTURE_DIFFUSE(0));
|
pcMat->AddProperty(&path, AI_MATKEY_TEXTURE_DIFFUSE(0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system
|
||||||
|
pScene->mRootNode->mTransformation = aiMatrix4x4(
|
||||||
|
1.f, 0.f, 0.f, 0.f,
|
||||||
|
0.f, 0.f, 1.f, 0.f,
|
||||||
|
0.f, -1.f, 0.f, 0.f,
|
||||||
|
0.f, 0.f, 0.f, 1.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // !! ASSIMP_BUILD_NO_MDC_IMPORTER
|
#endif // !! ASSIMP_BUILD_NO_MDC_IMPORTER
|
||||||
|
|
|
@ -36,7 +36,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#define MDC_NORMAL_TABLE_INCLUDED
|
#define MDC_NORMAL_TABLE_INCLUDED
|
||||||
|
|
||||||
/* mdc decoding normal table */
|
/* mdc decoding normal table */
|
||||||
float mdcNormals[ 256 ][ 3 ] =
|
const float mdcNormals[ 256 ][ 3 ] =
|
||||||
{
|
{
|
||||||
{ 1.000000f, 0.000000f, 0.000000f },
|
{ 1.000000f, 0.000000f, 0.000000f },
|
||||||
{ 0.980785f, 0.195090f, 0.000000f },
|
{ 0.980785f, 0.195090f, 0.000000f },
|
||||||
|
|
|
@ -57,6 +57,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#ifdef MDL_HALFLIFE_LOG_WARN_HEADER
|
#ifdef MDL_HALFLIFE_LOG_WARN_HEADER
|
||||||
#undef MDL_HALFLIFE_LOG_WARN_HEADER
|
#undef MDL_HALFLIFE_LOG_WARN_HEADER
|
||||||
|
@ -868,7 +869,7 @@ void HL1MDLLoader::read_meshes() {
|
||||||
scene_mesh->mNormals[v] = bind_pose_normals[pTrivert->normindex];
|
scene_mesh->mNormals[v] = bind_pose_normals[pTrivert->normindex];
|
||||||
scene_mesh->mTextureCoords[0][v] = aiVector3D(
|
scene_mesh->mTextureCoords[0][v] = aiVector3D(
|
||||||
pTrivert->s * texcoords_s_scale,
|
pTrivert->s * texcoords_s_scale,
|
||||||
pTrivert->t * texcoords_t_scale, 0);
|
pTrivert->t * -texcoords_t_scale, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add face and indices.
|
// Add face and indices.
|
||||||
|
@ -879,9 +880,9 @@ void HL1MDLLoader::read_meshes() {
|
||||||
aiFace *face = &scene_mesh->mFaces[f];
|
aiFace *face = &scene_mesh->mFaces[f];
|
||||||
face->mNumIndices = 3;
|
face->mNumIndices = 3;
|
||||||
face->mIndices = new unsigned int[3];
|
face->mIndices = new unsigned int[3];
|
||||||
face->mIndices[0] = mesh_faces[f].v0;
|
face->mIndices[0] = mesh_faces[f].v2;
|
||||||
face->mIndices[1] = mesh_faces[f].v1;
|
face->mIndices[1] = mesh_faces[f].v1;
|
||||||
face->mIndices[2] = mesh_faces[f].v2;
|
face->mIndices[2] = mesh_faces[f].v0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add mesh bones.
|
// Add mesh bones.
|
||||||
|
|
|
@ -95,7 +95,7 @@ void UniqueNameGenerator::make_unique(std::vector<std::string> &names) {
|
||||||
auto generate_unique_name = [&](const std::string &base_name) -> std::string {
|
auto generate_unique_name = [&](const std::string &base_name) -> std::string {
|
||||||
auto *duplicate_info = &names_to_duplicates[base_name];
|
auto *duplicate_info = &names_to_duplicates[base_name];
|
||||||
|
|
||||||
std::string new_name = "";
|
std::string new_name;
|
||||||
|
|
||||||
bool found_identical_name;
|
bool found_identical_name;
|
||||||
bool tried_with_base_name_only = false;
|
bool tried_with_base_name_only = false;
|
||||||
|
|
|
@ -199,6 +199,7 @@ void MDLImporter::InternReadFile(const std::string &pFile,
|
||||||
const uint32_t iMagicWord = *((uint32_t *)mBuffer);
|
const uint32_t iMagicWord = *((uint32_t *)mBuffer);
|
||||||
|
|
||||||
// Determine the file subtype and call the appropriate member function
|
// Determine the file subtype and call the appropriate member function
|
||||||
|
bool is_half_life = false;
|
||||||
|
|
||||||
// Original Quake1 format
|
// Original Quake1 format
|
||||||
if (AI_MDL_MAGIC_NUMBER_BE == iMagicWord || AI_MDL_MAGIC_NUMBER_LE == iMagicWord) {
|
if (AI_MDL_MAGIC_NUMBER_BE == iMagicWord || AI_MDL_MAGIC_NUMBER_LE == iMagicWord) {
|
||||||
|
@ -240,6 +241,7 @@ void MDLImporter::InternReadFile(const std::string &pFile,
|
||||||
else if (AI_MDL_MAGIC_NUMBER_BE_HL2a == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_HL2a == iMagicWord ||
|
else if (AI_MDL_MAGIC_NUMBER_BE_HL2a == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_HL2a == iMagicWord ||
|
||||||
AI_MDL_MAGIC_NUMBER_BE_HL2b == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_HL2b == iMagicWord) {
|
AI_MDL_MAGIC_NUMBER_BE_HL2b == iMagicWord || AI_MDL_MAGIC_NUMBER_LE_HL2b == iMagicWord) {
|
||||||
iGSFileVersion = 0;
|
iGSFileVersion = 0;
|
||||||
|
is_half_life = true;
|
||||||
|
|
||||||
HalfLife::HalfLifeMDLBaseHeader *pHeader = (HalfLife::HalfLifeMDLBaseHeader *)mBuffer;
|
HalfLife::HalfLifeMDLBaseHeader *pHeader = (HalfLife::HalfLifeMDLBaseHeader *)mBuffer;
|
||||||
if (pHeader->version == AI_MDL_HL1_VERSION) {
|
if (pHeader->version == AI_MDL_HL1_VERSION) {
|
||||||
|
@ -252,12 +254,22 @@ void MDLImporter::InternReadFile(const std::string &pFile,
|
||||||
} else {
|
} else {
|
||||||
// print the magic word to the log file
|
// print the magic word to the log file
|
||||||
throw DeadlyImportError("Unknown MDL subformat ", pFile,
|
throw DeadlyImportError("Unknown MDL subformat ", pFile,
|
||||||
". Magic word (", std::string((char *)&iMagicWord, 4), ") is not known");
|
". Magic word (", ai_str_toprintable((const char *)&iMagicWord, sizeof(iMagicWord)), ") is not known");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system
|
if (is_half_life){
|
||||||
pScene->mRootNode->mTransformation = aiMatrix4x4(1.f, 0.f, 0.f, 0.f,
|
// Now rotate the whole scene 90 degrees around the z and x axes to convert to internal coordinate system
|
||||||
0.f, 0.f, 1.f, 0.f, 0.f, -1.f, 0.f, 0.f, 0.f, 0.f, 0.f, 1.f);
|
pScene->mRootNode->mTransformation = aiMatrix4x4(
|
||||||
|
0.f, -1.f, 0.f, 0.f,
|
||||||
|
0.f, 0.f, 1.f, 0.f,
|
||||||
|
-1.f, 0.f, 0.f, 0.f,
|
||||||
|
0.f, 0.f, 0.f, 1.f);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system
|
||||||
|
pScene->mRootNode->mTransformation = aiMatrix4x4(1.f, 0.f, 0.f, 0.f,
|
||||||
|
0.f, 0.f, 1.f, 0.f, 0.f, -1.f, 0.f, 0.f, 0.f, 0.f, 0.f, 1.f);
|
||||||
|
}
|
||||||
|
|
||||||
DeleteBufferAndCleanup();
|
DeleteBufferAndCleanup();
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
|
|
@ -75,7 +75,7 @@ using namespace std;
|
||||||
// Default constructor
|
// Default constructor
|
||||||
MMDImporter::MMDImporter() :
|
MMDImporter::MMDImporter() :
|
||||||
m_Buffer(),
|
m_Buffer(),
|
||||||
m_strAbsPath("") {
|
m_strAbsPath() {
|
||||||
DefaultIOSystem io;
|
DefaultIOSystem io;
|
||||||
m_strAbsPath = io.getOsSeparator();
|
m_strAbsPath = io.getOsSeparator();
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,7 +91,7 @@ namespace pmx
|
||||||
std::vector<char> buffer;
|
std::vector<char> buffer;
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
{
|
{
|
||||||
return std::string("");
|
return std::string();
|
||||||
}
|
}
|
||||||
buffer.reserve(size);
|
buffer.reserve(size);
|
||||||
stream->read((char*) buffer.data(), size);
|
stream->read((char*) buffer.data(), size);
|
||||||
|
@ -478,8 +478,7 @@ namespace pmx
|
||||||
|
|
||||||
void PmxSoftBody::Read(std::istream * /*stream*/, PmxSetting * /*setting*/)
|
void PmxSoftBody::Read(std::istream * /*stream*/, PmxSetting * /*setting*/)
|
||||||
{
|
{
|
||||||
std::cerr << "Not Implemented Exception" << std::endl;
|
throw DeadlyImportError("MMD: Soft Body support is not implemented.");
|
||||||
throw DeadlyImportError("MMD: Not Implemented Exception");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PmxModel::Init()
|
void PmxModel::Init()
|
||||||
|
@ -516,15 +515,13 @@ namespace pmx
|
||||||
char magic[4];
|
char magic[4];
|
||||||
stream->read((char*) magic, sizeof(char) * 4);
|
stream->read((char*) magic, sizeof(char) * 4);
|
||||||
if (magic[0] != 0x50 || magic[1] != 0x4d || magic[2] != 0x58 || magic[3] != 0x20)
|
if (magic[0] != 0x50 || magic[1] != 0x4d || magic[2] != 0x58 || magic[3] != 0x20)
|
||||||
{
|
{
|
||||||
std::cerr << "invalid magic number." << std::endl;
|
throw DeadlyImportError("MMD: Invalid magic number.");
|
||||||
throw DeadlyImportError("MMD: invalid magic number.");
|
|
||||||
}
|
}
|
||||||
stream->read((char*) &version, sizeof(float));
|
stream->read((char*) &version, sizeof(float));
|
||||||
if (version != 2.0f && version != 2.1f)
|
if (version != 2.0f && version != 2.1f)
|
||||||
{
|
{
|
||||||
std::cerr << "this is not ver2.0 or ver2.1 but " << version << "." << std::endl;
|
throw DeadlyImportError("MMD: Unsupported version (must be 2.0 or 2.1): ", ai_to_string(version));
|
||||||
throw DeadlyImportError("MMD: this is not ver2.0 or ver2.1 but ", ai_to_string(version));
|
|
||||||
}
|
}
|
||||||
this->setting.Read(stream);
|
this->setting.Read(stream);
|
||||||
|
|
||||||
|
|
|
@ -215,7 +215,12 @@ void MS3DImporter :: CollectChildJoints(const std::vector<TempJoint>& joints, ai
|
||||||
void MS3DImporter::InternReadFile( const std::string& pFile,
|
void MS3DImporter::InternReadFile( const std::string& pFile,
|
||||||
aiScene* pScene, IOSystem* pIOHandler)
|
aiScene* pScene, IOSystem* pIOHandler)
|
||||||
{
|
{
|
||||||
StreamReaderLE stream(pIOHandler->Open(pFile,"rb"));
|
|
||||||
|
auto file = pIOHandler->Open(pFile, "rb");
|
||||||
|
if (!file)
|
||||||
|
throw DeadlyImportError("MS3D: Could not open ", pFile);
|
||||||
|
|
||||||
|
StreamReaderLE stream(file);
|
||||||
|
|
||||||
// CanRead() should have done this already
|
// CanRead() should have done this already
|
||||||
char head[10];
|
char head[10];
|
||||||
|
|
|
@ -116,7 +116,13 @@ void NDOImporter::SetupProperties(const Importer* /*pImp*/)
|
||||||
void NDOImporter::InternReadFile( const std::string& pFile,
|
void NDOImporter::InternReadFile( const std::string& pFile,
|
||||||
aiScene* pScene, IOSystem* pIOHandler)
|
aiScene* pScene, IOSystem* pIOHandler)
|
||||||
{
|
{
|
||||||
StreamReaderBE reader(pIOHandler->Open( pFile, "rb"));
|
|
||||||
|
auto file = pIOHandler->Open( pFile, "rb");
|
||||||
|
if (!file) {
|
||||||
|
throw DeadlyImportError("Nendo: Could not open ", pFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
StreamReaderBE reader(file);
|
||||||
|
|
||||||
// first 9 bytes are nendo file format ("nendo 1.n")
|
// first 9 bytes are nendo file format ("nendo 1.n")
|
||||||
const char* head = (const char*)reader.GetPtr();
|
const char* head = (const char*)reader.GetPtr();
|
||||||
|
|
|
@ -45,6 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include <assimp/DefaultIOSystem.h>
|
#include <assimp/DefaultIOSystem.h>
|
||||||
#include <assimp/StringComparison.h>
|
#include <assimp/StringComparison.h>
|
||||||
|
#include <assimp/StringUtils.h>
|
||||||
#include <assimp/DefaultLogger.hpp>
|
#include <assimp/DefaultLogger.hpp>
|
||||||
|
|
||||||
#include <assimp/ai_assert.h>
|
#include <assimp/ai_assert.h>
|
||||||
|
@ -206,7 +207,7 @@ USE_ODDLPARSER_NS
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------------------
|
||||||
static void propId2StdString(Property *prop, std::string &name, std::string &key) {
|
static void propId2StdString(Property *prop, std::string &name, std::string &key) {
|
||||||
name = key = "";
|
name = key = std::string();
|
||||||
if (nullptr == prop) {
|
if (nullptr == prop) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -223,6 +224,18 @@ static void propId2StdString(Property *prop, std::string &name, std::string &key
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------------------
|
||||||
|
static void logDDLParserMessage (LogSeverity severity, const std::string &rawmsg) {
|
||||||
|
std::string msg = ai_str_toprintable(rawmsg);
|
||||||
|
switch (severity) {
|
||||||
|
case ddl_debug_msg: ASSIMP_LOG_DEBUG(msg); break;
|
||||||
|
case ddl_info_msg: ASSIMP_LOG_INFO(msg); break;
|
||||||
|
case ddl_warn_msg: ASSIMP_LOG_WARN(msg); break;
|
||||||
|
case ddl_error_msg: ASSIMP_LOG_ERROR(msg); break;
|
||||||
|
default: ASSIMP_LOG_VERBOSE_DEBUG(msg); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------------------
|
||||||
OpenGEXImporter::VertexContainer::VertexContainer() :
|
OpenGEXImporter::VertexContainer::VertexContainer() :
|
||||||
m_numColors(0), m_colors(nullptr), m_numUVComps(), m_textureCoords() {
|
m_numColors(0), m_colors(nullptr), m_numUVComps(), m_textureCoords() {
|
||||||
|
@ -306,6 +319,7 @@ void OpenGEXImporter::InternReadFile(const std::string &filename, aiScene *pScen
|
||||||
pIOHandler->Close(file);
|
pIOHandler->Close(file);
|
||||||
|
|
||||||
OpenDDLParser myParser;
|
OpenDDLParser myParser;
|
||||||
|
myParser.setLogCallback(&logDDLParserMessage);
|
||||||
myParser.setBuffer(&buffer[0], buffer.size());
|
myParser.setBuffer(&buffer[0], buffer.size());
|
||||||
bool success(myParser.parse());
|
bool success(myParser.parse());
|
||||||
if (success) {
|
if (success) {
|
||||||
|
|
|
@ -79,7 +79,7 @@ struct MetricInfo {
|
||||||
int m_intValue;
|
int m_intValue;
|
||||||
|
|
||||||
MetricInfo()
|
MetricInfo()
|
||||||
: m_stringValue( "" )
|
: m_stringValue( )
|
||||||
, m_floatValue( 0.0f )
|
, m_floatValue( 0.0f )
|
||||||
, m_intValue( -1 ) {
|
, m_intValue( -1 ) {
|
||||||
// empty
|
// empty
|
||||||
|
|
|
@ -172,7 +172,7 @@ void PLYImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
||||||
(headerCheck[1] != 'L' && headerCheck[1] != 'l') ||
|
(headerCheck[1] != 'L' && headerCheck[1] != 'l') ||
|
||||||
(headerCheck[2] != 'Y' && headerCheck[2] != 'y')) {
|
(headerCheck[2] != 'Y' && headerCheck[2] != 'y')) {
|
||||||
streamedBuffer.close();
|
streamedBuffer.close();
|
||||||
throw DeadlyImportError("Invalid .ply file: Magic number \'ply\' is no there");
|
throw DeadlyImportError("Invalid .ply file: Incorrect magic number (expected 'ply' or 'PLY').");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<char> mBuffer2;
|
std::vector<char> mBuffer2;
|
||||||
|
|
|
@ -178,7 +178,7 @@ struct Q3BSPModel {
|
||||||
m_Textures(),
|
m_Textures(),
|
||||||
m_Lightmaps(),
|
m_Lightmaps(),
|
||||||
m_EntityData(),
|
m_EntityData(),
|
||||||
m_ModelName( "" )
|
m_ModelName()
|
||||||
{
|
{
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,7 +75,7 @@ static const aiImporterDesc desc = {
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
"pk3"
|
"bsp pk3"
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
@ -113,7 +113,7 @@ static void extractIds(const std::string &key, int &id1, int &id2) {
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Local helper function to normalize filenames.
|
// Local helper function to normalize filenames.
|
||||||
static void normalizePathName(const std::string &rPath, std::string &normalizedPath) {
|
static void normalizePathName(const std::string &rPath, std::string &normalizedPath) {
|
||||||
normalizedPath = "";
|
normalizedPath = std::string();
|
||||||
if (rPath.empty()) {
|
if (rPath.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -183,7 +183,7 @@ void Q3BSPFileImporter::InternReadFile(const std::string &rFile, aiScene *scene,
|
||||||
throw DeadlyImportError("Failed to open file ", rFile, ".");
|
throw DeadlyImportError("Failed to open file ", rFile, ".");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string archiveName(""), mapName("");
|
std::string archiveName, mapName;
|
||||||
separateMapName(rFile, archiveName, mapName);
|
separateMapName(rFile, archiveName, mapName);
|
||||||
|
|
||||||
if (mapName.empty()) {
|
if (mapName.empty()) {
|
||||||
|
@ -202,8 +202,8 @@ void Q3BSPFileImporter::InternReadFile(const std::string &rFile, aiScene *scene,
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Separates the map name from the import name.
|
// Separates the map name from the import name.
|
||||||
void Q3BSPFileImporter::separateMapName(const std::string &importName, std::string &archiveName, std::string &mapName) {
|
void Q3BSPFileImporter::separateMapName(const std::string &importName, std::string &archiveName, std::string &mapName) {
|
||||||
archiveName = "";
|
archiveName = std::string();
|
||||||
mapName = "";
|
mapName = std::string();
|
||||||
if (importName.empty()) {
|
if (importName.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -221,7 +221,7 @@ void Q3BSPFileImporter::separateMapName(const std::string &importName, std::stri
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Returns the first map in the map archive.
|
// Returns the first map in the map archive.
|
||||||
bool Q3BSPFileImporter::findFirstMapInArchive(ZipArchiveIOSystem &bspArchive, std::string &mapName) {
|
bool Q3BSPFileImporter::findFirstMapInArchive(ZipArchiveIOSystem &bspArchive, std::string &mapName) {
|
||||||
mapName = "";
|
mapName = std::string();
|
||||||
std::vector<std::string> fileList;
|
std::vector<std::string> fileList;
|
||||||
bspArchive.getFileListExtension(fileList, "bsp");
|
bspArchive.getFileListExtension(fileList, "bsp");
|
||||||
if (fileList.empty()) {
|
if (fileList.empty()) {
|
||||||
|
@ -440,7 +440,7 @@ void Q3BSPFileImporter::createMaterials(const Q3BSP::Q3BSPModel *pModel, aiScene
|
||||||
if (-1 != textureId) {
|
if (-1 != textureId) {
|
||||||
sQ3BSPTexture *pTexture = pModel->m_Textures[textureId];
|
sQ3BSPTexture *pTexture = pModel->m_Textures[textureId];
|
||||||
if (nullptr != pTexture) {
|
if (nullptr != pTexture) {
|
||||||
std::string tmp("*"), texName("");
|
std::string tmp("*"), texName;
|
||||||
tmp += pTexture->strName;
|
tmp += pTexture->strName;
|
||||||
tmp += ".jpg";
|
tmp += ".jpg";
|
||||||
normalizePathName(tmp, texName);
|
normalizePathName(tmp, texName);
|
||||||
|
@ -512,7 +512,7 @@ size_t Q3BSPFileImporter::countTriangles(const std::vector<Q3BSP::sQ3BSPFace *>
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Creates the faces-to-material map.
|
// Creates the faces-to-material map.
|
||||||
void Q3BSPFileImporter::createMaterialMap(const Q3BSP::Q3BSPModel *pModel) {
|
void Q3BSPFileImporter::createMaterialMap(const Q3BSP::Q3BSPModel *pModel) {
|
||||||
std::string key("");
|
std::string key;
|
||||||
std::vector<sQ3BSPFace *> *pCurFaceArray = nullptr;
|
std::vector<sQ3BSPFace *> *pCurFaceArray = nullptr;
|
||||||
for (size_t idx = 0; idx < pModel->m_Faces.size(); idx++) {
|
for (size_t idx = 0; idx < pModel->m_Faces.size(); idx++) {
|
||||||
Q3BSP::sQ3BSPFace *pQ3BSPFace = pModel->m_Faces[idx];
|
Q3BSP::sQ3BSPFace *pQ3BSPFace = pModel->m_Faces[idx];
|
||||||
|
@ -660,7 +660,7 @@ bool Q3BSPFileImporter::expandFile(ZipArchiveIOSystem *pArchive, const std::stri
|
||||||
|
|
||||||
if (rExtList.empty()) {
|
if (rExtList.empty()) {
|
||||||
rFile = rFilename;
|
rFile = rFilename;
|
||||||
rExt = "";
|
rExt = std::string();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
// internal headers
|
// internal headers
|
||||||
#include "Q3DLoader.h"
|
#include "Q3DLoader.h"
|
||||||
|
#include <assimp/StringUtils.h>
|
||||||
#include <assimp/StreamReader.h>
|
#include <assimp/StreamReader.h>
|
||||||
#include <assimp/fast_atof.h>
|
#include <assimp/fast_atof.h>
|
||||||
#include <assimp/importerdesc.h>
|
#include <assimp/importerdesc.h>
|
||||||
|
@ -106,7 +107,12 @@ const aiImporterDesc *Q3DImporter::GetInfo() const {
|
||||||
// Imports the given file into the given scene structure.
|
// Imports the given file into the given scene structure.
|
||||||
void Q3DImporter::InternReadFile(const std::string &pFile,
|
void Q3DImporter::InternReadFile(const std::string &pFile,
|
||||||
aiScene *pScene, IOSystem *pIOHandler) {
|
aiScene *pScene, IOSystem *pIOHandler) {
|
||||||
StreamReaderLE stream(pIOHandler->Open(pFile, "rb"));
|
|
||||||
|
auto file = pIOHandler->Open(pFile, "rb");
|
||||||
|
if (!file)
|
||||||
|
throw DeadlyImportError("Quick3D: Could not open ", pFile);
|
||||||
|
|
||||||
|
StreamReaderLE stream(file);
|
||||||
|
|
||||||
// The header is 22 bytes large
|
// The header is 22 bytes large
|
||||||
if (stream.GetRemainingSize() < 22)
|
if (stream.GetRemainingSize() < 22)
|
||||||
|
@ -115,7 +121,7 @@ void Q3DImporter::InternReadFile(const std::string &pFile,
|
||||||
// Check the file's signature
|
// Check the file's signature
|
||||||
if (ASSIMP_strincmp((const char *)stream.GetPtr(), "quick3Do", 8) &&
|
if (ASSIMP_strincmp((const char *)stream.GetPtr(), "quick3Do", 8) &&
|
||||||
ASSIMP_strincmp((const char *)stream.GetPtr(), "quick3Ds", 8)) {
|
ASSIMP_strincmp((const char *)stream.GetPtr(), "quick3Ds", 8)) {
|
||||||
throw DeadlyImportError("Not a Quick3D file. Signature string is: ", std::string((const char *)stream.GetPtr(), 8));
|
throw DeadlyImportError("Not a Quick3D file. Signature string is: ", ai_str_toprintable((const char *)stream.GetPtr(), 8));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print the file format version
|
// Print the file format version
|
||||||
|
|
|
@ -68,6 +68,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
#include <assimp/DefaultLogger.hpp>
|
#include <assimp/DefaultLogger.hpp>
|
||||||
#include <assimp/IOSystem.hpp>
|
#include <assimp/IOSystem.hpp>
|
||||||
|
#include <assimp/StringUtils.h>
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
@ -166,14 +167,14 @@ static aiColor3D ReadColor(StreamReaderLE *stream) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void UnknownChunk(StreamReaderLE * /*stream*/, const SIBChunk &chunk) {
|
static void UnknownChunk(StreamReaderLE * /*stream*/, const SIBChunk &chunk) {
|
||||||
char temp[5] = {
|
char temp[4] = {
|
||||||
static_cast<char>((chunk.Tag >> 24) & 0xff),
|
static_cast<char>((chunk.Tag >> 24) & 0xff),
|
||||||
static_cast<char>((chunk.Tag >> 16) & 0xff),
|
static_cast<char>((chunk.Tag >> 16) & 0xff),
|
||||||
static_cast<char>((chunk.Tag >> 8) & 0xff),
|
static_cast<char>((chunk.Tag >> 8) & 0xff),
|
||||||
static_cast<char>(chunk.Tag & 0xff), '\0'
|
static_cast<char>(chunk.Tag & 0xff)
|
||||||
};
|
};
|
||||||
|
|
||||||
ASSIMP_LOG_WARN((Formatter::format(), "SIB: Skipping unknown '", temp, "' chunk."));
|
ASSIMP_LOG_WARN((Formatter::format(), "SIB: Skipping unknown '", ai_str_toprintable(temp, 4), "' chunk."));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reads a UTF-16LE string and returns it at UTF-8.
|
// Reads a UTF-16LE string and returns it at UTF-8.
|
||||||
|
@ -804,7 +805,12 @@ static void ReadScene(SIB *sib, StreamReaderLE *stream) {
|
||||||
// Imports the given file into the given scene structure.
|
// Imports the given file into the given scene structure.
|
||||||
void SIBImporter::InternReadFile(const std::string &pFile,
|
void SIBImporter::InternReadFile(const std::string &pFile,
|
||||||
aiScene *pScene, IOSystem *pIOHandler) {
|
aiScene *pScene, IOSystem *pIOHandler) {
|
||||||
StreamReaderLE stream(pIOHandler->Open(pFile, "rb"));
|
|
||||||
|
auto file = pIOHandler->Open(pFile, "rb");
|
||||||
|
if (!file)
|
||||||
|
throw DeadlyImportError("SIB: Could not open ", pFile);
|
||||||
|
|
||||||
|
StreamReaderLE stream(file);
|
||||||
|
|
||||||
// We should have at least one chunk
|
// We should have at least one chunk
|
||||||
if (stream.GetRemainingSize() < 16)
|
if (stream.GetRemainingSize() < 16)
|
||||||
|
|
|
@ -130,7 +130,7 @@ struct Mesh {
|
||||||
|
|
||||||
std::vector<Bone> mBones;
|
std::vector<Bone> mBones;
|
||||||
|
|
||||||
explicit Mesh(const std::string &pName = "") AI_NO_EXCEPT
|
explicit Mesh(const std::string &pName = std::string()) AI_NO_EXCEPT
|
||||||
: mName( pName )
|
: mName( pName )
|
||||||
, mPositions()
|
, mPositions()
|
||||||
, mPosFaces()
|
, mPosFaces()
|
||||||
|
|
|
@ -667,8 +667,8 @@ void XFileImporter::ConvertMaterials( aiScene* pScene, std::vector<XFile::Materi
|
||||||
|
|
||||||
// convert to lower case for easier comparison
|
// convert to lower case for easier comparison
|
||||||
for ( unsigned int c = 0; c < sz.length(); ++c ) {
|
for ( unsigned int c = 0; c < sz.length(); ++c ) {
|
||||||
if ( isalpha( sz[ c ] ) ) {
|
if ( isalpha( (unsigned char) sz[ c ] ) ) {
|
||||||
sz[ c ] = (char) tolower( sz[ c ] );
|
sz[ c ] = (char) tolower( (unsigned char) sz[ c ] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1245,13 +1245,13 @@ unsigned int XFileParser::ReadInt() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// at least one digit expected
|
// at least one digit expected
|
||||||
if (!isdigit(*mP))
|
if (!isdigit((unsigned char)*mP))
|
||||||
ThrowException("Number expected.");
|
ThrowException("Number expected.");
|
||||||
|
|
||||||
// read digits
|
// read digits
|
||||||
unsigned int number = 0;
|
unsigned int number = 0;
|
||||||
while (mP < mEnd) {
|
while (mP < mEnd) {
|
||||||
if (!isdigit(*mP))
|
if (!isdigit((unsigned char)*mP))
|
||||||
break;
|
break;
|
||||||
number = number * 10 + (*mP - 48);
|
number = number * 10 + (*mP - 48);
|
||||||
mP++;
|
mP++;
|
||||||
|
|
|
@ -167,10 +167,6 @@ bool X3DImporter::CanRead( const std::string &pFile, IOSystem * /*pIOHandler*/,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void X3DImporter::GetExtensionList( std::set<std::string> &extensionList ) {
|
|
||||||
extensionList.insert("x3d");
|
|
||||||
}
|
|
||||||
|
|
||||||
void X3DImporter::InternReadFile( const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler ) {
|
void X3DImporter::InternReadFile( const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler ) {
|
||||||
std::shared_ptr<IOStream> stream(pIOHandler->Open(pFile, "rb"));
|
std::shared_ptr<IOStream> stream(pIOHandler->Open(pFile, "rb"));
|
||||||
if (!stream) {
|
if (!stream) {
|
||||||
|
|
|
@ -307,7 +307,6 @@ public:
|
||||||
/// \param [in] pIOHandler - pointer to IO helper object.
|
/// \param [in] pIOHandler - pointer to IO helper object.
|
||||||
void ParseFile(const std::string &pFile, IOSystem *pIOHandler);
|
void ParseFile(const std::string &pFile, IOSystem *pIOHandler);
|
||||||
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool pCheckSig) const;
|
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool pCheckSig) const;
|
||||||
void GetExtensionList(std::set<std::string> &pExtensionList);
|
|
||||||
void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler);
|
void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler);
|
||||||
const aiImporterDesc *GetInfo() const;
|
const aiImporterDesc *GetInfo() const;
|
||||||
void Clear();
|
void Clear();
|
||||||
|
|
|
@ -142,7 +142,7 @@ void XGLImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
||||||
|
|
||||||
// check whether we can read from the file
|
// check whether we can read from the file
|
||||||
if (stream.get() == NULL) {
|
if (stream.get() == NULL) {
|
||||||
throw DeadlyImportError("Failed to open XGL/ZGL file " + pFile + "");
|
throw DeadlyImportError("Failed to open XGL/ZGL file " + pFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
// see if its compressed, if so uncompress it
|
// see if its compressed, if so uncompress it
|
||||||
|
@ -200,7 +200,7 @@ void XGLImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
||||||
// parse the XML file
|
// parse the XML file
|
||||||
mXmlParser = new XmlParser;
|
mXmlParser = new XmlParser;
|
||||||
if (!mXmlParser->parse(stream.get())) {
|
if (!mXmlParser->parse(stream.get())) {
|
||||||
return;
|
throw DeadlyImportError("XML parse error while loading XGL file ", pFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
TempScope scope;
|
TempScope scope;
|
||||||
|
|
|
@ -1033,7 +1033,7 @@ namespace glTF
|
||||||
|
|
||||||
AssetMetadata()
|
AssetMetadata()
|
||||||
: premultipliedAlpha(false)
|
: premultipliedAlpha(false)
|
||||||
, version("")
|
, version()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1071,7 +1071,7 @@ struct AssetMetadata {
|
||||||
void Read(Document &doc);
|
void Read(Document &doc);
|
||||||
|
|
||||||
AssetMetadata() :
|
AssetMetadata() :
|
||||||
version("") {}
|
version() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -47,7 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
CIOStreamWrapper::~CIOStreamWrapper(void) {
|
CIOStreamWrapper::~CIOStreamWrapper() {
|
||||||
/* Various places depend on this destructor to close the file */
|
/* Various places depend on this destructor to close the file */
|
||||||
if (mFile) {
|
if (mFile) {
|
||||||
mIO->mFileSystem->CloseProc(mIO->mFileSystem, mFile);
|
mIO->mFileSystem->CloseProc(mIO->mFileSystem, mFile);
|
||||||
|
@ -78,7 +78,7 @@ aiReturn CIOStreamWrapper::Seek(size_t pOffset,
|
||||||
}
|
}
|
||||||
|
|
||||||
// ...................................................................
|
// ...................................................................
|
||||||
size_t CIOStreamWrapper::Tell(void) const {
|
size_t CIOStreamWrapper::Tell() const {
|
||||||
return mFile->TellProc(mFile);
|
return mFile->TellProc(mFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,20 +65,6 @@ using namespace Assimp;
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
BaseImporter::BaseImporter() AI_NO_EXCEPT
|
BaseImporter::BaseImporter() AI_NO_EXCEPT
|
||||||
: m_progress() {
|
: m_progress() {
|
||||||
/**
|
|
||||||
* Assimp Importer
|
|
||||||
* unit conversions available
|
|
||||||
* if you need another measurment unit add it below.
|
|
||||||
* it's currently defined in assimp that we prefer meters.
|
|
||||||
*
|
|
||||||
* NOTE: Initialised here rather than in the header file
|
|
||||||
* to workaround a VS2013 bug with brace initialisers
|
|
||||||
* */
|
|
||||||
importerUnits[ImporterUnits::M] = 1.0;
|
|
||||||
importerUnits[ImporterUnits::CM] = 0.01;
|
|
||||||
importerUnits[ImporterUnits::MM] = 0.001;
|
|
||||||
importerUnits[ImporterUnits::INCHES] = 0.0254;
|
|
||||||
importerUnits[ImporterUnits::FEET] = 0.3048;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -97,7 +83,7 @@ void BaseImporter::UpdateImporterScale(Importer *pImp) {
|
||||||
// Set active scaling
|
// Set active scaling
|
||||||
pImp->SetPropertyFloat(AI_CONFIG_APP_SCALE_KEY, static_cast<float>(activeScale));
|
pImp->SetPropertyFloat(AI_CONFIG_APP_SCALE_KEY, static_cast<float>(activeScale));
|
||||||
|
|
||||||
ASSIMP_LOG_DEBUG_F("UpdateImporterScale scale set: %f", activeScale);
|
ASSIMP_LOG_DEBUG_F("UpdateImporterScale scale set: ", activeScale);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -193,7 +179,7 @@ void BaseImporter::GetExtensionList(std::set<std::string> &extensions) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < read; ++i) {
|
for (size_t i = 0; i < read; ++i) {
|
||||||
buffer[i] = static_cast<char>(::tolower(buffer[i]));
|
buffer[i] = static_cast<char>(::tolower((unsigned char)buffer[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
// It is not a proper handling of unicode files here ...
|
// It is not a proper handling of unicode files here ...
|
||||||
|
@ -214,7 +200,7 @@ void BaseImporter::GetExtensionList(std::set<std::string> &extensions) {
|
||||||
token.clear();
|
token.clear();
|
||||||
const char *ptr(tokens[i]);
|
const char *ptr(tokens[i]);
|
||||||
for (size_t tokIdx = 0; tokIdx < len; ++tokIdx) {
|
for (size_t tokIdx = 0; tokIdx < len; ++tokIdx) {
|
||||||
token.push_back(static_cast<char>(tolower(*ptr)));
|
token.push_back(static_cast<char>(tolower(static_cast<unsigned char>(*ptr))));
|
||||||
++ptr;
|
++ptr;
|
||||||
}
|
}
|
||||||
const char *r = strstr(buffer, token.c_str());
|
const char *r = strstr(buffer, token.c_str());
|
||||||
|
@ -223,7 +209,7 @@ void BaseImporter::GetExtensionList(std::set<std::string> &extensions) {
|
||||||
}
|
}
|
||||||
// We need to make sure that we didn't accidentially identify the end of another token as our token,
|
// We need to make sure that we didn't accidentially identify the end of another token as our token,
|
||||||
// e.g. in a previous version the "gltf " present in some gltf files was detected as "f "
|
// e.g. in a previous version the "gltf " present in some gltf files was detected as "f "
|
||||||
if (noAlphaBeforeTokens && (r != buffer && isalpha(r[-1]))) {
|
if (noAlphaBeforeTokens && (r != buffer && isalpha(static_cast<unsigned char>(r[-1])))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// We got a match, either we don't care where it is, or it happens to
|
// We got a match, either we don't care where it is, or it happens to
|
||||||
|
@ -271,7 +257,7 @@ std::string BaseImporter::GetExtension(const std::string &file) {
|
||||||
|
|
||||||
// no file extension at all
|
// no file extension at all
|
||||||
if (pos == std::string::npos) {
|
if (pos == std::string::npos) {
|
||||||
return "";
|
return std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
// thanks to Andy Maloney for the hint
|
// thanks to Andy Maloney for the hint
|
||||||
|
|
|
@ -76,7 +76,7 @@ public:
|
||||||
if (std::string::npos != (ss2 = mBase.find_last_of("\\/"))) {
|
if (std::string::npos != (ss2 = mBase.find_last_of("\\/"))) {
|
||||||
mBase.erase(ss2,mBase.length()-ss2);
|
mBase.erase(ss2,mBase.length()-ss2);
|
||||||
} else {
|
} else {
|
||||||
mBase = "";
|
mBase = std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure the directory is terminated properly
|
// make sure the directory is terminated properly
|
||||||
|
|
|
@ -149,7 +149,7 @@ void AllocateFromAssimpHeap::operator delete[] ( void* data) {
|
||||||
Importer::Importer()
|
Importer::Importer()
|
||||||
: pimpl( new ImporterPimpl ) {
|
: pimpl( new ImporterPimpl ) {
|
||||||
pimpl->mScene = nullptr;
|
pimpl->mScene = nullptr;
|
||||||
pimpl->mErrorString = "";
|
pimpl->mErrorString = std::string();
|
||||||
|
|
||||||
// Allocate a default IO handler
|
// Allocate a default IO handler
|
||||||
pimpl->mIOHandler = new DefaultIOSystem;
|
pimpl->mIOHandler = new DefaultIOSystem;
|
||||||
|
@ -387,7 +387,7 @@ void Importer::FreeScene( ) {
|
||||||
delete pimpl->mScene;
|
delete pimpl->mScene;
|
||||||
pimpl->mScene = nullptr;
|
pimpl->mScene = nullptr;
|
||||||
|
|
||||||
pimpl->mErrorString = "";
|
pimpl->mErrorString = std::string();
|
||||||
pimpl->mException = std::exception_ptr();
|
pimpl->mException = std::exception_ptr();
|
||||||
ASSIMP_END_EXCEPTION_REGION(void);
|
ASSIMP_END_EXCEPTION_REGION(void);
|
||||||
}
|
}
|
||||||
|
@ -434,7 +434,7 @@ aiScene* Importer::GetOrphanedScene() {
|
||||||
ASSIMP_BEGIN_EXCEPTION_REGION();
|
ASSIMP_BEGIN_EXCEPTION_REGION();
|
||||||
pimpl->mScene = nullptr;
|
pimpl->mScene = nullptr;
|
||||||
|
|
||||||
pimpl->mErrorString = ""; // reset error string
|
pimpl->mErrorString = std::string();
|
||||||
pimpl->mException = std::exception_ptr();
|
pimpl->mException = std::exception_ptr();
|
||||||
ASSIMP_END_EXCEPTION_REGION(aiScene*);
|
ASSIMP_END_EXCEPTION_REGION(aiScene*);
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,7 @@ corresponding preprocessor flag to selectively disable formats.
|
||||||
|
|
||||||
#include <assimp/BaseImporter.h>
|
#include <assimp/BaseImporter.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Importers
|
// Importers
|
||||||
|
@ -204,7 +205,17 @@ corresponding preprocessor flag to selectively disable formats.
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void GetImporterInstanceList(std::vector<BaseImporter *> &out) {
|
void GetImporterInstanceList(std::vector<BaseImporter *> &out) {
|
||||||
|
|
||||||
|
// Some importers may be unimplemented or otherwise unsuitable for general use
|
||||||
|
// in their current state. Devs can set ASSIMP_ENABLE_DEV_IMPORTERS in their
|
||||||
|
// local environment to enable them, otherwise they're left out of the registry.
|
||||||
|
const char *envStr = std::getenv("ASSIMP_ENABLE_DEV_IMPORTERS");
|
||||||
|
bool devImportersEnabled = envStr && strcmp(envStr, "0");
|
||||||
|
|
||||||
|
// Ensure no unused var warnings if all uses are #ifndef'd away below:
|
||||||
|
(void)devImportersEnabled;
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// Add an instance of each worker class here
|
// Add an instance of each worker class here
|
||||||
// (register_new_importers_here)
|
// (register_new_importers_here)
|
||||||
|
@ -354,7 +365,9 @@ void GetImporterInstanceList(std::vector<BaseImporter *> &out) {
|
||||||
out.push_back(new D3MFImporter());
|
out.push_back(new D3MFImporter());
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_X3D_IMPORTER
|
||||||
out.push_back(new X3DImporter());
|
if (devImportersEnabled) { // https://github.com/assimp/assimp/issues/3647
|
||||||
|
out.push_back(new X3DImporter());
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifndef ASSIMP_BUILD_NO_MMD_IMPORTER
|
#ifndef ASSIMP_BUILD_NO_MMD_IMPORTER
|
||||||
out.push_back(new MMDImporter());
|
out.push_back(new MMDImporter());
|
||||||
|
|
|
@ -45,7 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
// possible as new fields are added to assimp structures.
|
// possible as new fields are added to assimp structures.
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* @file Implements Assimp::SceneCombiner. This is a smart utility
|
* @file Implements Assimp::SceneCombiner. This is a smart utility
|
||||||
* class that combines multiple scenes, meshes, ... into one. Currently
|
* class that combines multiple scenes, meshes, ... into one. Currently
|
||||||
* these utilities are used by the IRR and LWS loaders and the
|
* these utilities are used by the IRR and LWS loaders and the
|
||||||
|
@ -359,7 +359,7 @@ void SceneCombiner::MergeScenes(aiScene **_dest, aiScene *master, std::vector<At
|
||||||
|
|
||||||
// generate the output texture list + an offset table for all texture indices
|
// generate the output texture list + an offset table for all texture indices
|
||||||
if (dest->mNumTextures) {
|
if (dest->mNumTextures) {
|
||||||
aiTexture **pip = dest->mTextures = new aiTexture *[dest->mNumMaterials];
|
aiTexture **pip = dest->mTextures = new aiTexture *[dest->mNumTextures];
|
||||||
cnt = 0;
|
cnt = 0;
|
||||||
for (unsigned int n = 0; n < src.size(); ++n) {
|
for (unsigned int n = 0; n < src.size(); ++n) {
|
||||||
SceneHelper *cur = &src[n];
|
SceneHelper *cur = &src[n];
|
||||||
|
@ -638,6 +638,8 @@ void SceneCombiner::MergeScenes(aiScene **_dest, aiScene *master, std::vector<At
|
||||||
deleteMe->mMaterials = nullptr;
|
deleteMe->mMaterials = nullptr;
|
||||||
delete[] deleteMe->mAnimations;
|
delete[] deleteMe->mAnimations;
|
||||||
deleteMe->mAnimations = nullptr;
|
deleteMe->mAnimations = nullptr;
|
||||||
|
delete[] deleteMe->mTextures;
|
||||||
|
deleteMe->mTextures = nullptr;
|
||||||
|
|
||||||
deleteMe->mRootNode = nullptr;
|
deleteMe->mRootNode = nullptr;
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/scene.h>
|
#include <assimp/scene.h>
|
||||||
|
|
||||||
aiNode::aiNode()
|
aiNode::aiNode()
|
||||||
: mName("")
|
: mName()
|
||||||
, mParent(nullptr)
|
, mParent(nullptr)
|
||||||
, mNumChildren(0)
|
, mNumChildren(0)
|
||||||
, mChildren(nullptr)
|
, mChildren(nullptr)
|
||||||
|
|
|
@ -70,6 +70,7 @@ GenFaceNormalsProcess::~GenFaceNormalsProcess() {
|
||||||
// Returns whether the processing step is present in the given flag field.
|
// Returns whether the processing step is present in the given flag field.
|
||||||
bool GenFaceNormalsProcess::IsActive(unsigned int pFlags) const {
|
bool GenFaceNormalsProcess::IsActive(unsigned int pFlags) const {
|
||||||
force_ = (pFlags & aiProcess_ForceGenNormals) != 0;
|
force_ = (pFlags & aiProcess_ForceGenNormals) != 0;
|
||||||
|
flippedWindingOrder_ = (pFlags & aiProcess_FlipWindingOrder) != 0;
|
||||||
return (pFlags & aiProcess_GenNormals) != 0;
|
return (pFlags & aiProcess_GenNormals) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,6 +135,8 @@ bool GenFaceNormalsProcess::GenMeshFaceNormals(aiMesh *pMesh) {
|
||||||
const aiVector3D *pV1 = &pMesh->mVertices[face.mIndices[0]];
|
const aiVector3D *pV1 = &pMesh->mVertices[face.mIndices[0]];
|
||||||
const aiVector3D *pV2 = &pMesh->mVertices[face.mIndices[1]];
|
const aiVector3D *pV2 = &pMesh->mVertices[face.mIndices[1]];
|
||||||
const aiVector3D *pV3 = &pMesh->mVertices[face.mIndices[face.mNumIndices - 1]];
|
const aiVector3D *pV3 = &pMesh->mVertices[face.mIndices[face.mNumIndices - 1]];
|
||||||
|
if (flippedWindingOrder_)
|
||||||
|
std::swap( pV2, pV3 );
|
||||||
const aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1)).NormalizeSafe();
|
const aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1)).NormalizeSafe();
|
||||||
|
|
||||||
for (unsigned int i = 0; i < face.mNumIndices; ++i) {
|
for (unsigned int i = 0; i < face.mNumIndices; ++i) {
|
||||||
|
|
|
@ -80,6 +80,7 @@ public:
|
||||||
private:
|
private:
|
||||||
bool GenMeshFaceNormals(aiMesh* pcMesh);
|
bool GenMeshFaceNormals(aiMesh* pcMesh);
|
||||||
mutable bool force_ = false;
|
mutable bool force_ = false;
|
||||||
|
mutable bool flippedWindingOrder_ = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
|
|
|
@ -70,6 +70,7 @@ GenVertexNormalsProcess::~GenVertexNormalsProcess() {
|
||||||
// Returns whether the processing step is present in the given flag field.
|
// Returns whether the processing step is present in the given flag field.
|
||||||
bool GenVertexNormalsProcess::IsActive(unsigned int pFlags) const {
|
bool GenVertexNormalsProcess::IsActive(unsigned int pFlags) const {
|
||||||
force_ = (pFlags & aiProcess_ForceGenNormals) != 0;
|
force_ = (pFlags & aiProcess_ForceGenNormals) != 0;
|
||||||
|
flippedWindingOrder_ = (pFlags & aiProcess_FlipWindingOrder) != 0;
|
||||||
return (pFlags & aiProcess_GenSmoothNormals) != 0;
|
return (pFlags & aiProcess_GenSmoothNormals) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,6 +143,8 @@ bool GenVertexNormalsProcess::GenMeshVertexNormals(aiMesh *pMesh, unsigned int m
|
||||||
const aiVector3D *pV1 = &pMesh->mVertices[face.mIndices[0]];
|
const aiVector3D *pV1 = &pMesh->mVertices[face.mIndices[0]];
|
||||||
const aiVector3D *pV2 = &pMesh->mVertices[face.mIndices[1]];
|
const aiVector3D *pV2 = &pMesh->mVertices[face.mIndices[1]];
|
||||||
const aiVector3D *pV3 = &pMesh->mVertices[face.mIndices[face.mNumIndices - 1]];
|
const aiVector3D *pV3 = &pMesh->mVertices[face.mIndices[face.mNumIndices - 1]];
|
||||||
|
if (flippedWindingOrder_)
|
||||||
|
std::swap( pV2, pV3 );
|
||||||
const aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1)).NormalizeSafe();
|
const aiVector3D vNor = ((*pV2 - *pV1) ^ (*pV3 - *pV1)).NormalizeSafe();
|
||||||
|
|
||||||
for (unsigned int i = 0; i < face.mNumIndices; ++i) {
|
for (unsigned int i = 0; i < face.mNumIndices; ++i) {
|
||||||
|
|
|
@ -104,6 +104,7 @@ private:
|
||||||
/** Configuration option: maximum smoothing angle, in radians*/
|
/** Configuration option: maximum smoothing angle, in radians*/
|
||||||
ai_real configMaxAngle;
|
ai_real configMaxAngle;
|
||||||
mutable bool force_ = false;
|
mutable bool force_ = false;
|
||||||
|
mutable bool flippedWindingOrder_ = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
|
|
|
@ -429,7 +429,7 @@ void PretransformVertices::Execute(aiScene *pScene) {
|
||||||
const unsigned int iOldNodes = CountNodes(pScene->mRootNode);
|
const unsigned int iOldNodes = CountNodes(pScene->mRootNode);
|
||||||
|
|
||||||
if (configTransform) {
|
if (configTransform) {
|
||||||
pScene->mRootNode->mTransformation = configTransformation;
|
pScene->mRootNode->mTransformation = configTransformation * pScene->mRootNode->mTransformation;
|
||||||
}
|
}
|
||||||
|
|
||||||
// first compute absolute transformation matrices for all nodes
|
// first compute absolute transformation matrices for all nodes
|
||||||
|
|
|
@ -81,7 +81,7 @@ public:
|
||||||
/** @brief Set list of fixed (inmutable) materials
|
/** @brief Set list of fixed (inmutable) materials
|
||||||
* @param fixed See #AI_CONFIG_PP_RRM_EXCLUDE_LIST
|
* @param fixed See #AI_CONFIG_PP_RRM_EXCLUDE_LIST
|
||||||
*/
|
*/
|
||||||
void SetFixedMaterialsString(const std::string& fixed = "") {
|
void SetFixedMaterialsString(const std::string& fixed = std::string()) {
|
||||||
mConfigFixedMaterials = fixed;
|
mConfigFixedMaterials = fixed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -252,7 +252,7 @@ DecoderBuffer ParseLineIntoDecoderBuffer(DecoderBuffer *buffer) {
|
||||||
|
|
||||||
std::string ToLower(const std::string &str) {
|
std::string ToLower(const std::string &str) {
|
||||||
std::string out;
|
std::string out;
|
||||||
std::transform(str.begin(), str.end(), std::back_inserter(out), tolower);
|
std::transform(str.begin(), str.end(), std::back_inserter(out), [](unsigned char c){return tolower(c);});
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -268,14 +268,14 @@ std::vector<std::string> PlyReader::SplitWords(const std::string &line) {
|
||||||
while ((end = line.find_first_of(" \t\n\v\f\r", start)) !=
|
while ((end = line.find_first_of(" \t\n\v\f\r", start)) !=
|
||||||
std::string::npos) {
|
std::string::npos) {
|
||||||
const std::string word(line.substr(start, end - start));
|
const std::string word(line.substr(start, end - start));
|
||||||
if (!std::all_of(word.begin(), word.end(), isspace)) {
|
if (!std::all_of(word.begin(), word.end(), [](unsigned char c){return isspace(c);})) {
|
||||||
output.push_back(word);
|
output.push_back(word);
|
||||||
}
|
}
|
||||||
start = end + 1;
|
start = end + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string last_word(line.substr(start));
|
const std::string last_word(line.substr(start));
|
||||||
if (!std::all_of(last_word.begin(), last_word.end(), isspace)) {
|
if (!std::all_of(last_word.begin(), last_word.end(), [](unsigned char c){return isspace(c);})) {
|
||||||
output.push_back(last_word);
|
output.push_back(last_word);
|
||||||
}
|
}
|
||||||
return output;
|
return output;
|
||||||
|
|
|
@ -644,7 +644,7 @@ class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase {
|
||||||
|
|
||||||
// Check for invalid characters
|
// Check for invalid characters
|
||||||
for (std::string::size_type index = 0; index < name.size(); ++index) {
|
for (std::string::size_type index = 0; index < name.size(); ++index) {
|
||||||
if (!isalnum(name[index]) && name[index] != '_')
|
if (!IsAlNum(name[index]) && name[index] != '_')
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -72,13 +72,15 @@ const char *getTypeToken(Value::ValueType type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void logInvalidTokenError(char *in, const std::string &exp, OpenDDLParser::logCallback callback) {
|
static void logInvalidTokenError(char *in, const std::string &exp, OpenDDLParser::logCallback callback) {
|
||||||
std::stringstream stream;
|
if (callback) {
|
||||||
stream << "Invalid token \"" << *in << "\""
|
std::string full(in);
|
||||||
<< " expected \"" << exp << "\"" << std::endl;
|
std::string part(full.substr(0, 50));
|
||||||
std::string full(in);
|
std::stringstream stream;
|
||||||
std::string part(full.substr(0, 50));
|
stream << "Invalid token \"" << *in << "\" "
|
||||||
stream << part;
|
<< "(expected \"" << exp << "\") "
|
||||||
callback(ddl_error_msg, stream.str());
|
<< "in: \"" << part << "\"";
|
||||||
|
callback(ddl_error_msg, stream.str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isIntegerType(Value::ValueType integerType) {
|
static bool isIntegerType(Value::ValueType integerType) {
|
||||||
|
@ -111,26 +113,8 @@ static DDLNode *createDDLNode(Text *id, OpenDDLParser *parser) {
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void logMessage(LogSeverity severity, const std::string &msg) {
|
|
||||||
std::string log;
|
|
||||||
if (ddl_debug_msg == severity) {
|
|
||||||
log += "Debug:";
|
|
||||||
} else if (ddl_info_msg == severity) {
|
|
||||||
log += "Info :";
|
|
||||||
} else if (ddl_warn_msg == severity) {
|
|
||||||
log += "Warn :";
|
|
||||||
} else if (ddl_error_msg == severity) {
|
|
||||||
log += "Error:";
|
|
||||||
} else {
|
|
||||||
log += "None :";
|
|
||||||
}
|
|
||||||
|
|
||||||
log += msg;
|
|
||||||
std::cout << log;
|
|
||||||
}
|
|
||||||
|
|
||||||
OpenDDLParser::OpenDDLParser() :
|
OpenDDLParser::OpenDDLParser() :
|
||||||
m_logCallback(logMessage),
|
m_logCallback(nullptr),
|
||||||
m_buffer(),
|
m_buffer(),
|
||||||
m_stack(),
|
m_stack(),
|
||||||
m_context(nullptr) {
|
m_context(nullptr) {
|
||||||
|
@ -138,7 +122,7 @@ OpenDDLParser::OpenDDLParser() :
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenDDLParser::OpenDDLParser(const char *buffer, size_t len) :
|
OpenDDLParser::OpenDDLParser(const char *buffer, size_t len) :
|
||||||
m_logCallback(&logMessage), m_buffer(), m_context(nullptr) {
|
m_logCallback(nullptr), m_buffer(), m_context(nullptr) {
|
||||||
if (0 != len) {
|
if (0 != len) {
|
||||||
setBuffer(buffer, len);
|
setBuffer(buffer, len);
|
||||||
}
|
}
|
||||||
|
@ -149,13 +133,8 @@ OpenDDLParser::~OpenDDLParser() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenDDLParser::setLogCallback(logCallback callback) {
|
void OpenDDLParser::setLogCallback(logCallback callback) {
|
||||||
if (nullptr != callback) {
|
// install user-specific log callback; null = no log callback
|
||||||
// install user-specific log callback
|
m_logCallback = callback;
|
||||||
m_logCallback = callback;
|
|
||||||
} else {
|
|
||||||
// install default log callback
|
|
||||||
m_logCallback = &logMessage;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenDDLParser::logCallback OpenDDLParser::getLogCallback() const {
|
OpenDDLParser::logCallback OpenDDLParser::getLogCallback() const {
|
||||||
|
|
|
@ -1,58 +0,0 @@
|
||||||
/build/
|
|
||||||
/test/build/
|
|
||||||
/xcodeproj/
|
|
||||||
.vscode/
|
|
||||||
|
|
||||||
# Object files
|
|
||||||
*.o
|
|
||||||
*.ko
|
|
||||||
*.obj
|
|
||||||
*.elf
|
|
||||||
|
|
||||||
# Precompiled Headers
|
|
||||||
*.gch
|
|
||||||
*.pch
|
|
||||||
|
|
||||||
# Libraries
|
|
||||||
*.lib
|
|
||||||
*.a
|
|
||||||
*.la
|
|
||||||
*.lo
|
|
||||||
|
|
||||||
# Shared objects (inc. Windows DLLs)
|
|
||||||
*.dll
|
|
||||||
*.so
|
|
||||||
*.so.*
|
|
||||||
*.dylib
|
|
||||||
*.suo
|
|
||||||
|
|
||||||
# Executables
|
|
||||||
*.exe
|
|
||||||
*.out
|
|
||||||
*.app
|
|
||||||
*.i*86
|
|
||||||
*.x86_64
|
|
||||||
*.hex
|
|
||||||
|
|
||||||
# Temporary
|
|
||||||
*.swp
|
|
||||||
.DS_Store
|
|
||||||
|
|
||||||
# CMake
|
|
||||||
CMakeScripts
|
|
||||||
*.cmake
|
|
||||||
|
|
||||||
# Xcode
|
|
||||||
*.build
|
|
||||||
*.xcodeproj
|
|
||||||
zip.sln
|
|
||||||
zip.vcxproj.filters
|
|
||||||
zip.vcxproj
|
|
||||||
ALL_BUILD.vcxproj.filters
|
|
||||||
ALL_BUILD.vcxproj
|
|
||||||
CMakeFiles/
|
|
||||||
zip.dir/
|
|
||||||
test/test.exe.vcxproj.filters
|
|
||||||
test/test.exe.vcxproj
|
|
||||||
test/test.exe.dir/
|
|
||||||
|
|
|
@ -1,26 +1,29 @@
|
||||||
cmake_minimum_required(VERSION 3.10)
|
cmake_minimum_required(VERSION 3.4)
|
||||||
|
|
||||||
project(zip
|
project(zip
|
||||||
LANGUAGES C
|
LANGUAGES C
|
||||||
VERSION "0.1.18")
|
VERSION "0.1.19")
|
||||||
set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
|
set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
|
||||||
|
set(CMAKE_VERBOSE_MAKEFILE ON)
|
||||||
option(CMAKE_DISABLE_TESTING "Disable test creation" OFF)
|
option(CMAKE_DISABLE_TESTING "Disable test creation" OFF)
|
||||||
|
|
||||||
if (MSVC)
|
|
||||||
# Use secure functions by default and suppress warnings about "deprecated" functions
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT=1")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_NONSTDC_NO_WARNINGS=1 /D _CRT_SECURE_NO_WARNINGS=1")
|
|
||||||
elseif ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR
|
|
||||||
"${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR
|
|
||||||
"${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang")
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -Wall -Wextra -Werror -pedantic")
|
|
||||||
endif (MSVC)
|
|
||||||
|
|
||||||
# zip
|
# zip
|
||||||
set(SRC src/miniz.h src/zip.h src/zip.c)
|
set(SRC src/miniz.h src/zip.h src/zip.c)
|
||||||
add_library(${PROJECT_NAME} ${SRC})
|
|
||||||
|
# this is the "object library" target: compiles the sources only once
|
||||||
|
add_library(OBJLIB OBJECT ${SRC})
|
||||||
|
# shared libraries need PIC
|
||||||
|
set_property(TARGET OBJLIB PROPERTY POSITION_INDEPENDENT_CODE 1)
|
||||||
|
|
||||||
|
# static and shared libraries built from the same object files
|
||||||
|
if (BUILD_SHARED_LIBS)
|
||||||
|
add_library(${PROJECT_NAME} SHARED $<TARGET_OBJECTS:OBJLIB>)
|
||||||
|
include(GenerateExportHeader)
|
||||||
|
generate_export_header(${PROJECT_NAME})
|
||||||
|
else()
|
||||||
|
add_library(${PROJECT_NAME} STATIC $<TARGET_OBJECTS:OBJLIB>)
|
||||||
|
endif()
|
||||||
|
|
||||||
target_include_directories(${PROJECT_NAME} PUBLIC
|
target_include_directories(${PROJECT_NAME} PUBLIC
|
||||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
|
||||||
$<INSTALL_INTERFACE:include>
|
$<INSTALL_INTERFACE:include>
|
||||||
|
@ -34,6 +37,17 @@ if (NOT CMAKE_DISABLE_TESTING)
|
||||||
add_sanitizers(${PROJECT_NAME} ${test_out})
|
add_sanitizers(${PROJECT_NAME} ${test_out})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (MSVC)
|
||||||
|
# Use secure functions by default and suppress warnings about "deprecated" functions
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT=1")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_NONSTDC_NO_WARNINGS=1 /D _CRT_SECURE_NO_WARNINGS=1")
|
||||||
|
elseif ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR
|
||||||
|
"${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR
|
||||||
|
"${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang")
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99 -Wall -Wextra -Werror -pedantic -Wno-deprecated")
|
||||||
|
endif (MSVC)
|
||||||
|
|
||||||
####
|
####
|
||||||
# Installation (https://github.com/forexample/package-example) {
|
# Installation (https://github.com/forexample/package-example) {
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
This is done by hacking awesome [miniz](https://code.google.com/p/miniz) library and layering functions on top of the miniz v1.15 API.
|
This is done by hacking awesome [miniz](https://code.google.com/p/miniz) library and layering functions on top of the miniz v1.15 API.
|
||||||
|
|
||||||
[![Build](https://github.com/kuba--/zip/workflows/build/badge.svg)](https://github.com/kuba--/zip/actions?query=workflow%3Abuild)
|
[![Build](https://github.com/kuba--/zip/workflows/build/badge.svg)](https://github.com/kuba--/zip/actions?query=workflow%3Abuild)
|
||||||
[![Version](https://badge.fury.io/gh/kuba--%2Fzip.svg)](https://github.com/kuba--/zip/releases)
|
|
||||||
|
|
||||||
|
|
||||||
# The Idea
|
# The Idea
|
||||||
|
@ -155,10 +154,52 @@ struct zip_t *zip = zip_open("foo.zip", 0, 'r');
|
||||||
zip_close(zip);
|
zip_close(zip);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
* Create a new zip archive in memory (stream API).
|
||||||
|
|
||||||
|
```c
|
||||||
|
char *outbuf = NULL;
|
||||||
|
size_t outbufsize = 0;
|
||||||
|
|
||||||
|
const char *inbuf = "Append some data here...\0";
|
||||||
|
struct zip_t *zip = zip_stream_open(NULL, 0, ZIP_DEFAULT_COMPRESSION_LEVEL, 'w');
|
||||||
|
{
|
||||||
|
zip_entry_open(zip, "foo-1.txt");
|
||||||
|
{
|
||||||
|
zip_entry_write(zip, inbuf, strlen(inbuf));
|
||||||
|
}
|
||||||
|
zip_entry_close(zip);
|
||||||
|
|
||||||
|
/* copy compressed stream into outbuf */
|
||||||
|
zip_stream_copy(zip, (void **)&outbuf, &outbufsize);
|
||||||
|
}
|
||||||
|
zip_stream_close(zip);
|
||||||
|
|
||||||
|
free(outbuf);
|
||||||
|
```
|
||||||
|
|
||||||
|
* Extract a zip entry into a memory (stream API).
|
||||||
|
|
||||||
|
```c
|
||||||
|
char *buf = NULL;
|
||||||
|
ssize_t bufsize = 0;
|
||||||
|
|
||||||
|
struct zip_t *zip = zip_stream_open(zipstream, zipstreamsize, 0, 'r');
|
||||||
|
{
|
||||||
|
zip_entry_open(zip, "foo-1.txt");
|
||||||
|
{
|
||||||
|
zip_entry_read(zip, (void **)&buf, &bufsize);
|
||||||
|
}
|
||||||
|
zip_entry_close(zip);
|
||||||
|
}
|
||||||
|
zip_stream_close(zip);
|
||||||
|
|
||||||
|
free(buf);
|
||||||
|
```
|
||||||
|
|
||||||
* List of all zip entries
|
* List of all zip entries
|
||||||
```c
|
```c
|
||||||
struct zip_t *zip = zip_open("foo.zip", 0, 'r');
|
struct zip_t *zip = zip_open("foo.zip", 0, 'r');
|
||||||
int i, n = zip_total_entries(zip);
|
int i, n = zip_entries_total(zip);
|
||||||
for (i = 0; i < n; ++i) {
|
for (i = 0; i < n; ++i) {
|
||||||
zip_entry_openbyindex(zip, i);
|
zip_entry_openbyindex(zip, i);
|
||||||
{
|
{
|
||||||
|
@ -172,6 +213,49 @@ for (i = 0; i < n; ++i) {
|
||||||
zip_close(zip);
|
zip_close(zip);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
* Compress folder (recursively)
|
||||||
|
```c
|
||||||
|
void zip_walk(struct zip_t *zip, const char *path) {
|
||||||
|
DIR *dir;
|
||||||
|
struct dirent *entry;
|
||||||
|
char fullpath[MAX_PATH];
|
||||||
|
struct stat s;
|
||||||
|
|
||||||
|
memset(fullpath, 0, MAX_PATH);
|
||||||
|
dir = opendir(path);
|
||||||
|
assert(dir);
|
||||||
|
|
||||||
|
while ((entry = readdir(dir))) {
|
||||||
|
// skip "." and ".."
|
||||||
|
if (!strcmp(entry->d_name, ".\0") || !strcmp(entry->d_name, "..\0"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
snprintf(fullpath, sizeof(fullpath), "%s/%s", path, entry->d_name);
|
||||||
|
stat(fullpath, &s);
|
||||||
|
if (S_ISDIR(s.st_mode))
|
||||||
|
zip_walk(zip, fullpath);
|
||||||
|
else {
|
||||||
|
zip_entry_open(zip, fullpath);
|
||||||
|
zip_entry_fwrite(zip, fullpath);
|
||||||
|
zip_entry_close(zip);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir(dir);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
* Deletes zip archive entries.
|
||||||
|
```c
|
||||||
|
char *entries[] = {"unused.txt", "remove.ini", "delete.me"};
|
||||||
|
|
||||||
|
struct zip_t *zip = zip_open("foo.zip", 0, 'd');
|
||||||
|
{
|
||||||
|
zip_entries_delete(zip, entries, 3);
|
||||||
|
}
|
||||||
|
zip_close(zip);
|
||||||
|
```
|
||||||
|
|
||||||
# Bindings
|
# Bindings
|
||||||
Compile zip library as a dynamic library.
|
Compile zip library as a dynamic library.
|
||||||
```shell
|
```shell
|
||||||
|
@ -181,7 +265,7 @@ $ cmake -DBUILD_SHARED_LIBS=true ..
|
||||||
$ make
|
$ make
|
||||||
```
|
```
|
||||||
|
|
||||||
### Go (cgo)
|
### [Go](https://golang.org) (cgo)
|
||||||
```go
|
```go
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
@ -211,7 +295,7 @@ func main() {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Rust (ffi)
|
### [Rust](https://www.rust-lang.org) (ffi)
|
||||||
```rust
|
```rust
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
|
@ -236,7 +320,7 @@ extern "C" {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let path = CString::new("/tmp/test.zip").unwrap();
|
let path = CString::new("/tmp/rust.zip").unwrap();
|
||||||
let mode: libc::c_char = 'w' as libc::c_char;
|
let mode: libc::c_char = 'w' as libc::c_char;
|
||||||
|
|
||||||
let entryname = CString::new("test.txt").unwrap();
|
let entryname = CString::new("test.txt").unwrap();
|
||||||
|
@ -258,7 +342,7 @@ fn main() {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Ruby (ffi)
|
### [Ruby](http://www.ruby-lang.org) (ffi)
|
||||||
Install _ffi_ gem.
|
Install _ffi_ gem.
|
||||||
```shell
|
```shell
|
||||||
$ gem install ffi
|
$ gem install ffi
|
||||||
|
@ -291,7 +375,7 @@ Zip.zip_entry_close(ptr)
|
||||||
Zip.zip_close(ptr)
|
Zip.zip_close(ptr)
|
||||||
```
|
```
|
||||||
|
|
||||||
### Python (cffi)
|
### [Python](https://www.python.org) (cffi)
|
||||||
Install _cffi_ package
|
Install _cffi_ package
|
||||||
```shell
|
```shell
|
||||||
$ pip install cffi
|
$ pip install cffi
|
||||||
|
@ -325,7 +409,36 @@ Zip.zip_entry_close(ptr)
|
||||||
Zip.zip_close(ptr)
|
Zip.zip_close(ptr)
|
||||||
```
|
```
|
||||||
|
|
||||||
### Ring
|
### [Never](https://never-lang.readthedocs.io/) (ffi)
|
||||||
|
```never
|
||||||
|
extern "libzip.so" func zip_open(zipname: string, level: int, mode: char) -> c_ptr
|
||||||
|
extern "libzip.so" func zip_close(zip: c_ptr) -> void
|
||||||
|
|
||||||
|
extern "libzip.so" func zip_entry_open(zip: c_ptr, entryname: string) -> int
|
||||||
|
extern "libzip.so" func zip_entry_close(zip: c_ptr) -> int
|
||||||
|
extern "libzip.so" func zip_entry_write(zip: c_ptr, buf: string, bufsize: int) -> int
|
||||||
|
extern "libzip.so" func zip_entry_fwrite(zip: c_ptr, filename: string) -> int
|
||||||
|
|
||||||
|
func main() -> int
|
||||||
|
{
|
||||||
|
let content = "Test content"
|
||||||
|
|
||||||
|
let zip = zip_open("/tmp/never.zip", 6, 'w');
|
||||||
|
|
||||||
|
zip_entry_open(zip, "test.file");
|
||||||
|
zip_entry_fwrite(zip, "/tmp/test.txt");
|
||||||
|
zip_entry_close(zip);
|
||||||
|
|
||||||
|
zip_entry_open(zip, "test.content");
|
||||||
|
zip_entry_write(zip, content, length(content));
|
||||||
|
zip_entry_close(zip);
|
||||||
|
|
||||||
|
zip_close(zip);
|
||||||
|
0
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### [Ring](http://ring-lang.net)
|
||||||
The language comes with RingZip based on this library
|
The language comes with RingZip based on this library
|
||||||
```ring
|
```ring
|
||||||
load "ziplib.ring"
|
load "ziplib.ring"
|
||||||
|
@ -342,13 +455,15 @@ new Zip {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
# Contribution Rules/Coding Standards
|
# Check out more cool projects which use this library:
|
||||||
No need to throw away your coding style, just do your best to follow default clang-format style.
|
- [Filament](https://github.com/google/filament): Filament is a real-time physically based rendering engine for Android, iOS, Linux, macOS, Windows, and WebGL. It is designed to be as small as possible and as efficient as possible on Android.
|
||||||
Apply `clang-format` to the source files before commit:
|
- [Hermes JS Engine](https://github.com/facebook/hermes): Hermes is a JavaScript engine optimized for fast start-up of React Native apps on Android. It features ahead-of-time static optimization and compact bytecode.
|
||||||
```sh
|
- [Open Asset Import Library](https://github.com/assimp/assimp): A library to import and export various 3d-model-formats including scene-post-processing to generate missing render data.
|
||||||
for file in $(git ls-files | \grep -E '\.(c|h)$' | \grep -v -- '#')
|
- [PowerToys](https://github.com/microsoft/PowerToys): Set of utilities for power users to tune and streamline their Windows 10 experience for greater productivity.
|
||||||
do
|
- [The Ring Programming Language](https://ring-lang.github.io): Innovative and practical general-purpose multi-paradigm language.
|
||||||
clang-format -i $file
|
- [The V Programming Language](https://github.com/vlang/v): Simple, fast, safe, compiled. For developing maintainable software.
|
||||||
done
|
- [TIC-80](https://github.com/nesbox/TIC-80): TIC-80 is a FREE and OPEN SOURCE fantasy computer for making, playing and sharing tiny games.
|
||||||
```
|
- [Urho3D](https://github.com/urho3d/Urho3D): Urho3D is a free lightweight, cross-platform 2D and 3D game engine implemented in C++ and released under the MIT license. Greatly inspired by OGRE and Horde3D.
|
||||||
|
- [Vcpkg](https://github.com/microsoft/vcpkg): Vcpkg helps you manage C and C++ libraries on Windows, Linux and MacOS.
|
||||||
|
- [and more...](https://grep.app/search?q=kuba--/zip)
|
||||||
|
|
||||||
|
|
|
@ -400,7 +400,7 @@ typedef enum {
|
||||||
#ifndef MINIZ_NO_ZLIB_APIS
|
#ifndef MINIZ_NO_ZLIB_APIS
|
||||||
|
|
||||||
// Heap allocation callbacks.
|
// Heap allocation callbacks.
|
||||||
// Note that mz_alloc_func parameter types purpsosely differ from zlib's:
|
// Note that mz_alloc_func parameter types purposely differ from zlib's:
|
||||||
// items/size is size_t, not unsigned long.
|
// items/size is size_t, not unsigned long.
|
||||||
typedef void *(*mz_alloc_func)(void *opaque, size_t items, size_t size);
|
typedef void *(*mz_alloc_func)(void *opaque, size_t items, size_t size);
|
||||||
typedef void (*mz_free_func)(void *opaque, void *address);
|
typedef void (*mz_free_func)(void *opaque, void *address);
|
||||||
|
@ -2194,7 +2194,8 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r,
|
||||||
} else
|
} else
|
||||||
tree_cur = pTable->m_tree[-tree_cur - 1];
|
tree_cur = pTable->m_tree[-tree_cur - 1];
|
||||||
}
|
}
|
||||||
tree_cur -= ((rev_code >>= 1) & 1);
|
rev_code >>= 1;
|
||||||
|
tree_cur -= (rev_code & 1);
|
||||||
pTable->m_tree[-tree_cur - 1] = (mz_int16)sym_index;
|
pTable->m_tree[-tree_cur - 1] = (mz_int16)sym_index;
|
||||||
}
|
}
|
||||||
if (r->m_type == 2) {
|
if (r->m_type == 2) {
|
||||||
|
@ -3970,6 +3971,7 @@ mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits,
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable : 4121 4127 4244)
|
||||||
#pragma warning(disable : 4204) // nonstandard extension used : non-constant
|
#pragma warning(disable : 4204) // nonstandard extension used : non-constant
|
||||||
// aggregate initializer (also supported by GNU
|
// aggregate initializer (also supported by GNU
|
||||||
// C and C99, so no big deal)
|
// C and C99, so no big deal)
|
||||||
|
@ -4098,10 +4100,6 @@ void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h,
|
||||||
pLen_out, 6, MZ_FALSE);
|
pLen_out, 6, MZ_FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma warning(pop)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ------------------- .ZIP archive reading
|
// ------------------- .ZIP archive reading
|
||||||
|
|
||||||
#ifndef MINIZ_NO_ARCHIVE_APIS
|
#ifndef MINIZ_NO_ARCHIVE_APIS
|
||||||
|
@ -4112,18 +4110,39 @@ void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h,
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
static wchar_t *str2wstr(const char *str) {
|
||||||
|
int len = (int) strlen(str) + 1;
|
||||||
|
wchar_t *wstr = malloc(len * sizeof(wchar_t));
|
||||||
|
MultiByteToWideChar(CP_UTF8, 0, str, len * sizeof(char), wstr, len);
|
||||||
|
return wstr;
|
||||||
|
}
|
||||||
|
|
||||||
static FILE *mz_fopen(const char *pFilename, const char *pMode) {
|
static FILE *mz_fopen(const char *pFilename, const char *pMode) {
|
||||||
FILE *pFile = NULL;
|
wchar_t *wFilename = str2wstr(pFilename);
|
||||||
fopen_s(&pFile, pFilename, pMode);
|
wchar_t *wMode = str2wstr(pMode);
|
||||||
|
FILE *pFile = _wfopen(wFilename, wMode);
|
||||||
|
|
||||||
|
free(wFilename);
|
||||||
|
free(wMode);
|
||||||
|
|
||||||
return pFile;
|
return pFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream) {
|
static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream) {
|
||||||
FILE *pFile = NULL;
|
wchar_t *wPath = str2wstr(pPath);
|
||||||
if (freopen_s(&pFile, pPath, pMode, pStream))
|
wchar_t *wMode = str2wstr(pMode);
|
||||||
return NULL;
|
FILE *pFile = _wfreopen(wPath, wMode, pStream);
|
||||||
|
|
||||||
|
free(wPath);
|
||||||
|
free(wMode);
|
||||||
|
|
||||||
return pFile;
|
return pFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef MINIZ_NO_TIME
|
#ifndef MINIZ_NO_TIME
|
||||||
#include <sys/utime.h>
|
#include <sys/utime.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -4144,7 +4163,7 @@ static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream) {
|
||||||
#include <sys/utime.h>
|
#include <sys/utime.h>
|
||||||
#endif
|
#endif
|
||||||
#define MZ_FILE FILE
|
#define MZ_FILE FILE
|
||||||
#define MZ_FOPEN(f, m) fopen(f, m)
|
#define MZ_FOPEN(f, m) mz_fopen
|
||||||
#define MZ_FCLOSE fclose
|
#define MZ_FCLOSE fclose
|
||||||
#define MZ_FREAD fread
|
#define MZ_FREAD fread
|
||||||
#define MZ_FWRITE fwrite
|
#define MZ_FWRITE fwrite
|
||||||
|
@ -4153,7 +4172,7 @@ static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream) {
|
||||||
#define MZ_FILE_STAT_STRUCT _stat
|
#define MZ_FILE_STAT_STRUCT _stat
|
||||||
#define MZ_FILE_STAT _stat
|
#define MZ_FILE_STAT _stat
|
||||||
#define MZ_FFLUSH fflush
|
#define MZ_FFLUSH fflush
|
||||||
#define MZ_FREOPEN(f, m, s) freopen(f, m, s)
|
#define MZ_FREOPEN(f, m, s) mz_freopen
|
||||||
#define MZ_DELETE_FILE remove
|
#define MZ_DELETE_FILE remove
|
||||||
#elif defined(__TINYC__)
|
#elif defined(__TINYC__)
|
||||||
#ifndef MINIZ_NO_TIME
|
#ifndef MINIZ_NO_TIME
|
||||||
|
@ -5361,13 +5380,9 @@ mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip,
|
||||||
} else {
|
} else {
|
||||||
// Temporarily allocate a read buffer.
|
// Temporarily allocate a read buffer.
|
||||||
read_buf_size = MZ_MIN(file_stat.m_comp_size, MZ_ZIP_MAX_IO_BUF_SIZE);
|
read_buf_size = MZ_MIN(file_stat.m_comp_size, MZ_ZIP_MAX_IO_BUF_SIZE);
|
||||||
#if defined(_MSC_VER) && !defined(__clang__)
|
|
||||||
if (((0, sizeof(size_t) == sizeof(mz_uint32))) &&
|
|
||||||
(read_buf_size > 0x7FFFFFFF))
|
|
||||||
#else
|
|
||||||
if (((sizeof(size_t) == sizeof(mz_uint32))) && (read_buf_size > 0x7FFFFFFF))
|
if (((sizeof(size_t) == sizeof(mz_uint32))) && (read_buf_size > 0x7FFFFFFF))
|
||||||
#endif
|
|
||||||
return MZ_FALSE;
|
return MZ_FALSE;
|
||||||
|
|
||||||
if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1,
|
if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1,
|
||||||
(size_t)read_buf_size)))
|
(size_t)read_buf_size)))
|
||||||
return MZ_FALSE;
|
return MZ_FALSE;
|
||||||
|
@ -5454,11 +5469,7 @@ void *mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, mz_uint file_index,
|
||||||
uncomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS);
|
uncomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS);
|
||||||
|
|
||||||
alloc_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? comp_size : uncomp_size;
|
alloc_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? comp_size : uncomp_size;
|
||||||
#if defined(_MSC_VER) && !defined(__clang__)
|
|
||||||
if (((0, sizeof(size_t) == sizeof(mz_uint32))) && (alloc_size > 0x7FFFFFFF))
|
|
||||||
#else
|
|
||||||
if (((sizeof(size_t) == sizeof(mz_uint32))) && (alloc_size > 0x7FFFFFFF))
|
if (((sizeof(size_t) == sizeof(mz_uint32))) && (alloc_size > 0x7FFFFFFF))
|
||||||
#endif
|
|
||||||
return NULL;
|
return NULL;
|
||||||
if (NULL ==
|
if (NULL ==
|
||||||
(pBuf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)alloc_size)))
|
(pBuf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)alloc_size)))
|
||||||
|
@ -5560,14 +5571,10 @@ mz_bool mz_zip_reader_extract_to_callback(mz_zip_archive *pZip,
|
||||||
if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method)) {
|
if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method)) {
|
||||||
// The file is stored or the caller has requested the compressed data.
|
// The file is stored or the caller has requested the compressed data.
|
||||||
if (pZip->m_pState->m_pMem) {
|
if (pZip->m_pState->m_pMem) {
|
||||||
#if defined (_MSC_VER) && !defined(__clang__)
|
|
||||||
if (((0, sizeof(size_t) == sizeof(mz_uint32))) &&
|
|
||||||
(file_stat.m_comp_size > 0xFFFFFFFF))
|
|
||||||
#else
|
|
||||||
if (((sizeof(size_t) == sizeof(mz_uint32))) &&
|
if (((sizeof(size_t) == sizeof(mz_uint32))) &&
|
||||||
(file_stat.m_comp_size > 0xFFFFFFFF))
|
(file_stat.m_comp_size > 0xFFFFFFFF))
|
||||||
#endif
|
|
||||||
return MZ_FALSE;
|
return MZ_FALSE;
|
||||||
|
|
||||||
if (pCallback(pOpaque, out_buf_ofs, pRead_buf,
|
if (pCallback(pOpaque, out_buf_ofs, pRead_buf,
|
||||||
(size_t)file_stat.m_comp_size) != file_stat.m_comp_size)
|
(size_t)file_stat.m_comp_size) != file_stat.m_comp_size)
|
||||||
status = TINFL_STATUS_FAILED;
|
status = TINFL_STATUS_FAILED;
|
||||||
|
@ -6085,7 +6092,7 @@ mz_zip_writer_compute_padding_needed_for_file_alignment(mz_zip_archive *pZip) {
|
||||||
if (!pZip->m_file_offset_alignment)
|
if (!pZip->m_file_offset_alignment)
|
||||||
return 0;
|
return 0;
|
||||||
n = (mz_uint32)(pZip->m_archive_size & (pZip->m_file_offset_alignment - 1));
|
n = (mz_uint32)(pZip->m_archive_size & (pZip->m_file_offset_alignment - 1));
|
||||||
return (mz_uint)(pZip->m_file_offset_alignment - n) &
|
return (pZip->m_file_offset_alignment - n) &
|
||||||
(pZip->m_file_offset_alignment - 1);
|
(pZip->m_file_offset_alignment - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6289,7 +6296,10 @@ mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name,
|
||||||
mz_uint32 ext_attributes) {
|
mz_uint32 ext_attributes) {
|
||||||
mz_uint uncomp_crc32 = MZ_CRC32_INIT, level, num_alignment_padding_bytes;
|
mz_uint uncomp_crc32 = MZ_CRC32_INIT, level, num_alignment_padding_bytes;
|
||||||
mz_uint16 method = 0, dos_time = 0, dos_date = 0;
|
mz_uint16 method = 0, dos_time = 0, dos_date = 0;
|
||||||
|
#ifndef MINIZ_NO_TIME
|
||||||
time_t file_modified_time;
|
time_t file_modified_time;
|
||||||
|
#endif
|
||||||
|
|
||||||
mz_uint64 local_dir_header_ofs, cur_archive_file_ofs, uncomp_size = 0,
|
mz_uint64 local_dir_header_ofs, cur_archive_file_ofs, uncomp_size = 0,
|
||||||
comp_size = 0;
|
comp_size = 0;
|
||||||
size_t archive_name_size;
|
size_t archive_name_size;
|
||||||
|
@ -6326,10 +6336,12 @@ mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name,
|
||||||
comment_size + archive_name_size) > 0xFFFFFFFF))
|
comment_size + archive_name_size) > 0xFFFFFFFF))
|
||||||
return MZ_FALSE;
|
return MZ_FALSE;
|
||||||
|
|
||||||
|
#ifndef MINIZ_NO_TIME
|
||||||
memset(&file_modified_time, 0, sizeof(file_modified_time));
|
memset(&file_modified_time, 0, sizeof(file_modified_time));
|
||||||
if (!mz_zip_get_file_modified_time(pSrc_filename, &file_modified_time))
|
if (!mz_zip_get_file_modified_time(pSrc_filename, &file_modified_time))
|
||||||
return MZ_FALSE;
|
return MZ_FALSE;
|
||||||
mz_zip_time_t_to_dos_time(file_modified_time, &dos_time, &dos_date);
|
mz_zip_time_t_to_dos_time(file_modified_time, &dos_time, &dos_date);
|
||||||
|
#endif
|
||||||
|
|
||||||
pSrc_file = MZ_FOPEN(pSrc_filename, "rb");
|
pSrc_file = MZ_FOPEN(pSrc_filename, "rb");
|
||||||
if (!pSrc_file)
|
if (!pSrc_file)
|
||||||
|
@ -6814,6 +6826,10 @@ void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename,
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // #ifndef MINIZ_NO_STDIO
|
#endif // #ifndef MINIZ_NO_STDIO
|
||||||
|
|
||||||
#endif // #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
|
#endif // #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -15,19 +15,11 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma warning(push)
|
|
||||||
#pragma warning(disable : 4127 )
|
|
||||||
#endif //_MSC_VER
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(_SSIZE_T_DEFINED) && !defined(_SSIZE_T_DEFINED_) && \
|
#if !defined(_POSIX_C_SOURCE) && defined(_MSC_VER)
|
||||||
!defined(__DEFINED_ssize_t) && !defined(__ssize_t_defined) && \
|
|
||||||
!defined(_SSIZE_T) && !defined(_SSIZE_T_) && !defined(_SSIZE_T_DECLARED)
|
|
||||||
|
|
||||||
// 64-bit Windows is the only mainstream platform
|
// 64-bit Windows is the only mainstream platform
|
||||||
// where sizeof(long) != sizeof(void*)
|
// where sizeof(long) != sizeof(void*)
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
|
@ -35,15 +27,6 @@ typedef long long ssize_t; /* byte count or error */
|
||||||
#else
|
#else
|
||||||
typedef long ssize_t; /* byte count or error */
|
typedef long ssize_t; /* byte count or error */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define _SSIZE_T_DEFINED
|
|
||||||
#define _SSIZE_T_DEFINED_
|
|
||||||
#define __DEFINED_ssize_t
|
|
||||||
#define __ssize_t_defined
|
|
||||||
#define _SSIZE_T
|
|
||||||
#define _SSIZE_T_
|
|
||||||
#define _SSIZE_T_DECLARED
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef MAX_PATH
|
#ifndef MAX_PATH
|
||||||
|
@ -64,9 +47,49 @@ typedef long ssize_t; /* byte count or error */
|
||||||
/**
|
/**
|
||||||
* Default zip compression level.
|
* Default zip compression level.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define ZIP_DEFAULT_COMPRESSION_LEVEL 6
|
#define ZIP_DEFAULT_COMPRESSION_LEVEL 6
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Error codes
|
||||||
|
*/
|
||||||
|
#define ZIP_ENOINIT -1 // not initialized
|
||||||
|
#define ZIP_EINVENTNAME -2 // invalid entry name
|
||||||
|
#define ZIP_ENOENT -3 // entry not found
|
||||||
|
#define ZIP_EINVMODE -4 // invalid zip mode
|
||||||
|
#define ZIP_EINVLVL -5 // invalid compression level
|
||||||
|
#define ZIP_ENOSUP64 -6 // no zip 64 support
|
||||||
|
#define ZIP_EMEMSET -7 // memset error
|
||||||
|
#define ZIP_EWRTENT -8 // cannot write data to entry
|
||||||
|
#define ZIP_ETDEFLINIT -9 // cannot initialize tdefl compressor
|
||||||
|
#define ZIP_EINVIDX -10 // invalid index
|
||||||
|
#define ZIP_ENOHDR -11 // header not found
|
||||||
|
#define ZIP_ETDEFLBUF -12 // cannot flush tdefl buffer
|
||||||
|
#define ZIP_ECRTHDR -13 // cannot create entry header
|
||||||
|
#define ZIP_EWRTHDR -14 // cannot write entry header
|
||||||
|
#define ZIP_EWRTDIR -15 // cannot write to central dir
|
||||||
|
#define ZIP_EOPNFILE -16 // cannot open file
|
||||||
|
#define ZIP_EINVENTTYPE -17 // invalid entry type
|
||||||
|
#define ZIP_EMEMNOALLOC -18 // extracting data using no memory allocation
|
||||||
|
#define ZIP_ENOFILE -19 // file not found
|
||||||
|
#define ZIP_ENOPERM -20 // no permission
|
||||||
|
#define ZIP_EOOMEM -21 // out of memory
|
||||||
|
#define ZIP_EINVZIPNAME -22 // invalid zip archive name
|
||||||
|
#define ZIP_EMKDIR -23 // make dir error
|
||||||
|
#define ZIP_ESYMLINK -24 // symlink error
|
||||||
|
#define ZIP_ECLSZIP -25 // close archive error
|
||||||
|
#define ZIP_ECAPSIZE -26 // capacity size too small
|
||||||
|
#define ZIP_EFSEEK -27 // fseek error
|
||||||
|
#define ZIP_EFREAD -28 // fread error
|
||||||
|
#define ZIP_EFWRITE -29 // fwrite error
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Looks up the error message string coresponding to an error number.
|
||||||
|
* @param errnum error number
|
||||||
|
* @return error message string coresponding to errnum or NULL if error is not
|
||||||
|
* found.
|
||||||
|
*/
|
||||||
|
extern const char *zip_strerror(int errnum);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @struct zip_t
|
* @struct zip_t
|
||||||
*
|
*
|
||||||
|
@ -242,8 +265,8 @@ extern ssize_t zip_entry_read(struct zip_t *zip, void **buf, size_t *bufsize);
|
||||||
*
|
*
|
||||||
* @note ensure supplied output buffer is large enough.
|
* @note ensure supplied output buffer is large enough.
|
||||||
* zip_entry_size function (returns uncompressed size for the current
|
* zip_entry_size function (returns uncompressed size for the current
|
||||||
* entry) can be handy to estimate how big buffer is needed. for large
|
* entry) can be handy to estimate how big buffer is needed.
|
||||||
* entries, please take a look at zip_entry_extract function.
|
* For large entries, please take a look at zip_entry_extract function.
|
||||||
*
|
*
|
||||||
* @return the return code - the number of bytes actually read on success.
|
* @return the return code - the number of bytes actually read on success.
|
||||||
* Otherwise a -1 on error (e.g. bufsize is not large enough).
|
* Otherwise a -1 on error (e.g. bufsize is not large enough).
|
||||||
|
@ -285,7 +308,71 @@ zip_entry_extract(struct zip_t *zip,
|
||||||
* @return the return code - the number of entries on success, negative number
|
* @return the return code - the number of entries on success, negative number
|
||||||
* (< 0) on error.
|
* (< 0) on error.
|
||||||
*/
|
*/
|
||||||
extern int zip_total_entries(struct zip_t *zip);
|
extern int zip_entries_total(struct zip_t *zip);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes zip archive entries.
|
||||||
|
*
|
||||||
|
* @param zip zip archive handler.
|
||||||
|
* @param entries array of zip archive entries to be deleted.
|
||||||
|
* @param len the number of entries to be deleted.
|
||||||
|
* @return the number of deleted entries, or negative number (< 0) on error.
|
||||||
|
*/
|
||||||
|
extern int zip_entries_delete(struct zip_t *zip, char *const entries[],
|
||||||
|
size_t len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts a zip archive stream into directory.
|
||||||
|
*
|
||||||
|
* If on_extract is not NULL, the callback will be called after
|
||||||
|
* successfully extracted each zip entry.
|
||||||
|
* Returning a negative value from the callback will cause abort and return an
|
||||||
|
* error. The last argument (void *arg) is optional, which you can use to pass
|
||||||
|
* data to the on_extract callback.
|
||||||
|
*
|
||||||
|
* @param stream zip archive stream.
|
||||||
|
* @param size stream size.
|
||||||
|
* @param dir output directory.
|
||||||
|
* @param on_extract on extract callback.
|
||||||
|
* @param arg opaque pointer.
|
||||||
|
*
|
||||||
|
* @return the return code - 0 on success, negative number (< 0) on error.
|
||||||
|
*/
|
||||||
|
extern int zip_stream_extract(const char *stream, size_t size, const char *dir,
|
||||||
|
int (*on_extract)(const char *filename,
|
||||||
|
void *arg),
|
||||||
|
void *arg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens zip archive stream into memory.
|
||||||
|
*
|
||||||
|
* @param stream zip archive stream.
|
||||||
|
* @param size stream size.
|
||||||
|
*
|
||||||
|
* @return the zip archive handler or NULL on error
|
||||||
|
*/
|
||||||
|
extern struct zip_t *zip_stream_open(const char *stream, size_t size, int level,
|
||||||
|
char mode);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy zip archive stream output buffer.
|
||||||
|
*
|
||||||
|
* @param zip zip archive handler.
|
||||||
|
* @param buf output buffer. User should free buf.
|
||||||
|
* @param bufsize output buffer size (in bytes).
|
||||||
|
*
|
||||||
|
* @return copy size
|
||||||
|
*/
|
||||||
|
extern ssize_t zip_stream_copy(struct zip_t *zip, void **buf, ssize_t *bufsize);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close zip archive releases resources.
|
||||||
|
*
|
||||||
|
* @param zip zip archive handler.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
extern void zip_stream_close(struct zip_t *zip);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new archive and puts files into a single zip archive.
|
* Creates a new archive and puts files into a single zip archive.
|
||||||
|
@ -319,11 +406,6 @@ extern int zip_extract(const char *zipname, const char *dir,
|
||||||
void *arg);
|
void *arg);
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma warning(pop)
|
|
||||||
#endif //_MSC_VER
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,11 +1,38 @@
|
||||||
cmake_minimum_required(VERSION 3.10)
|
cmake_minimum_required(VERSION 3.4)
|
||||||
|
|
||||||
# test
|
# tests
|
||||||
set(test_out test.out)
|
set(test_write_out test_write.out)
|
||||||
|
add_executable(${test_write_out} test_write.c)
|
||||||
|
target_link_libraries(${test_write_out} zip)
|
||||||
|
add_test(NAME ${test_write_out} COMMAND ${test_write_out})
|
||||||
|
set(test_write_out ${test_write_out} PARENT_SCOPE)
|
||||||
|
|
||||||
add_executable(${test_out} test.c)
|
set(test_append_out test_append.out)
|
||||||
target_link_libraries(${test_out} zip)
|
add_executable(${test_append_out} test_append.c)
|
||||||
|
target_link_libraries(${test_append_out} zip)
|
||||||
|
add_test(NAME ${test_append_out} COMMAND ${test_append_out})
|
||||||
|
set(test_append_out ${test_append_out} PARENT_SCOPE)
|
||||||
|
|
||||||
add_test(NAME ${test_out} COMMAND ${test_out})
|
set(test_read_out test_read.out)
|
||||||
|
add_executable(${test_read_out} test_read.c)
|
||||||
|
target_link_libraries(${test_read_out} zip)
|
||||||
|
add_test(NAME ${test_read_out} COMMAND ${test_read_out})
|
||||||
|
set(test_read_out ${test_read_out} PARENT_SCOPE)
|
||||||
|
|
||||||
set(test_out ${test_out} PARENT_SCOPE)
|
set(test_extract_out test_extract.out)
|
||||||
|
add_executable(${test_extract_out} test_extract.c)
|
||||||
|
target_link_libraries(${test_extract_out} zip)
|
||||||
|
add_test(NAME ${test_extract_out} COMMAND ${test_extract_out})
|
||||||
|
set(test_extract_out ${test_extract_out} PARENT_SCOPE)
|
||||||
|
|
||||||
|
set(test_entry_out test_entry.out)
|
||||||
|
add_executable(${test_entry_out} test_entry.c)
|
||||||
|
target_link_libraries(${test_entry_out} zip)
|
||||||
|
add_test(NAME ${test_entry_out} COMMAND ${test_entry_out})
|
||||||
|
set(test_entry_out ${test_entry_out} PARENT_SCOPE)
|
||||||
|
|
||||||
|
set(test_permissions_out test_permissions.out)
|
||||||
|
add_executable(${test_permissions_out} test_permissions.c)
|
||||||
|
target_link_libraries(${test_permissions_out} zip)
|
||||||
|
add_test(NAME ${test_permissions_out} COMMAND ${test_permissions_out})
|
||||||
|
set(test_permissions_out ${test_permissions_out} PARENT_SCOPE)
|
||||||
|
|
|
@ -81,6 +81,7 @@ __Exporters__:
|
||||||
- JSON (for WebGl, via https://github.com/acgessler/assimp2json)
|
- JSON (for WebGl, via https://github.com/acgessler/assimp2json)
|
||||||
- ASSBIN
|
- ASSBIN
|
||||||
- STEP
|
- STEP
|
||||||
|
- [PBRTv4](https://github.com/mmp/pbrt-v4)
|
||||||
- glTF 1.0 (partial)
|
- glTF 1.0 (partial)
|
||||||
- glTF 2.0 (partial)
|
- glTF 2.0 (partial)
|
||||||
- 3MF ( experimental )
|
- 3MF ( experimental )
|
||||||
|
|
|
@ -51,10 +51,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include "Exceptional.h"
|
#include "Exceptional.h"
|
||||||
|
|
||||||
#include <assimp/ai_assert.h>
|
|
||||||
#include <assimp/types.h>
|
#include <assimp/types.h>
|
||||||
#include <assimp/ProgressHandler.hpp>
|
#include <assimp/ProgressHandler.hpp>
|
||||||
#include <map>
|
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
@ -179,42 +177,10 @@ public:
|
||||||
/**
|
/**
|
||||||
* Will be called only by scale process when scaling is requested.
|
* Will be called only by scale process when scaling is requested.
|
||||||
*/
|
*/
|
||||||
virtual void SetFileScale(double scale) {
|
void SetFileScale(double scale) {
|
||||||
fileScale = scale;
|
fileScale = scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual double GetFileScale() const {
|
|
||||||
return fileScale;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum ImporterUnits {
|
|
||||||
M,
|
|
||||||
MM,
|
|
||||||
CM,
|
|
||||||
INCHES,
|
|
||||||
FEET
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Assimp Importer
|
|
||||||
* unit conversions available
|
|
||||||
* NOTE: Valid options are initialised in the
|
|
||||||
* constructor in the implementation file to
|
|
||||||
* work around a VS2013 compiler bug if support
|
|
||||||
* for that compiler is dropped in the future
|
|
||||||
* initialisation can be moved back here
|
|
||||||
* */
|
|
||||||
std::map<ImporterUnits, double> importerUnits;
|
|
||||||
|
|
||||||
virtual void SetApplicationUnits(const ImporterUnits &unit) {
|
|
||||||
importerScale = importerUnits[unit];
|
|
||||||
applicationUnits = unit;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual const ImporterUnits &GetApplicationUnits() {
|
|
||||||
return applicationUnits;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Called by #Importer::GetExtensionList for each loaded importer.
|
/** Called by #Importer::GetExtensionList for each loaded importer.
|
||||||
* Take the extension list contained in the structure returned by
|
* Take the extension list contained in the structure returned by
|
||||||
|
@ -223,7 +189,6 @@ public:
|
||||||
void GetExtensionList(std::set<std::string> &extensions);
|
void GetExtensionList(std::set<std::string> &extensions);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ImporterUnits applicationUnits = ImporterUnits::M;
|
|
||||||
double importerScale = 1.0;
|
double importerScale = 1.0;
|
||||||
double fileScale = 1.0;
|
double fileScale = 1.0;
|
||||||
|
|
||||||
|
@ -420,7 +385,7 @@ public: // static utilities
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/* Pushes state into importer for the importer scale */
|
/* Pushes state into importer for the importer scale */
|
||||||
virtual void UpdateImporterScale(Importer *pImp);
|
void UpdateImporterScale(Importer *pImp);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// Error description in case there was one.
|
/// Error description in case there was one.
|
||||||
|
|
|
@ -119,7 +119,7 @@ private:
|
||||||
AI_FORCE_INLINE
|
AI_FORCE_INLINE
|
||||||
DefaultIOStream::DefaultIOStream() AI_NO_EXCEPT
|
DefaultIOStream::DefaultIOStream() AI_NO_EXCEPT
|
||||||
: mFile(nullptr)
|
: mFile(nullptr)
|
||||||
, mFilename("")
|
, mFilename()
|
||||||
, mCachedSize(SIZE_MAX) {
|
, mCachedSize(SIZE_MAX) {
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
|
@ -294,7 +294,7 @@ bool IOSystem::PushDirectory( const std::string &path ) {
|
||||||
AI_FORCE_INLINE
|
AI_FORCE_INLINE
|
||||||
const std::string &IOSystem::CurrentDirectory() const {
|
const std::string &IOSystem::CurrentDirectory() const {
|
||||||
if ( m_pathStack.empty() ) {
|
if ( m_pathStack.empty() ) {
|
||||||
static const std::string Dummy("");
|
static const std::string Dummy;
|
||||||
return Dummy;
|
return Dummy;
|
||||||
}
|
}
|
||||||
return m_pathStack[ m_pathStack.size()-1 ];
|
return m_pathStack[ m_pathStack.size()-1 ];
|
||||||
|
|
|
@ -286,7 +286,7 @@ public:
|
||||||
* @see GetPropertyInteger()
|
* @see GetPropertyInteger()
|
||||||
*/
|
*/
|
||||||
std::string GetPropertyString(const char *szName,
|
std::string GetPropertyString(const char *szName,
|
||||||
const std::string &sErrorReturn = "") const;
|
const std::string &sErrorReturn = std::string()) const;
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** Get a matrix configuration property
|
/** Get a matrix configuration property
|
||||||
|
|
|
@ -262,7 +262,7 @@ AI_FORCE_INLINE unsigned int tokenize(const string_type &str, std::vector<string
|
||||||
inline std::string ai_stdStrToLower(const std::string &str) {
|
inline std::string ai_stdStrToLower(const std::string &str) {
|
||||||
std::string out(str);
|
std::string out(str);
|
||||||
for (size_t i = 0; i < str.size(); ++i) {
|
for (size_t i = 0; i < str.size(); ++i) {
|
||||||
out[i] = (char) tolower(out[i]);
|
out[i] = (char) tolower((unsigned char)out[i]);
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
|
@ -146,8 +146,8 @@ inline int ASSIMP_stricmp(const char *s1, const char *s2) {
|
||||||
#else
|
#else
|
||||||
char c1, c2;
|
char c1, c2;
|
||||||
do {
|
do {
|
||||||
c1 = tolower(*s1++);
|
c1 = tolower((unsigned char)*(s1++));
|
||||||
c2 = tolower(*s2++);
|
c2 = tolower((unsigned char)*(s2++));
|
||||||
} while (c1 && (c1 == c2));
|
} while (c1 && (c1 == c2));
|
||||||
return c1 - c2;
|
return c1 - c2;
|
||||||
#endif
|
#endif
|
||||||
|
@ -197,8 +197,8 @@ inline int ASSIMP_strincmp(const char *s1, const char *s2, unsigned int n) {
|
||||||
unsigned int p = 0;
|
unsigned int p = 0;
|
||||||
do {
|
do {
|
||||||
if (p++ >= n) return 0;
|
if (p++ >= n) return 0;
|
||||||
c1 = tolower(*s1++);
|
c1 = tolower((unsigned char)*(s1++));
|
||||||
c2 = tolower(*s2++);
|
c2 = tolower((unsigned char)*(s2++));
|
||||||
} while (c1 && (c1 == c2));
|
} while (c1 && (c1 == c2));
|
||||||
|
|
||||||
return c1 - c2;
|
return c1 - c2;
|
||||||
|
|
|
@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
|
||||||
|
|
||||||
Copyright (c) 2006-2021, assimp team
|
Copyright (c) 2006-2021, assimp team
|
||||||
|
|
||||||
|
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use of this software in source and binary forms,
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
@ -55,6 +54,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <locale>
|
#include <locale>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <iomanip>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#define AI_SIZEFMT "%Iu"
|
#define AI_SIZEFMT "%Iu"
|
||||||
|
@ -157,7 +157,7 @@ AI_FORCE_INLINE std::string ai_decimal_to_hexa(T toConvert) {
|
||||||
ss >> result;
|
ss >> result;
|
||||||
|
|
||||||
for (size_t i = 0; i < result.size(); ++i) {
|
for (size_t i = 0; i < result.size(); ++i) {
|
||||||
result[i] = (char)toupper(result[i]);
|
result[i] = (char)toupper((unsigned char)result[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -177,7 +177,7 @@ AI_FORCE_INLINE std::string ai_rgba2hex(int r, int g, int b, int a, bool with_he
|
||||||
if (with_head) {
|
if (with_head) {
|
||||||
ss << "#";
|
ss << "#";
|
||||||
}
|
}
|
||||||
ss << std::hex << (r << 24 | g << 16 | b << 8 | a);
|
ss << std::hex << std::setfill('0') << std::setw(8) << (r << 24 | g << 16 | b << 8 | a);
|
||||||
|
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
@ -249,4 +249,31 @@ AI_FORCE_INLINE std::string ai_str_toupper(const std::string &in) {
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
// ---------------------------------------------------------------------------------
|
||||||
|
/// @brief Make a string printable by replacing all non-printable characters with
|
||||||
|
/// the specified placeholder character.
|
||||||
|
/// @param in The incoming string.
|
||||||
|
/// @param placeholder Placeholder character, default is a question mark.
|
||||||
|
/// @return The string, with all non-printable characters replaced.
|
||||||
|
AI_FORCE_INLINE std::string ai_str_toprintable(const std::string &in, char placeholder = '?') {
|
||||||
|
std::string out(in);
|
||||||
|
std::transform(out.begin(), out.end(), out.begin(), [placeholder] (unsigned char c) {
|
||||||
|
return isprint(c) ? (char)c : placeholder;
|
||||||
|
});
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------
|
||||||
|
/// @brief Make a string printable by replacing all non-printable characters with
|
||||||
|
/// the specified placeholder character.
|
||||||
|
/// @param in The incoming string.
|
||||||
|
/// @param len The length of the incoming string.
|
||||||
|
/// @param placeholder Placeholder character, default is a question mark.
|
||||||
|
/// @return The string, with all non-printable characters replaced. Will return an
|
||||||
|
/// empty string if in is null or len is <= 0.
|
||||||
|
AI_FORCE_INLINE std::string ai_str_toprintable(const char *in, int len, char placeholder = '?') {
|
||||||
|
return (in && len > 0) ? ai_str_toprintable(std::string(in, len), placeholder) : std::string();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // INCLUDED_AI_STRINGUTILS_H
|
||||||
|
|
|
@ -43,8 +43,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#define INCLUDED_AI_IRRXML_WRAPPER
|
#define INCLUDED_AI_IRRXML_WRAPPER
|
||||||
|
|
||||||
#include <assimp/DefaultLogger.hpp>
|
#include <assimp/DefaultLogger.hpp>
|
||||||
|
#include <assimp/ai_assert.h>
|
||||||
|
|
||||||
#include "BaseImporter.h"
|
#include "BaseImporter.h"
|
||||||
#include "IOStream.hpp"
|
#include "IOStream.hpp"
|
||||||
|
|
||||||
#include <pugixml.hpp>
|
#include <pugixml.hpp>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -136,7 +139,9 @@ public:
|
||||||
if (parse_result.status == pugi::status_ok) {
|
if (parse_result.status == pugi::status_ok) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
ASSIMP_LOG_DEBUG("Error while parse xml.");
|
std::ostringstream oss;
|
||||||
|
oss << "Error while parsing XML: " << parse_result.description() << " @ " << parse_result.offset;
|
||||||
|
ASSIMP_LOG_DEBUG(oss.str());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -239,7 +244,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool getValueAsString( XmlNode &node, std::string &text ) {
|
static inline bool getValueAsString( XmlNode &node, std::string &text ) {
|
||||||
text = "";
|
text = std::string();
|
||||||
if (node.empty()) {
|
if (node.empty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include "StringComparison.h"
|
#include "StringComparison.h"
|
||||||
#include <assimp/DefaultLogger.hpp>
|
#include <assimp/DefaultLogger.hpp>
|
||||||
#include <assimp/Exceptional.h>
|
#include <assimp/Exceptional.h>
|
||||||
|
#include <assimp/StringUtils.h>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
# include <stdint.h>
|
# include <stdint.h>
|
||||||
|
@ -193,7 +194,7 @@ uint64_t strtoul10_64( const char* in, const char** out=0, unsigned int* max_ino
|
||||||
|
|
||||||
if ( *in < '0' || *in > '9' ) {
|
if ( *in < '0' || *in > '9' ) {
|
||||||
// The string is known to be bad, so don't risk printing the whole thing.
|
// The string is known to be bad, so don't risk printing the whole thing.
|
||||||
throw ExceptionType("The string \"", std::string(in).substr(0, 100), "\" cannot be converted into a value." );
|
throw ExceptionType("The string \"", ai_str_toprintable(in, 30), "\" cannot be converted into a value." );
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( ;; ) {
|
for ( ;; ) {
|
||||||
|
@ -293,7 +294,7 @@ const char* fast_atoreal_move(const char* c, Real& out, bool check_comma = true)
|
||||||
if (!(c[0] >= '0' && c[0] <= '9') &&
|
if (!(c[0] >= '0' && c[0] <= '9') &&
|
||||||
!((c[0] == '.' || (check_comma && c[0] == ',')) && c[1] >= '0' && c[1] <= '9')) {
|
!((c[0] == '.' || (check_comma && c[0] == ',')) && c[1] >= '0' && c[1] <= '9')) {
|
||||||
// The string is known to be bad, so don't risk printing the whole thing.
|
// The string is known to be bad, so don't risk printing the whole thing.
|
||||||
throw ExceptionType("Cannot parse string \"", std::string(c).substr(0, 100),
|
throw ExceptionType("Cannot parse string \"", ai_str_toprintable(c, 30),
|
||||||
"\" as a real number: does not start with digit "
|
"\" as a real number: does not start with digit "
|
||||||
"or decimal point followed by digit.");
|
"or decimal point followed by digit.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#-*- coding: utf-8 -*-
|
#-*- coding: utf-8 -*-
|
||||||
|
|
||||||
from ctypes import POINTER, c_void_p, c_uint, c_char, c_float, Structure, c_char_p, c_double, c_ubyte, c_size_t, c_uint32
|
from ctypes import POINTER, c_void_p, c_uint, c_char, c_float, Structure, c_double, c_ubyte, c_size_t, c_uint32
|
||||||
|
|
||||||
|
|
||||||
class Vector2D(Structure):
|
class Vector2D(Structure):
|
||||||
|
@ -1121,7 +1121,7 @@ class Scene(Structure):
|
||||||
("mMetadata", POINTER(Metadata)),
|
("mMetadata", POINTER(Metadata)),
|
||||||
|
|
||||||
# Internal data, do not touch
|
# Internal data, do not touch
|
||||||
("mPrivate", c_char_p),
|
("mPrivate", POINTER(c_char)),
|
||||||
]
|
]
|
||||||
|
|
||||||
assimp_structs_as_tuple = (Matrix4x4,
|
assimp_structs_as_tuple = (Matrix4x4,
|
||||||
|
|
|
@ -42,22 +42,12 @@ void ModelLoader::Draw(ID3D11DeviceContext * devcon) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string textype;
|
|
||||||
|
|
||||||
Mesh ModelLoader::processMesh(aiMesh * mesh, const aiScene * scene) {
|
Mesh ModelLoader::processMesh(aiMesh * mesh, const aiScene * scene) {
|
||||||
// Data to fill
|
// Data to fill
|
||||||
std::vector<VERTEX> vertices;
|
std::vector<VERTEX> vertices;
|
||||||
std::vector<UINT> indices;
|
std::vector<UINT> indices;
|
||||||
std::vector<Texture> textures;
|
std::vector<Texture> textures;
|
||||||
|
|
||||||
if (mesh->mMaterialIndex >= 0) {
|
|
||||||
aiMaterial* mat = scene->mMaterials[mesh->mMaterialIndex];
|
|
||||||
|
|
||||||
if (textype.empty()) {
|
|
||||||
textype = determineTextureType(scene, mat);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Walk through each of the mesh's vertices
|
// Walk through each of the mesh's vertices
|
||||||
for (UINT i = 0; i < mesh->mNumVertices; i++) {
|
for (UINT i = 0; i < mesh->mNumVertices; i++) {
|
||||||
VERTEX vertex;
|
VERTEX vertex;
|
||||||
|
@ -108,9 +98,10 @@ std::vector<Texture> ModelLoader::loadMaterialTextures(aiMaterial * mat, aiTextu
|
||||||
if (!skip) { // If texture hasn't been loaded already, load it
|
if (!skip) { // If texture hasn't been loaded already, load it
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
Texture texture;
|
Texture texture;
|
||||||
if (textype == "embedded compressed texture") {
|
|
||||||
int textureindex = getTextureIndex(&str);
|
const aiTexture* embeddedTexture = scene->GetEmbeddedTexture(str.C_Str());
|
||||||
texture.texture = getTextureFromModel(scene, textureindex);
|
if (embeddedTexture != nullptr) {
|
||||||
|
texture.texture = loadEmbeddedTexture(embeddedTexture);
|
||||||
} else {
|
} else {
|
||||||
std::string filename = std::string(str.C_Str());
|
std::string filename = std::string(str.C_Str());
|
||||||
filename = directory_ + '/' + filename;
|
filename = directory_ + '/' + filename;
|
||||||
|
@ -148,38 +139,46 @@ void ModelLoader::processNode(aiNode * node, const aiScene * scene) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ModelLoader::determineTextureType(const aiScene * scene, aiMaterial * mat) {
|
ID3D11ShaderResourceView * ModelLoader::loadEmbeddedTexture(const aiTexture* embeddedTexture) {
|
||||||
aiString textypeStr;
|
|
||||||
mat->GetTexture(aiTextureType_DIFFUSE, 0, &textypeStr);
|
|
||||||
std::string textypeteststr = textypeStr.C_Str();
|
|
||||||
if (textypeteststr == "*0" || textypeteststr == "*1" || textypeteststr == "*2" || textypeteststr == "*3" || textypeteststr == "*4" || textypeteststr == "*5") {
|
|
||||||
if (scene->mTextures[0]->mHeight == 0) {
|
|
||||||
return "embedded compressed texture";
|
|
||||||
} else {
|
|
||||||
return "embedded non-compressed texture";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (textypeteststr.find('.') != std::string::npos) {
|
|
||||||
return "textures are on disk";
|
|
||||||
}
|
|
||||||
|
|
||||||
return ".";
|
|
||||||
}
|
|
||||||
|
|
||||||
int ModelLoader::getTextureIndex(aiString * str) {
|
|
||||||
std::string tistr;
|
|
||||||
tistr = str->C_Str();
|
|
||||||
tistr = tistr.substr(1);
|
|
||||||
return stoi(tistr);
|
|
||||||
}
|
|
||||||
|
|
||||||
ID3D11ShaderResourceView * ModelLoader::getTextureFromModel(const aiScene * scene, int textureindex) {
|
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
ID3D11ShaderResourceView *texture;
|
ID3D11ShaderResourceView *texture = nullptr;
|
||||||
|
|
||||||
int* size = reinterpret_cast<int*>(&scene->mTextures[textureindex]->mWidth);
|
if (embeddedTexture->mHeight != 0) {
|
||||||
|
// Load an uncompressed ARGB8888 embedded texture
|
||||||
|
D3D11_TEXTURE2D_DESC desc;
|
||||||
|
desc.Width = embeddedTexture->mWidth;
|
||||||
|
desc.Height = embeddedTexture->mHeight;
|
||||||
|
desc.MipLevels = 1;
|
||||||
|
desc.ArraySize = 1;
|
||||||
|
desc.SampleDesc.Count = 1;
|
||||||
|
desc.SampleDesc.Quality = 0;
|
||||||
|
desc.Usage = D3D11_USAGE_DEFAULT;
|
||||||
|
desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
|
||||||
|
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||||
|
desc.CPUAccessFlags = 0;
|
||||||
|
desc.MiscFlags = 0;
|
||||||
|
|
||||||
hr = CreateWICTextureFromMemory(dev_, devcon_, reinterpret_cast<unsigned char*>(scene->mTextures[textureindex]->pcData), *size, nullptr, &texture);
|
D3D11_SUBRESOURCE_DATA subresourceData;
|
||||||
|
subresourceData.pSysMem = embeddedTexture->pcData;
|
||||||
|
subresourceData.SysMemPitch = embeddedTexture->mWidth * 4;
|
||||||
|
subresourceData.SysMemSlicePitch = embeddedTexture->mWidth * embeddedTexture->mHeight * 4;
|
||||||
|
|
||||||
|
ID3D11Texture2D *texture2D = nullptr;
|
||||||
|
hr = dev_->CreateTexture2D(&desc, &subresourceData, &texture2D);
|
||||||
|
if (FAILED(hr))
|
||||||
|
MessageBox(hwnd_, "CreateTexture2D failed!", "Error!", MB_ICONERROR | MB_OK);
|
||||||
|
|
||||||
|
hr = dev_->CreateShaderResourceView(texture2D, nullptr, &texture);
|
||||||
|
if (FAILED(hr))
|
||||||
|
MessageBox(hwnd_, "CreateShaderResourceView failed!", "Error!", MB_ICONERROR | MB_OK);
|
||||||
|
|
||||||
|
return texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
// mHeight is 0, so try to load a compressed texture of mWidth bytes
|
||||||
|
const size_t size = embeddedTexture->mWidth;
|
||||||
|
|
||||||
|
hr = CreateWICTextureFromMemory(dev_, devcon_, reinterpret_cast<const unsigned char*>(embeddedTexture->pcData), size, nullptr, &texture);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
MessageBox(hwnd_, "Texture couldn't be created from memory!", "Error!", MB_ICONERROR | MB_OK);
|
MessageBox(hwnd_, "Texture couldn't be created from memory!", "Error!", MB_ICONERROR | MB_OK);
|
||||||
|
|
||||||
|
|
|
@ -35,9 +35,7 @@ private:
|
||||||
void processNode(aiNode* node, const aiScene* scene);
|
void processNode(aiNode* node, const aiScene* scene);
|
||||||
Mesh processMesh(aiMesh* mesh, const aiScene* scene);
|
Mesh processMesh(aiMesh* mesh, const aiScene* scene);
|
||||||
std::vector<Texture> loadMaterialTextures(aiMaterial* mat, aiTextureType type, std::string typeName, const aiScene* scene);
|
std::vector<Texture> loadMaterialTextures(aiMaterial* mat, aiTextureType type, std::string typeName, const aiScene* scene);
|
||||||
std::string determineTextureType(const aiScene* scene, aiMaterial* mat);
|
ID3D11ShaderResourceView* loadEmbeddedTexture(const aiTexture* embeddedTexture);
|
||||||
int getTextureIndex(aiString* str);
|
|
||||||
ID3D11ShaderResourceView* getTextureFromModel(const aiScene* scene, int textureindex);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // !MODEL_LOADER_H
|
#endif // !MODEL_LOADER_H
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue