commit
ccc0a50d96
|
@ -55,6 +55,8 @@ namespace XmlTag {
|
|||
static const std::string resources = "resources";
|
||||
static const std::string object = "object";
|
||||
static const std::string mesh = "mesh";
|
||||
static const std::string components = "components";
|
||||
static const std::string component = "component";
|
||||
static const std::string vertices = "vertices";
|
||||
static const std::string vertex = "vertex";
|
||||
static const std::string triangles = "triangles";
|
||||
|
@ -67,6 +69,7 @@ namespace XmlTag {
|
|||
static const std::string v3 = "v3";
|
||||
static const std::string id = "id";
|
||||
static const std::string pid = "pid";
|
||||
static const std::string pindex = "pindex";
|
||||
static const std::string p1 = "p1";
|
||||
static const std::string name = "name";
|
||||
static const std::string type = "type";
|
||||
|
|
|
@ -137,7 +137,7 @@ bool D3MFExporter::exportContentTypes() {
|
|||
mContentOutput << std::endl;
|
||||
mContentOutput << "</Types>";
|
||||
mContentOutput << std::endl;
|
||||
exportContentTyp(XmlTag::CONTENT_TYPES_ARCHIVE);
|
||||
zipContentType(XmlTag::CONTENT_TYPES_ARCHIVE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -162,7 +162,7 @@ bool D3MFExporter::exportRelations() {
|
|||
mRelOutput << "</Relationships>";
|
||||
mRelOutput << std::endl;
|
||||
|
||||
writeRelInfoToFile("_rels", ".rels");
|
||||
zipRelInfo("_rels", ".rels");
|
||||
mRelOutput.flush();
|
||||
|
||||
return true;
|
||||
|
@ -196,7 +196,7 @@ bool D3MFExporter::export3DModel() {
|
|||
info->type = XmlTag::PACKAGE_START_PART_RELATIONSHIP_TYPE;
|
||||
mRelations.push_back(info);
|
||||
|
||||
writeModelToArchive("3D", "3DModel.model");
|
||||
zipModel("3D", "3DModel.model");
|
||||
mModelOutput.flush();
|
||||
|
||||
return true;
|
||||
|
@ -357,42 +357,27 @@ void D3MFExporter::writeBuild() {
|
|||
mModelOutput << std::endl;
|
||||
}
|
||||
|
||||
void D3MFExporter::exportContentTyp(const std::string &filename) {
|
||||
if (nullptr == m_zipArchive) {
|
||||
throw DeadlyExportError("3MF-Export: Zip archive not valid, nullptr.");
|
||||
}
|
||||
const std::string entry = filename;
|
||||
zip_entry_open(m_zipArchive, entry.c_str());
|
||||
|
||||
const std::string &exportTxt(mContentOutput.str());
|
||||
zip_entry_write(m_zipArchive, exportTxt.c_str(), exportTxt.size());
|
||||
|
||||
zip_entry_close(m_zipArchive);
|
||||
void D3MFExporter::zipContentType(const std::string &filename) {
|
||||
addFileInZip(filename, mContentOutput.str());
|
||||
}
|
||||
|
||||
void D3MFExporter::writeModelToArchive(const std::string &folder, const std::string &modelName) {
|
||||
if (nullptr == m_zipArchive) {
|
||||
throw DeadlyExportError("3MF-Export: Zip archive not valid, nullptr.");
|
||||
}
|
||||
void D3MFExporter::zipModel(const std::string &folder, const std::string &modelName) {
|
||||
const std::string entry = folder + "/" + modelName;
|
||||
zip_entry_open(m_zipArchive, entry.c_str());
|
||||
|
||||
const std::string &exportTxt(mModelOutput.str());
|
||||
zip_entry_write(m_zipArchive, exportTxt.c_str(), exportTxt.size());
|
||||
|
||||
zip_entry_close(m_zipArchive);
|
||||
addFileInZip(entry, mModelOutput.str());
|
||||
}
|
||||
|
||||
void D3MFExporter::writeRelInfoToFile(const std::string &folder, const std::string &relName) {
|
||||
void D3MFExporter::zipRelInfo(const std::string &folder, const std::string &relName) {
|
||||
const std::string entry = folder + "/" + relName;
|
||||
addFileInZip(entry, mRelOutput.str());
|
||||
}
|
||||
|
||||
void D3MFExporter::addFileInZip(const std::string& entry, const std::string& content) {
|
||||
if (nullptr == m_zipArchive) {
|
||||
throw DeadlyExportError("3MF-Export: Zip archive not valid, nullptr.");
|
||||
}
|
||||
const std::string entry = folder + "/" + relName;
|
||||
|
||||
zip_entry_open(m_zipArchive, entry.c_str());
|
||||
|
||||
const std::string &exportTxt(mRelOutput.str());
|
||||
zip_entry_write(m_zipArchive, exportTxt.c_str(), exportTxt.size());
|
||||
|
||||
zip_entry_write(m_zipArchive, content.c_str(), content.size());
|
||||
zip_entry_close(m_zipArchive);
|
||||
}
|
||||
|
||||
|
|
|
@ -82,9 +82,12 @@ protected:
|
|||
void writeVertex( const aiVector3D &pos );
|
||||
void writeFaces( aiMesh *mesh, unsigned int matIdx );
|
||||
void writeBuild();
|
||||
void exportContentTyp( const std::string &filename );
|
||||
void writeModelToArchive( const std::string &folder, const std::string &modelName );
|
||||
void writeRelInfoToFile( const std::string &folder, const std::string &relName );
|
||||
|
||||
// Zip the data
|
||||
void zipContentType( const std::string &filename );
|
||||
void zipModel( const std::string &folder, const std::string &modelName );
|
||||
void zipRelInfo( const std::string &folder, const std::string &relName );
|
||||
void addFileInZip( const std::string &entry, const std::string &content );
|
||||
|
||||
private:
|
||||
std::string mArchiveName;
|
||||
|
|
|
@ -66,22 +66,79 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
namespace Assimp {
|
||||
namespace D3MF {
|
||||
|
||||
enum class ResourceType {
|
||||
RT_Object,
|
||||
RT_BaseMaterials,
|
||||
RT_Unknown
|
||||
}; // To be extended with other resource types (eg. material extension resources like Texture2d, Texture2dGroup...)
|
||||
|
||||
class Resource
|
||||
{
|
||||
public:
|
||||
Resource(int id) :
|
||||
mId(id) {}
|
||||
|
||||
virtual ~Resource() {}
|
||||
|
||||
int mId;
|
||||
|
||||
virtual ResourceType getType() {
|
||||
return ResourceType::RT_Unknown;
|
||||
}
|
||||
};
|
||||
|
||||
class BaseMaterials : public Resource {
|
||||
public:
|
||||
BaseMaterials(int id) :
|
||||
Resource(id),
|
||||
mMaterials(),
|
||||
mMaterialIndex() {}
|
||||
|
||||
std::vector<aiMaterial *> mMaterials;
|
||||
std::vector<unsigned int> mMaterialIndex;
|
||||
|
||||
virtual ResourceType getType() {
|
||||
return ResourceType::RT_BaseMaterials;
|
||||
}
|
||||
};
|
||||
|
||||
struct Component {
|
||||
int mObjectId;
|
||||
aiMatrix4x4 mTransformation;
|
||||
};
|
||||
|
||||
class Object : public Resource {
|
||||
public:
|
||||
std::vector<aiMesh*> mMeshes;
|
||||
std::vector<unsigned int> mMeshIndex;
|
||||
std::vector<Component> mComponents;
|
||||
std::string mName;
|
||||
|
||||
Object(int id) :
|
||||
Resource(id),
|
||||
mName (std::string("Object_") + to_string(id)){}
|
||||
|
||||
virtual ResourceType getType() {
|
||||
return ResourceType::RT_Object;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class XmlSerializer {
|
||||
public:
|
||||
using MatArray = std::vector<aiMaterial *>;
|
||||
using MatId2MatArray = std::map<unsigned int, std::vector<unsigned int>>;
|
||||
|
||||
XmlSerializer(XmlParser *xmlParser) :
|
||||
mMeshes(),
|
||||
mMatArray(),
|
||||
mActiveMatGroup(99999999),
|
||||
mMatId2MatArray(),
|
||||
mResourcesDictionnary(),
|
||||
mMaterialCount(0),
|
||||
mMeshCount(0),
|
||||
mXmlParser(xmlParser) {
|
||||
// empty
|
||||
}
|
||||
|
||||
~XmlSerializer() {
|
||||
// empty
|
||||
for (auto it = mResourcesDictionnary.begin(); it != mResourcesDictionnary.end(); it++) {
|
||||
delete it->second;
|
||||
}
|
||||
}
|
||||
|
||||
void ImportXml(aiScene *scene) {
|
||||
|
@ -89,10 +146,8 @@ public:
|
|||
return;
|
||||
}
|
||||
|
||||
scene->mRootNode = new aiNode();
|
||||
std::vector<aiNode *> children;
|
||||
scene->mRootNode = new aiNode("3MF");
|
||||
|
||||
std::string nodeName;
|
||||
XmlNode node = mXmlParser->getRootNode().child("model");
|
||||
if (node.empty()) {
|
||||
return;
|
||||
|
@ -101,9 +156,7 @@ public:
|
|||
for (XmlNode currentNode = resNode.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
|
||||
const std::string ¤tNodeName = currentNode.name();
|
||||
if (currentNodeName == D3MF::XmlTag::object) {
|
||||
children.push_back(ReadObject(currentNode, scene));
|
||||
} else if (currentNodeName == D3MF::XmlTag::build) {
|
||||
//
|
||||
ReadObject(currentNode);;
|
||||
} else if (currentNodeName == D3MF::XmlTag::basematerials) {
|
||||
ReadBaseMaterials(currentNode);
|
||||
} else if (currentNodeName == D3MF::XmlTag::meta) {
|
||||
|
@ -111,10 +164,29 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
if (scene->mRootNode->mName.length == 0) {
|
||||
scene->mRootNode->mName.Set("3MF");
|
||||
XmlNode buildNode = node.child("build");
|
||||
for (XmlNode currentNode = buildNode.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
|
||||
const std::string ¤tNodeName = currentNode.name();
|
||||
if (currentNodeName == D3MF::XmlTag::item) {
|
||||
int objectId = -1;
|
||||
std::string transformationMatrixStr;
|
||||
aiMatrix4x4 transformationMatrix;
|
||||
getNodeAttribute(currentNode, D3MF::XmlTag::objectid, objectId);
|
||||
bool hasTransform = getNodeAttribute(currentNode, D3MF::XmlTag::transform, transformationMatrixStr);
|
||||
|
||||
auto it = mResourcesDictionnary.find(objectId);
|
||||
if (it != mResourcesDictionnary.end() && it->second->getType() == ResourceType::RT_Object) {
|
||||
Object *obj = static_cast<Object *>(it->second);
|
||||
if (hasTransform) {
|
||||
transformationMatrix = parseTransformMatrix(transformationMatrixStr);
|
||||
}
|
||||
|
||||
addObjectToNode(scene->mRootNode, obj, transformationMatrix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// import the metadata
|
||||
if (!mMetaData.empty()) {
|
||||
const size_t numMeta(mMetaData.size());
|
||||
|
@ -126,66 +198,177 @@ public:
|
|||
}
|
||||
|
||||
// import the meshes
|
||||
scene->mNumMeshes = static_cast<unsigned int>(mMeshes.size());
|
||||
scene->mMeshes = new aiMesh *[scene->mNumMeshes]();
|
||||
std::copy(mMeshes.begin(), mMeshes.end(), scene->mMeshes);
|
||||
scene->mNumMeshes = static_cast<unsigned int>(mMeshCount);
|
||||
if (scene->mNumMeshes != 0) {
|
||||
scene->mMeshes = new aiMesh *[scene->mNumMeshes]();
|
||||
for (auto it = mResourcesDictionnary.begin(); it != mResourcesDictionnary.end(); it++) {
|
||||
if (it->second->getType() == ResourceType::RT_Object) {
|
||||
Object *obj = static_cast<Object*>(it->second);
|
||||
for (unsigned int i = 0; i < obj->mMeshes.size(); ++i) {
|
||||
scene->mMeshes[obj->mMeshIndex[i]] = obj->mMeshes[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// import the materials
|
||||
scene->mNumMaterials = static_cast<unsigned int>(mMatArray.size());
|
||||
if (0 != scene->mNumMaterials) {
|
||||
scene->mNumMaterials = static_cast<unsigned int>(mMaterialCount);
|
||||
if (scene->mNumMaterials != 0) {
|
||||
scene->mMaterials = new aiMaterial *[scene->mNumMaterials];
|
||||
std::copy(mMatArray.begin(), mMatArray.end(), scene->mMaterials);
|
||||
for (auto it = mResourcesDictionnary.begin(); it != mResourcesDictionnary.end(); it++) {
|
||||
if (it->second->getType() == ResourceType::RT_BaseMaterials) {
|
||||
BaseMaterials *baseMaterials = static_cast<BaseMaterials *>(it->second);
|
||||
for (unsigned int i = 0; i < baseMaterials->mMaterials.size(); ++i) {
|
||||
scene->mMaterials[baseMaterials->mMaterialIndex[i]] = baseMaterials->mMaterials[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// create the scene-graph
|
||||
scene->mRootNode->mNumChildren = static_cast<unsigned int>(children.size());
|
||||
scene->mRootNode->mChildren = new aiNode *[scene->mRootNode->mNumChildren]();
|
||||
std::copy(children.begin(), children.end(), scene->mRootNode->mChildren);
|
||||
}
|
||||
|
||||
private:
|
||||
aiNode *ReadObject(XmlNode &node, aiScene *scene) {
|
||||
std::unique_ptr<aiNode> nodePtr(new aiNode());
|
||||
|
||||
std::vector<unsigned long> meshIds;
|
||||
void addObjectToNode(aiNode* parent, Object* obj, aiMatrix4x4 nodeTransform) {
|
||||
aiNode *sceneNode = new aiNode(obj->mName);
|
||||
sceneNode->mNumMeshes = static_cast<unsigned int>(obj->mMeshes.size());
|
||||
sceneNode->mMeshes = new unsigned int[sceneNode->mNumMeshes];
|
||||
std::copy(obj->mMeshIndex.begin(), obj->mMeshIndex.end(), sceneNode->mMeshes);
|
||||
|
||||
std::string name, type;
|
||||
pugi::xml_attribute attr = node.attribute(D3MF::XmlTag::id.c_str());
|
||||
if (!attr.empty()) {
|
||||
name = attr.as_string();
|
||||
sceneNode->mTransformation = nodeTransform;
|
||||
|
||||
parent->addChildren(1, &sceneNode);
|
||||
|
||||
for (size_t i = 0; i < obj->mComponents.size(); ++i) {
|
||||
Component c = obj->mComponents[i];
|
||||
auto it = mResourcesDictionnary.find(c.mObjectId);
|
||||
if (it != mResourcesDictionnary.end() && it->second->getType() == ResourceType::RT_Object) {
|
||||
addObjectToNode(sceneNode, static_cast<Object*>(it->second), c.mTransformation);
|
||||
}
|
||||
|
||||
}
|
||||
attr = node.attribute(D3MF::XmlTag::type.c_str());
|
||||
if (!attr.empty()) {
|
||||
type = attr.as_string();
|
||||
}
|
||||
|
||||
bool getNodeAttribute(const XmlNode& node, const std::string& attribute, std::string& value) {
|
||||
pugi::xml_attribute objectAttribute = node.attribute(attribute.c_str());
|
||||
if (!objectAttribute.empty()) {
|
||||
value = objectAttribute.as_string();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool getNodeAttribute(const XmlNode &node, const std::string &attribute, int &value) {
|
||||
std::string strValue;
|
||||
bool ret = getNodeAttribute(node, attribute, strValue);
|
||||
if (ret) {
|
||||
value = std::atoi(strValue.c_str());
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
aiMatrix4x4 parseTransformMatrix(std::string matrixStr) {
|
||||
// split the string
|
||||
std::vector<float> numbers;
|
||||
std::string currentNumber;
|
||||
for (size_t i = 0; i < matrixStr.size(); ++i) {
|
||||
const char c = matrixStr[i];
|
||||
if (c == ' ') {
|
||||
if (currentNumber.size() > 0) {
|
||||
float f = std::stof(currentNumber);
|
||||
numbers.push_back(f);
|
||||
currentNumber.clear();
|
||||
}
|
||||
} else {
|
||||
currentNumber.push_back(c);
|
||||
}
|
||||
}
|
||||
if (currentNumber.size() > 0) {
|
||||
float f = std::stof(currentNumber);
|
||||
numbers.push_back(f);
|
||||
}
|
||||
|
||||
nodePtr->mParent = scene->mRootNode;
|
||||
nodePtr->mName.Set(name);
|
||||
aiMatrix4x4 transformMatrix;
|
||||
transformMatrix.a1 = numbers[0];
|
||||
transformMatrix.b1 = numbers[1];
|
||||
transformMatrix.c1 = numbers[2];
|
||||
transformMatrix.d1 = 0;
|
||||
|
||||
size_t meshIdx = mMeshes.size();
|
||||
transformMatrix.a2 = numbers[3];
|
||||
transformMatrix.b2 = numbers[4];
|
||||
transformMatrix.c2 = numbers[5];
|
||||
transformMatrix.d2 = 0;
|
||||
|
||||
transformMatrix.a3 = numbers[6];
|
||||
transformMatrix.b3 = numbers[7];
|
||||
transformMatrix.c3 = numbers[8];
|
||||
transformMatrix.d3 = 0;
|
||||
|
||||
transformMatrix.a4 = numbers[9];
|
||||
transformMatrix.b4 = numbers[10];
|
||||
transformMatrix.c4 = numbers[11];
|
||||
transformMatrix.d4 = 1;
|
||||
return transformMatrix;
|
||||
}
|
||||
|
||||
void ReadObject(XmlNode &node) {
|
||||
int id = -1, pid = -1, pindex = -1;
|
||||
bool hasId = getNodeAttribute(node, D3MF::XmlTag::id, id);
|
||||
//bool hasType = getNodeAttribute(node, D3MF::XmlTag::type, type); not used currently
|
||||
bool hasPid = getNodeAttribute(node, D3MF::XmlTag::pid, pid);
|
||||
bool hasPindex = getNodeAttribute(node, D3MF::XmlTag::pindex, pindex);
|
||||
|
||||
std::string idStr = to_string(id);
|
||||
|
||||
if (!hasId) {
|
||||
return;
|
||||
}
|
||||
|
||||
Object *obj = new Object(id);
|
||||
|
||||
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
|
||||
const std::string ¤tName = currentNode.name();
|
||||
if (currentName == D3MF::XmlTag::mesh) {
|
||||
auto mesh = ReadMesh(currentNode);
|
||||
mesh->mName.Set(name);
|
||||
mMeshes.push_back(mesh);
|
||||
meshIds.push_back(static_cast<unsigned long>(meshIdx));
|
||||
++meshIdx;
|
||||
mesh->mName.Set(idStr);
|
||||
|
||||
if (hasPid) {
|
||||
auto it = mResourcesDictionnary.find(pid);
|
||||
if (hasPindex && it != mResourcesDictionnary.end() && it->second->getType() == ResourceType::RT_BaseMaterials) {
|
||||
BaseMaterials *materials = static_cast<BaseMaterials *>(it->second);
|
||||
mesh->mMaterialIndex = materials->mMaterialIndex[pindex];
|
||||
}
|
||||
}
|
||||
|
||||
obj->mMeshes.push_back(mesh);
|
||||
obj->mMeshIndex.push_back(mMeshCount);
|
||||
mMeshCount++;
|
||||
} else if (currentName == D3MF::XmlTag::components) {
|
||||
for (XmlNode currentSubNode = currentNode.first_child(); currentSubNode; currentSubNode = currentSubNode.next_sibling()) {
|
||||
if (currentSubNode.name() == D3MF::XmlTag::component) {
|
||||
int objectId = -1;
|
||||
std::string componentTransformStr;
|
||||
aiMatrix4x4 componentTransform;
|
||||
if (getNodeAttribute(currentSubNode, D3MF::XmlTag::transform, componentTransformStr)) {
|
||||
componentTransform = parseTransformMatrix(componentTransformStr);
|
||||
}
|
||||
|
||||
if (getNodeAttribute(currentSubNode, D3MF::XmlTag::objectid, objectId))
|
||||
obj->mComponents.push_back({ objectId, componentTransform });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nodePtr->mNumMeshes = static_cast<unsigned int>(meshIds.size());
|
||||
|
||||
nodePtr->mMeshes = new unsigned int[nodePtr->mNumMeshes];
|
||||
|
||||
std::copy(meshIds.begin(), meshIds.end(), nodePtr->mMeshes);
|
||||
|
||||
return nodePtr.release();
|
||||
mResourcesDictionnary.insert(std::make_pair(id, obj));
|
||||
}
|
||||
|
||||
aiMesh *ReadMesh(XmlNode &node) {
|
||||
aiMesh *mesh = new aiMesh();
|
||||
|
||||
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
|
||||
const std::string ¤tName = currentNode.name();
|
||||
if (currentName == D3MF::XmlTag::vertices) {
|
||||
|
@ -241,11 +424,23 @@ private:
|
|||
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) {
|
||||
const std::string ¤tName = currentNode.name();
|
||||
if (currentName == D3MF::XmlTag::triangle) {
|
||||
faces.push_back(ReadTriangle(currentNode));
|
||||
const char *pidToken = currentNode.attribute(D3MF::XmlTag::p1.c_str()).as_string();
|
||||
if (nullptr != pidToken) {
|
||||
int matIdx(std::atoi(pidToken));
|
||||
mesh->mMaterialIndex = matIdx;
|
||||
aiFace face = ReadTriangle(currentNode);
|
||||
faces.push_back(face);
|
||||
|
||||
int pid, p1;
|
||||
bool hasPid = getNodeAttribute(currentNode, D3MF::XmlTag::pid, pid);
|
||||
bool hasP1 = getNodeAttribute(currentNode, D3MF::XmlTag::p1, p1);
|
||||
|
||||
if (hasPid && hasP1) {
|
||||
auto it = mResourcesDictionnary.find(pid);
|
||||
if (it != mResourcesDictionnary.end())
|
||||
{
|
||||
if (it->second->getType() == ResourceType::RT_BaseMaterials) {
|
||||
BaseMaterials *baseMaterials = static_cast<BaseMaterials *>(it->second);
|
||||
mesh->mMaterialIndex = baseMaterials->mMaterialIndex[p1];
|
||||
}
|
||||
// TODO: manage the separation into several meshes if the triangles of the mesh do not all refer to the same material
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -270,26 +465,21 @@ private:
|
|||
}
|
||||
|
||||
void ReadBaseMaterials(XmlNode &node) {
|
||||
std::vector<unsigned int> MatIdArray;
|
||||
const char *baseMaterialId = node.attribute(D3MF::XmlTag::basematerials_id.c_str()).as_string();
|
||||
if (nullptr != baseMaterialId) {
|
||||
unsigned int id = std::atoi(baseMaterialId);
|
||||
const size_t newMatIdx(mMatArray.size());
|
||||
if (id != mActiveMatGroup) {
|
||||
mActiveMatGroup = id;
|
||||
MatId2MatArray::const_iterator it(mMatId2MatArray.find(id));
|
||||
if (mMatId2MatArray.end() == it) {
|
||||
MatIdArray.clear();
|
||||
mMatId2MatArray[id] = MatIdArray;
|
||||
} else {
|
||||
MatIdArray = it->second;
|
||||
int id = -1;
|
||||
if (getNodeAttribute(node, D3MF::XmlTag::basematerials_id, id)) {
|
||||
BaseMaterials* baseMaterials = new BaseMaterials(id);
|
||||
|
||||
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling())
|
||||
{
|
||||
if (currentNode.name() == D3MF::XmlTag::basematerials_base) {
|
||||
baseMaterials->mMaterialIndex.push_back(mMaterialCount);
|
||||
baseMaterials->mMaterials.push_back(readMaterialDef(currentNode, id));
|
||||
mMaterialCount++;
|
||||
}
|
||||
}
|
||||
MatIdArray.push_back(static_cast<unsigned int>(newMatIdx));
|
||||
mMatId2MatArray[mActiveMatGroup] = MatIdArray;
|
||||
}
|
||||
|
||||
mMatArray.push_back(readMaterialDef(node));
|
||||
mResourcesDictionnary.insert(std::make_pair(id, baseMaterials));
|
||||
}
|
||||
}
|
||||
|
||||
bool parseColor(const char *color, aiColor4D &diffuse) {
|
||||
|
@ -304,37 +494,24 @@ private:
|
|||
}
|
||||
|
||||
const char *buf(color);
|
||||
if ('#' != *buf) {
|
||||
if ('#' != buf[0]) {
|
||||
return false;
|
||||
}
|
||||
++buf;
|
||||
char comp[3] = { 0, 0, '\0' };
|
||||
|
||||
comp[0] = *buf;
|
||||
++buf;
|
||||
comp[1] = *buf;
|
||||
++buf;
|
||||
diffuse.r = static_cast<ai_real>(strtol(comp, nullptr, 16)) / ai_real(255.0);
|
||||
char r[3] = { buf[1], buf[2], '\0' };
|
||||
diffuse.r = static_cast<ai_real>(strtol(r, nullptr, 16)) / ai_real(255.0);
|
||||
|
||||
comp[0] = *buf;
|
||||
++buf;
|
||||
comp[1] = *buf;
|
||||
++buf;
|
||||
diffuse.g = static_cast<ai_real>(strtol(comp, nullptr, 16)) / ai_real(255.0);
|
||||
char g[3] = { buf[3], buf[4], '\0' };
|
||||
diffuse.g = static_cast<ai_real>(strtol(g, nullptr, 16)) / ai_real(255.0);
|
||||
|
||||
comp[0] = *buf;
|
||||
++buf;
|
||||
comp[1] = *buf;
|
||||
++buf;
|
||||
diffuse.b = static_cast<ai_real>(strtol(comp, nullptr, 16)) / ai_real(255.0);
|
||||
char b[3] = { buf[5], buf[6], '\0' };
|
||||
diffuse.b = static_cast<ai_real>(strtol(b, nullptr, 16)) / ai_real(255.0);
|
||||
|
||||
if (7 == len)
|
||||
return true;
|
||||
comp[0] = *buf;
|
||||
++buf;
|
||||
comp[1] = *buf;
|
||||
++buf;
|
||||
diffuse.a = static_cast<ai_real>(strtol(comp, nullptr, 16)) / ai_real(255.0);
|
||||
|
||||
char a[3] = { buf[7], buf[8], '\0' };
|
||||
diffuse.a = static_cast<ai_real>(strtol(a, nullptr, 16)) / ai_real(255.0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -347,32 +524,30 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
aiMaterial *readMaterialDef(XmlNode &node) {
|
||||
aiMaterial *mat(nullptr);
|
||||
const char *name(nullptr);
|
||||
const std::string nodeName = node.name();
|
||||
if (nodeName == D3MF::XmlTag::basematerials_base) {
|
||||
name = node.attribute(D3MF::XmlTag::basematerials_name.c_str()).as_string();
|
||||
std::string stdMatName;
|
||||
aiString matName;
|
||||
std::string strId(to_string(mActiveMatGroup));
|
||||
stdMatName += "id";
|
||||
stdMatName += strId;
|
||||
stdMatName += "_";
|
||||
if (nullptr != name) {
|
||||
stdMatName += std::string(name);
|
||||
} else {
|
||||
stdMatName += "basemat";
|
||||
}
|
||||
matName.Set(stdMatName);
|
||||
aiMaterial *readMaterialDef(XmlNode &node, unsigned int basematerialsId) {
|
||||
aiMaterial *material = new aiMaterial();
|
||||
material->mNumProperties = 0;
|
||||
std::string name;
|
||||
bool hasName = getNodeAttribute(node, D3MF::XmlTag::basematerials_name, name);
|
||||
|
||||
mat = new aiMaterial;
|
||||
mat->AddProperty(&matName, AI_MATKEY_NAME);
|
||||
|
||||
assignDiffuseColor(node, mat);
|
||||
std::string stdMaterialName;
|
||||
std::string strId(to_string(basematerialsId));
|
||||
stdMaterialName += "id";
|
||||
stdMaterialName += strId;
|
||||
stdMaterialName += "_";
|
||||
if (hasName) {
|
||||
stdMaterialName += std::string(name);
|
||||
} else {
|
||||
stdMaterialName += "basemat_";
|
||||
stdMaterialName += to_string(mMaterialCount - basematerialsId);
|
||||
}
|
||||
|
||||
return mat;
|
||||
aiString assimpMaterialName(stdMaterialName);
|
||||
material->AddProperty(&assimpMaterialName, AI_MATKEY_NAME);
|
||||
|
||||
assignDiffuseColor(node, material);
|
||||
|
||||
return material;
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -381,10 +556,8 @@ private:
|
|||
std::string value;
|
||||
};
|
||||
std::vector<MetaEntry> mMetaData;
|
||||
std::vector<aiMesh *> mMeshes;
|
||||
MatArray mMatArray;
|
||||
unsigned int mActiveMatGroup;
|
||||
MatId2MatArray mMatId2MatArray;
|
||||
std::map<unsigned int, Resource*> mResourcesDictionnary;
|
||||
unsigned int mMaterialCount, mMeshCount;
|
||||
XmlParser *mXmlParser;
|
||||
};
|
||||
|
||||
|
|
|
@ -121,7 +121,6 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
bool result = false;
|
||||
const size_t len = stream->FileSize();
|
||||
mData.resize(len + 1);
|
||||
memset(&mData[0], '\0', len + 1);
|
||||
|
@ -130,11 +129,11 @@ public:
|
|||
mDoc = new pugi::xml_document();
|
||||
pugi::xml_parse_result parse_result = mDoc->load_string(&mData[0], pugi::parse_full);
|
||||
if (parse_result.status == pugi::status_ok) {
|
||||
return true;
|
||||
} else {
|
||||
ASSIMP_LOG_DEBUG("Error while parse xml.");
|
||||
result = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
pugi::xml_document *getDocument() const {
|
||||
|
|
Loading…
Reference in New Issue