mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-24 17:29:57 +00:00
Refactor ColladaSerializer.cpp, encode material names only once, decode them before passing to OpenCollada functions that take URI parameters
This commit is contained in:
committed by
Thomas Krijnen
parent
1c83b2db53
commit
06589ca1c6
@@ -60,11 +60,7 @@ void ColladaSerializer::ColladaExporter::ColladaGeometries::addFloatSource(const
|
|||||||
source.finish();
|
source.finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColladaSerializer::ColladaExporter::ColladaGeometries::write(
|
void ColladaSerializer::ColladaExporter::ColladaGeometries::write(std::string mesh_id, std::string, std::vector<real_t> positions, std::vector<real_t> normals, std::vector<int> faces, std::vector<int> edges, std::vector<int> material_ids, std::vector<IfcGeom::Material> materials, std::vector<real_t> uvs, std::vector<std::string> material_references)
|
||||||
const std::string &mesh_id, const std::string& /*default_material_name*/, const std::vector<real_t>& positions,
|
|
||||||
const std::vector<real_t>& normals, const std::vector<int>& faces, const std::vector<int>& edges,
|
|
||||||
const std::vector<int> material_ids, const std::vector<IfcGeom::Material>& materials,
|
|
||||||
const std::vector<real_t>& uvs)
|
|
||||||
{
|
{
|
||||||
openMesh(mesh_id);
|
openMesh(mesh_id);
|
||||||
|
|
||||||
@@ -101,14 +97,8 @@ void ColladaSerializer::ColladaExporter::ColladaGeometries::write(
|
|||||||
const size_t num_triangles = std::distance(index_range_start, it) / 3;
|
const size_t num_triangles = std::distance(index_range_start, it) / 3;
|
||||||
if ((previous_material_id != current_material_id && num_triangles > 0) || (it == faces.end())) {
|
if ((previous_material_id != current_material_id && num_triangles > 0) || (it == faces.end())) {
|
||||||
COLLADASW::Triangles triangles(mSW);
|
COLLADASW::Triangles triangles(mSW);
|
||||||
std::string material_name = (serializer->settings().get(SerializerSettings::USE_MATERIAL_NAMES)
|
|
||||||
? materials[previous_material_id].original_name() : materials[previous_material_id].name());
|
|
||||||
|
|
||||||
if (material_name.empty()) {
|
std::string material_name = material_references[previous_material_id];
|
||||||
material_name = "missing-material-" + materials[previous_material_id].name();
|
|
||||||
}
|
|
||||||
|
|
||||||
collada_id(material_name);
|
|
||||||
triangles.setMaterial(material_name);
|
triangles.setMaterial(material_name);
|
||||||
triangles.setCount((unsigned long)num_triangles);
|
triangles.setCount((unsigned long)num_triangles);
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
@@ -163,15 +153,7 @@ void ColladaSerializer::ColladaExporter::ColladaGeometries::write(
|
|||||||
|
|
||||||
for (linelist_t::const_iterator it = linelist.begin(); it != linelist.end(); ++it) {
|
for (linelist_t::const_iterator it = linelist.begin(); it != linelist.end(); ++it) {
|
||||||
COLLADASW::Lines lines(mSW);
|
COLLADASW::Lines lines(mSW);
|
||||||
std::string material_name = (serializer->settings().get(SerializerSettings::USE_MATERIAL_NAMES)
|
lines.setMaterial(material_references[it->first]);
|
||||||
? materials[it->first].original_name() : materials[it->first].name());
|
|
||||||
|
|
||||||
if (material_name.empty()) {
|
|
||||||
material_name = "missing-material-" + materials[it->first].name();
|
|
||||||
}
|
|
||||||
|
|
||||||
collada_id(material_name);
|
|
||||||
lines.setMaterial(material_name);
|
|
||||||
lines.setCount((unsigned long)it->second.size());
|
lines.setCount((unsigned long)it->second.size());
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
lines.getInputList().push_back(COLLADASW::Input(COLLADASW::InputSemantic::VERTEX, "#" + mesh_id + COLLADASW::LibraryGeometries::VERTICES_ID_SUFFIX, offset));
|
lines.getInputList().push_back(COLLADASW::Input(COLLADASW::InputSemantic::VERTEX, "#" + mesh_id + COLLADASW::LibraryGeometries::VERTICES_ID_SUFFIX, offset));
|
||||||
@@ -234,11 +216,13 @@ void ColladaSerializer::ColladaExporter::ColladaScene::add(
|
|||||||
node.start();
|
node.start();
|
||||||
node.addMatrix(matrix_array);
|
node.addMatrix(matrix_array);
|
||||||
COLLADASW::InstanceGeometry instanceGeometry(mSW);
|
COLLADASW::InstanceGeometry instanceGeometry(mSW);
|
||||||
instanceGeometry.setUrl ("#" + geom_name);
|
instanceGeometry.setUrl("#" + geom_name);
|
||||||
BOOST_FOREACH(std::string material_name, material_ids) {
|
BOOST_FOREACH(std::string material_name, material_ids) {
|
||||||
/// @todo This is done 6 times in this file, try to perform this once and be done with the material naming for the export.
|
// Unescape to avoid double escaping beucase OpenCollada's material URI parameter escapes XML internally
|
||||||
collada_id(material_name);
|
std::string unescaped = material_name;
|
||||||
COLLADASW::InstanceMaterial material(material_name, "#" + material_name);
|
IfcUtil::unescape_xml(unescaped);
|
||||||
|
|
||||||
|
COLLADASW::InstanceMaterial material(material_name, "#" + unescaped);
|
||||||
instanceGeometry.getBindMaterial().getInstanceMaterialList().push_back(material);
|
instanceGeometry.getBindMaterial().getInstanceMaterialList().push_back(material);
|
||||||
}
|
}
|
||||||
instanceGeometry.add();
|
instanceGeometry.add();
|
||||||
@@ -319,17 +303,9 @@ void ColladaSerializer::ColladaExporter::ColladaScene::write() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColladaSerializer::ColladaExporter::ColladaMaterials::ColladaEffects::write(const IfcGeom::Material& material)
|
void ColladaSerializer::ColladaExporter::ColladaMaterials::ColladaEffects::write(const IfcGeom::Material &material, const std::string &material_uri)
|
||||||
{
|
{
|
||||||
std::string material_name = (serializer->settings().get(SerializerSettings::USE_MATERIAL_NAMES)
|
openEffect(material_uri + "-fx");
|
||||||
? material.original_name() : material.name());
|
|
||||||
|
|
||||||
if (material_name.empty()) {
|
|
||||||
material_name = "missing-material-" + material.name();
|
|
||||||
}
|
|
||||||
|
|
||||||
collada_id(material_name);
|
|
||||||
openEffect(material_name + "-fx");
|
|
||||||
COLLADASW::EffectProfile effect(mSW);
|
COLLADASW::EffectProfile effect(mSW);
|
||||||
effect.setShaderType(COLLADASW::EffectProfile::LAMBERT);
|
effect.setShaderType(COLLADASW::EffectProfile::LAMBERT);
|
||||||
if (material.hasDiffuse()) {
|
if (material.hasDiffuse()) {
|
||||||
@@ -361,11 +337,29 @@ void ColladaSerializer::ColladaExporter::ColladaMaterials::ColladaEffects::close
|
|||||||
|
|
||||||
void ColladaSerializer::ColladaExporter::ColladaMaterials::add(const IfcGeom::Material& material) {
|
void ColladaSerializer::ColladaExporter::ColladaMaterials::add(const IfcGeom::Material& material) {
|
||||||
if (!contains(material)) {
|
if (!contains(material)) {
|
||||||
effects.write(material);
|
std::string material_name = (serializer->settings().get(SerializerSettings::USE_MATERIAL_NAMES)
|
||||||
|
? material.original_name() : material.name());
|
||||||
|
|
||||||
|
if (material_name.empty()) {
|
||||||
|
material_name = "missing-material-" + material.name();
|
||||||
|
}
|
||||||
|
|
||||||
|
collada_id(material_name);
|
||||||
|
|
||||||
|
effects.write(material, material_name);
|
||||||
materials.push_back(material);
|
materials.push_back(material);
|
||||||
|
material_uris.push_back(material_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string ColladaSerializer::ColladaExporter::ColladaMaterials::getMaterialUri(const IfcGeom::Material& material) {
|
||||||
|
std::vector<IfcGeom::Material>::iterator it = std::find(materials.begin(), materials.end(), material);
|
||||||
|
long index = std::distance(materials.begin(), it);
|
||||||
|
|
||||||
|
std::string material_uri = material_uris.at(static_cast<unsigned long>(index));
|
||||||
|
return material_uri;
|
||||||
|
}
|
||||||
|
|
||||||
bool ColladaSerializer::ColladaExporter::ColladaMaterials::contains(const IfcGeom::Material& material) {
|
bool ColladaSerializer::ColladaExporter::ColladaMaterials::contains(const IfcGeom::Material& material) {
|
||||||
return std::find(materials.begin(), materials.end(), material) != materials.end();
|
return std::find(materials.begin(), materials.end(), material) != materials.end();
|
||||||
}
|
}
|
||||||
@@ -373,18 +367,13 @@ bool ColladaSerializer::ColladaExporter::ColladaMaterials::contains(const IfcGeo
|
|||||||
void ColladaSerializer::ColladaExporter::ColladaMaterials::write() {
|
void ColladaSerializer::ColladaExporter::ColladaMaterials::write() {
|
||||||
effects.close();
|
effects.close();
|
||||||
BOOST_FOREACH(const IfcGeom::Material& material, materials) {
|
BOOST_FOREACH(const IfcGeom::Material& material, materials) {
|
||||||
std::string material_name = (serializer->settings().get(SerializerSettings::USE_MATERIAL_NAMES)
|
std::string material_name = getMaterialUri(material);
|
||||||
? material.original_name() : material.name());
|
|
||||||
|
|
||||||
if (material_name.empty()) {
|
|
||||||
material_name = "missing-material-" + material.name();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string material_name_unescaped = material_name; // workaround double-escaping that would occur in addInstanceEffect()
|
|
||||||
IfcUtil::sanitate_material_name(material_name_unescaped);
|
|
||||||
collada_id(material_name);
|
|
||||||
openMaterial(material_name);
|
openMaterial(material_name);
|
||||||
addInstanceEffect("#" + material_name_unescaped + "-fx");
|
|
||||||
|
// Unescape to avoid double escaping beucase OpenCollada's addInstanceEffect escapes XML internally
|
||||||
|
IfcUtil::unescape_xml(material_name);
|
||||||
|
|
||||||
|
addInstanceEffect("#" + material_name + "-fx");
|
||||||
closeMaterial();
|
closeMaterial();
|
||||||
}
|
}
|
||||||
closeLibrary();
|
closeLibrary();
|
||||||
@@ -412,17 +401,9 @@ void ColladaSerializer::ColladaExporter::write(const IfcGeom::TriangulationEleme
|
|||||||
|
|
||||||
std::vector<std::string> material_references;
|
std::vector<std::string> material_references;
|
||||||
BOOST_FOREACH(const IfcGeom::Material& material, mesh.materials()) {
|
BOOST_FOREACH(const IfcGeom::Material& material, mesh.materials()) {
|
||||||
if (!materials.contains(material)) {
|
materials.add(material);
|
||||||
materials.add(material);
|
|
||||||
}
|
|
||||||
std::string material_name = (serializer->settings().get(SerializerSettings::USE_MATERIAL_NAMES)
|
|
||||||
? material.original_name() : material.name());
|
|
||||||
|
|
||||||
if (material_name.empty()) {
|
std::string material_name = materials.getMaterialUri(material);
|
||||||
material_name = "missing-material-" + material.name();
|
|
||||||
}
|
|
||||||
|
|
||||||
collada_id(material_name);
|
|
||||||
material_references.push_back(material_name);
|
material_references.push_back(material_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -482,7 +463,7 @@ void ColladaSerializer::ColladaExporter::endDocument() {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
geometries_written.insert(it->representation_id);
|
geometries_written.insert(it->representation_id);
|
||||||
geometries.write(it->representation_id, it->type, it->vertices, it->normals, it->faces, it->edges, it->material_ids, it->materials, it->uvs);
|
geometries.write(it->representation_id, it->type, it->vertices, it->normals, it->faces, it->edges, it->material_ids, it->materials, it->uvs, it->material_references);
|
||||||
}
|
}
|
||||||
geometries.close();
|
geometries.close();
|
||||||
|
|
||||||
|
|||||||
@@ -69,11 +69,7 @@ private:
|
|||||||
{}
|
{}
|
||||||
void addFloatSource(const std::string& mesh_id, const std::string& suffix,
|
void addFloatSource(const std::string& mesh_id, const std::string& suffix,
|
||||||
const std::vector<real_t>& floats, const char* coords = "XYZ");
|
const std::vector<real_t>& floats, const char* coords = "XYZ");
|
||||||
void write(const std::string &mesh_id, const std::string& default_material_name,
|
void write(std::string mesh_id, std::string default_material_name, std::vector<real_t> positions, std::vector<real_t> normals, std::vector<int> faces, std::vector<int> edges, std::vector<int> material_ids, std::vector<IfcGeom::Material> materials, std::vector<real_t> uvs, std::vector<std::string> material_references);
|
||||||
const std::vector<real_t>& positions, const std::vector<real_t>& normals,
|
|
||||||
const std::vector<int>& faces, const std::vector<int>& edges,
|
|
||||||
const std::vector<int> material_ids, const std::vector<IfcGeom::Material>& materials,
|
|
||||||
const std::vector<real_t>& uvs);
|
|
||||||
void close();
|
void close();
|
||||||
ColladaSerializer *serializer;
|
ColladaSerializer *serializer;
|
||||||
};
|
};
|
||||||
@@ -115,11 +111,12 @@ private:
|
|||||||
explicit ColladaEffects(COLLADASW::StreamWriter& stream)
|
explicit ColladaEffects(COLLADASW::StreamWriter& stream)
|
||||||
: COLLADASW::LibraryEffects(&stream)
|
: COLLADASW::LibraryEffects(&stream)
|
||||||
{}
|
{}
|
||||||
void write(const IfcGeom::Material& material);
|
void write(const IfcGeom::Material &material, const std::string &material_uri);
|
||||||
void close();
|
void close();
|
||||||
ColladaSerializer *serializer;
|
ColladaSerializer *serializer;
|
||||||
};
|
};
|
||||||
std::vector<IfcGeom::Material> materials;
|
std::vector<IfcGeom::Material> materials;
|
||||||
|
std::vector<std::string> material_uris;
|
||||||
public:
|
public:
|
||||||
explicit ColladaMaterials(COLLADASW::StreamWriter& stream, ColladaSerializer *_serializer)
|
explicit ColladaMaterials(COLLADASW::StreamWriter& stream, ColladaSerializer *_serializer)
|
||||||
: COLLADASW::LibraryMaterials(&stream)
|
: COLLADASW::LibraryMaterials(&stream)
|
||||||
@@ -127,6 +124,7 @@ private:
|
|||||||
, effects(stream)
|
, effects(stream)
|
||||||
{}
|
{}
|
||||||
void add(const IfcGeom::Material& material);
|
void add(const IfcGeom::Material& material);
|
||||||
|
std::string getMaterialUri(const IfcGeom::Material& material);
|
||||||
bool contains(const IfcGeom::Material& material);
|
bool contains(const IfcGeom::Material& material);
|
||||||
void write();
|
void write();
|
||||||
ColladaSerializer *serializer;
|
ColladaSerializer *serializer;
|
||||||
|
|||||||
Reference in New Issue
Block a user