mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-17 10:59:17 +00:00
More work
This commit is contained in:
@@ -66,7 +66,7 @@ void ColladaSerializer::ColladaExporter::ColladaGeometries::write(
|
||||
const std::string &mesh_id, const std::string &/**<@todo 'default_material_name' unused, remove? */,
|
||||
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>& /**<@todo 'materials' unused, remove? */,
|
||||
const std::vector<int>& material_ids, const std::vector<ifcopenshell::geometry::taxonomy::style>& /**<@todo 'materials' unused, remove? */,
|
||||
const std::vector<real_t>& uvs, const std::vector<std::string>& material_references)
|
||||
{
|
||||
openMesh(mesh_id);
|
||||
@@ -179,7 +179,7 @@ void ColladaSerializer::ColladaExporter::ColladaGeometries::close() {
|
||||
|
||||
void ColladaSerializer::ColladaExporter::ColladaScene::add(
|
||||
const std::string& node_id, const std::string& node_name, const std::string& geom_name,
|
||||
const std::vector<std::string>& material_ids, const IfcGeom::Transformation<real_t>& transformation)
|
||||
const std::vector<std::string>& material_ids, const ifcopenshell::geometry::Transformation& transformation)
|
||||
{
|
||||
if (!scene_opened) {
|
||||
openVisualScene(scene_id);
|
||||
@@ -194,13 +194,13 @@ void ColladaSerializer::ColladaExporter::ColladaScene::add(
|
||||
// The matrix attribute of an entity is basically a 4x3 representation of its ObjectPlacement.
|
||||
// Note that this placement is absolute, ie it is multiplied with all parent placements.
|
||||
|
||||
IfcGeom::Transformation<real_t>* relative_trsf = 0;
|
||||
const IfcGeom::Transformation<real_t>* transformation_towrite = &transformation;
|
||||
ifcopenshell::geometry::Transformation* relative_trsf = 0;
|
||||
const ifcopenshell::geometry::Transformation* transformation_towrite = &transformation;
|
||||
|
||||
// If this is not the first parent, get the relative placement
|
||||
if (parentNodes.size() > 0)
|
||||
{
|
||||
relative_trsf = new IfcGeom::Transformation<real_t>(matrixStack.top().multiplied(transformation));
|
||||
relative_trsf = new ifcopenshell::geometry::Transformation(matrixStack.top().multiplied(transformation));
|
||||
transformation_towrite = relative_trsf;
|
||||
}
|
||||
|
||||
@@ -236,22 +236,22 @@ void ColladaSerializer::ColladaExporter::ColladaScene::add(
|
||||
node.end();
|
||||
}
|
||||
|
||||
void ColladaSerializer::ColladaExporter::ColladaScene::addParent(const IfcGeom::Element<real_t>& parent){
|
||||
void ColladaSerializer::ColladaExporter::ColladaScene::addParent(const ifcopenshell::geometry::Element& parent){
|
||||
//we open the visual scene tag if it's not.
|
||||
if (!scene_opened) {
|
||||
openVisualScene(scene_id);
|
||||
scene_opened = true;
|
||||
}
|
||||
|
||||
const IfcGeom::Transformation<real_t>& parent_trsf = parent.transformation();
|
||||
const ifcopenshell::geometry::Transformation& parent_trsf = parent.transformation();
|
||||
|
||||
IfcGeom::Transformation<real_t>* relative_trsf = 0;
|
||||
const IfcGeom::Transformation<real_t>* transformation_towrite = &parent_trsf;
|
||||
ifcopenshell::geometry::Transformation* relative_trsf = 0;
|
||||
const ifcopenshell::geometry::Transformation* transformation_towrite = &parent_trsf;
|
||||
|
||||
// If this is not the first parent, get the relative placement
|
||||
if (parentNodes.size() > 0)
|
||||
{
|
||||
relative_trsf = new IfcGeom::Transformation<real_t>(matrixStack.top().multiplied(parent_trsf));
|
||||
relative_trsf = new ifcopenshell::geometry::Transformation(matrixStack.top().multiplied(parent_trsf));
|
||||
transformation_towrite = relative_trsf;
|
||||
}
|
||||
|
||||
@@ -311,24 +311,24 @@ void ColladaSerializer::ColladaExporter::ColladaScene::write() {
|
||||
}
|
||||
|
||||
void ColladaSerializer::ColladaExporter::ColladaMaterials::ColladaEffects::write(
|
||||
const IfcGeom::Material &material, const std::string &material_uri)
|
||||
const ifcopenshell::geometry::taxonomy::style &material, const std::string &material_uri)
|
||||
{
|
||||
openEffect(material_uri + "-fx");
|
||||
COLLADASW::EffectProfile effect(mSW);
|
||||
effect.setShaderType(COLLADASW::EffectProfile::LAMBERT);
|
||||
if (material.hasDiffuse()) {
|
||||
const double* diffuse = material.diffuse();
|
||||
if (material.diffuse) {
|
||||
auto diffuse = material.diffuse.get().components;
|
||||
effect.setDiffuse(COLLADASW::ColorOrTexture(COLLADASW::Color(diffuse[0],diffuse[1],diffuse[2])));
|
||||
}
|
||||
if (material.hasSpecular()) {
|
||||
const double* specular = material.specular();
|
||||
if (material.specular) {
|
||||
auto specular = material.specular.get().components;
|
||||
effect.setSpecular(COLLADASW::ColorOrTexture(COLLADASW::Color(specular[0],specular[1],specular[2])));
|
||||
}
|
||||
if (material.hasSpecularity()) {
|
||||
effect.setShininess(material.specularity());
|
||||
if (material.specularity) {
|
||||
effect.setShininess(*material.specularity);
|
||||
}
|
||||
if (material.hasTransparency()) {
|
||||
const double transparency = material.transparency();
|
||||
if (material.transparency) {
|
||||
const double transparency = *material.transparency;
|
||||
if (transparency > 0) {
|
||||
// The default opacity mode for Collada is A_ONE, which apparently indicates a
|
||||
// transparency value of 1 to be fully opaque. Hence transparency is inverted.
|
||||
@@ -343,13 +343,14 @@ void ColladaSerializer::ColladaExporter::ColladaMaterials::ColladaEffects::close
|
||||
closeLibrary();
|
||||
}
|
||||
|
||||
void ColladaSerializer::ColladaExporter::ColladaMaterials::add(const IfcGeom::Material& material) {
|
||||
void ColladaSerializer::ColladaExporter::ColladaMaterials::add(const ifcopenshell::geometry::taxonomy::style& material) {
|
||||
if (!contains(material)) {
|
||||
std::string material_name = (serializer->settings().get(SerializerSettings::USE_MATERIAL_NAMES)
|
||||
? material.original_name() : material.name());
|
||||
// @todo original_name
|
||||
std::string material_name = *(serializer->settings().get(SerializerSettings::USE_MATERIAL_NAMES)
|
||||
? material.name : material.name);
|
||||
|
||||
if (material_name.empty()) {
|
||||
material_name = "missing-material-" + material.name();
|
||||
material_name = "missing-material-" + *material.name;
|
||||
}
|
||||
|
||||
collada_id(material_name);
|
||||
@@ -360,19 +361,19 @@ void ColladaSerializer::ColladaExporter::ColladaMaterials::add(const IfcGeom::Ma
|
||||
}
|
||||
}
|
||||
|
||||
std::string ColladaSerializer::ColladaExporter::ColladaMaterials::getMaterialUri(const IfcGeom::Material& material) {
|
||||
std::vector<IfcGeom::Material>::iterator it = std::find(materials.begin(), materials.end(), material);
|
||||
std::string ColladaSerializer::ColladaExporter::ColladaMaterials::getMaterialUri(const ifcopenshell::geometry::taxonomy::style& material) {
|
||||
std::vector<ifcopenshell::geometry::taxonomy::style>::iterator it = std::find(materials.begin(), materials.end(), material);
|
||||
ptrdiff_t index = std::distance(materials.begin(), it);
|
||||
return material_uris.at(index);
|
||||
}
|
||||
|
||||
bool ColladaSerializer::ColladaExporter::ColladaMaterials::contains(const IfcGeom::Material& material) {
|
||||
bool ColladaSerializer::ColladaExporter::ColladaMaterials::contains(const ifcopenshell::geometry::taxonomy::style& material) {
|
||||
return std::find(materials.begin(), materials.end(), material) != materials.end();
|
||||
}
|
||||
|
||||
void ColladaSerializer::ColladaExporter::ColladaMaterials::write() {
|
||||
effects.close();
|
||||
BOOST_FOREACH(const IfcGeom::Material& material, materials) {
|
||||
BOOST_FOREACH(const ifcopenshell::geometry::taxonomy::style& material, materials) {
|
||||
std::string material_name = getMaterialUri(material);
|
||||
openMaterial(material_name);
|
||||
|
||||
@@ -395,9 +396,9 @@ void ColladaSerializer::ColladaExporter::startDocument(const std::string& unit_n
|
||||
asset.add();
|
||||
}
|
||||
|
||||
void ColladaSerializer::ColladaExporter::write(const IfcGeom::TriangulationElement<real_t>* o)
|
||||
void ColladaSerializer::ColladaExporter::write(const ifcopenshell::geometry::TriangulationElement* o)
|
||||
{
|
||||
const IfcGeom::Representation::Triangulation<real_t>& mesh = o->geometry();
|
||||
const ifcopenshell::geometry::Representation::Triangulation& mesh = o->geometry();
|
||||
|
||||
std::string name = serializer->object_id(o);
|
||||
collada_id(name);
|
||||
@@ -406,7 +407,7 @@ void ColladaSerializer::ColladaExporter::write(const IfcGeom::TriangulationEleme
|
||||
collada_id(representation_id);
|
||||
|
||||
std::vector<std::string> material_references;
|
||||
BOOST_FOREACH(const IfcGeom::Material& material, mesh.materials()) {
|
||||
BOOST_FOREACH(const ifcopenshell::geometry::taxonomy::style& material, mesh.materials()) {
|
||||
materials.add(material);
|
||||
|
||||
std::string material_name = materials.getMaterialUri(material);
|
||||
@@ -456,7 +457,7 @@ std::string ColladaSerializer::differentiateSlabTypes(const IfcUtil::IfcBaseEnti
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string ColladaSerializer::object_id(const IfcGeom::Element<real_t>* o) /*override*/
|
||||
std::string ColladaSerializer::object_id(const ifcopenshell::geometry::Element* o) /*override*/
|
||||
{
|
||||
if (settings_.get(SerializerSettings::USE_ELEMENT_TYPES)) {
|
||||
const std::string slabSuffix = (o->product() && o->product()->declaration().name() == "IfcSlab")
|
||||
@@ -549,7 +550,7 @@ void ColladaSerializer::writeHeader() {
|
||||
exporter.startDocument(unit_name, unit_magnitude);
|
||||
}
|
||||
|
||||
void ColladaSerializer::write(const IfcGeom::TriangulationElement<real_t>* o) {
|
||||
void ColladaSerializer::write(const ifcopenshell::geometry::TriangulationElement* o) {
|
||||
exporter.write(o);
|
||||
}
|
||||
|
||||
|
||||
@@ -41,8 +41,6 @@
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#include "../ifcgeom/schema_agnostic/IfcGeomIterator.h"
|
||||
|
||||
#include "../serializers/GeometrySerializer.h"
|
||||
|
||||
#include <boost/numeric/ublas/matrix.hpp>
|
||||
@@ -68,14 +66,14 @@ private:
|
||||
, serializer(_serializer)
|
||||
{}
|
||||
void addFloatSource(const std::string& mesh_id, const std::string& suffix,
|
||||
const std::vector<real_t>& floats, const char* coords = "XYZ");
|
||||
const std::vector<double>& floats, const char* coords = "XYZ");
|
||||
/// @todo pass simply DeferredObject?
|
||||
void write(
|
||||
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<double>& positions, const std::vector<double>& 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, const std::vector<std::string>& material_references);
|
||||
const std::vector<int>& material_ids, const std::vector<ifcopenshell::geometry::taxonomy::style>& materials,
|
||||
const std::vector<double>& uvs, const std::vector<std::string>& material_references);
|
||||
void close();
|
||||
ColladaSerializer *serializer;
|
||||
};
|
||||
@@ -88,7 +86,7 @@ private:
|
||||
const std::string scene_id;
|
||||
bool scene_opened;
|
||||
std::stack<COLLADASW::Node*> parentNodes;
|
||||
std::stack<IfcGeom::Transformation<real_t> > matrixStack;
|
||||
std::stack<ifcopenshell::geometry::Transformation> matrixStack;
|
||||
public:
|
||||
ColladaScene(const std::string& scene_id, COLLADASW::StreamWriter& stream, ColladaSerializer *_serializer)
|
||||
: COLLADASW::LibraryVisualScenes(&stream)
|
||||
@@ -97,8 +95,8 @@ private:
|
||||
, serializer(_serializer)
|
||||
{}
|
||||
void add(const std::string& node_id, const std::string& node_name, const std::string& geom_name,
|
||||
const std::vector<std::string>& material_ids, const IfcGeom::Transformation<real_t>& matrix);
|
||||
void addParent(const IfcGeom::Element<real_t>& parent);
|
||||
const std::vector<std::string>& material_ids, const ifcopenshell::geometry::Transformation& matrix);
|
||||
void addParent(const ifcopenshell::geometry::Element& parent);
|
||||
void closeParent();
|
||||
COLLADASW::Node* GetDirectParent();
|
||||
void write();
|
||||
@@ -117,11 +115,11 @@ private:
|
||||
explicit ColladaEffects(COLLADASW::StreamWriter& stream)
|
||||
: COLLADASW::LibraryEffects(&stream)
|
||||
{}
|
||||
void write(const IfcGeom::Material &material, const std::string &material_uri);
|
||||
void write(const ifcopenshell::geometry::taxonomy::style &material, const std::string &material_uri);
|
||||
void close();
|
||||
ColladaSerializer *serializer;
|
||||
};
|
||||
std::vector<IfcGeom::Material> materials;
|
||||
std::vector<ifcopenshell::geometry::taxonomy::style> materials;
|
||||
std::vector<std::string> material_uris;
|
||||
public:
|
||||
explicit ColladaMaterials(COLLADASW::StreamWriter& stream, ColladaSerializer *_serializer)
|
||||
@@ -129,9 +127,9 @@ private:
|
||||
, serializer(_serializer)
|
||||
, effects(stream)
|
||||
{}
|
||||
void add(const IfcGeom::Material& material);
|
||||
std::string getMaterialUri(const IfcGeom::Material& material);
|
||||
bool contains(const IfcGeom::Material& material);
|
||||
void add(const ifcopenshell::geometry::taxonomy::style& material);
|
||||
std::string getMaterialUri(const ifcopenshell::geometry::taxonomy::style& material);
|
||||
bool contains(const ifcopenshell::geometry::taxonomy::style& material);
|
||||
void write();
|
||||
ColladaSerializer *serializer;
|
||||
ColladaEffects effects;
|
||||
@@ -158,21 +156,21 @@ private:
|
||||
|
||||
public:
|
||||
std::string unique_id, representation_id, type;
|
||||
IfcGeom::Transformation<real_t> transformation;
|
||||
std::vector<real_t> vertices;
|
||||
std::vector<real_t> normals;
|
||||
ifcopenshell::geometry::Transformation transformation;
|
||||
std::vector<double> vertices;
|
||||
std::vector<double> normals;
|
||||
std::vector<int> faces;
|
||||
std::vector<int> edges;
|
||||
std::vector<int> material_ids;
|
||||
std::vector<IfcGeom::Material> materials;
|
||||
std::vector<ifcopenshell::geometry::taxonomy::style> materials;
|
||||
std::vector<std::string> material_references;
|
||||
std::vector<real_t> uvs;
|
||||
std::vector<const IfcGeom::Element<real_t>*> parents_;
|
||||
std::vector<double> uvs;
|
||||
std::vector<const ifcopenshell::geometry::Element*> parents_;
|
||||
|
||||
DeferredObject(const std::string& unique_id, const std::string& representation_id, const std::string& type, const IfcGeom::Transformation<real_t>& transformation,
|
||||
const std::vector<real_t>& vertices, 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<std::string>& material_references, const std::vector<real_t>& uvs)
|
||||
DeferredObject(const std::string& unique_id, const std::string& representation_id, const std::string& type, const ifcopenshell::geometry::Transformation& transformation,
|
||||
const std::vector<double>& vertices, const std::vector<double>& normals, const std::vector<int>& faces,
|
||||
const std::vector<int>& edges, const std::vector<int>& material_ids, const std::vector<ifcopenshell::geometry::taxonomy::style>& materials,
|
||||
const std::vector<std::string>& material_references, const std::vector<double>& uvs)
|
||||
: unique_id(unique_id)
|
||||
, representation_id(representation_id)
|
||||
, type(type)
|
||||
@@ -187,8 +185,8 @@ private:
|
||||
, uvs(uvs)
|
||||
{}
|
||||
|
||||
std::vector<const IfcGeom::Element<real_t>*>& parents() { return parents_; }
|
||||
const std::vector<const IfcGeom::Element<real_t>*>& parents() const { return parents_; }
|
||||
std::vector<const ifcopenshell::geometry::Element*>& parents() { return parents_; }
|
||||
const std::vector<const ifcopenshell::geometry::Element*>& parents() const { return parents_; }
|
||||
};
|
||||
COLLADABU::NativeString filename;
|
||||
COLLADASW::StreamWriter stream;
|
||||
@@ -211,7 +209,7 @@ private:
|
||||
std::vector<DeferredObject> deferreds;
|
||||
virtual ~ColladaExporter() {}
|
||||
void startDocument(const std::string& unit_name, float unit_magnitude);
|
||||
void write(const IfcGeom::TriangulationElement<real_t>* o);
|
||||
void write(const ifcopenshell::geometry::TriangulationElement* o);
|
||||
void endDocument();
|
||||
};
|
||||
ColladaExporter exporter;
|
||||
@@ -229,8 +227,8 @@ public:
|
||||
}
|
||||
bool ready();
|
||||
void writeHeader();
|
||||
void write(const IfcGeom::TriangulationElement<real_t>* o);
|
||||
void write(const IfcGeom::NativeElement<real_t>* /*o*/) {}
|
||||
void write(const ifcopenshell::geometry::TriangulationElement* o);
|
||||
void write(const ifcopenshell::geometry::NativeElement* /*o*/) {}
|
||||
void finalize();
|
||||
bool isTesselated() const { return true; }
|
||||
void setUnitNameAndMagnitude(const std::string& name, float magnitude) {
|
||||
@@ -239,7 +237,7 @@ public:
|
||||
}
|
||||
void setFile(IfcParse::IfcFile*) {}
|
||||
|
||||
std::string object_id(const IfcGeom::Element<real_t>* o) /*override*/;
|
||||
std::string object_id(const ifcopenshell::geometry::Element* o) /*override*/;
|
||||
|
||||
private:
|
||||
static std::string differentiateSlabTypes(const IfcUtil::IfcBaseEntity* slab);
|
||||
|
||||
@@ -27,29 +27,29 @@ typedef float real_t;
|
||||
#endif
|
||||
|
||||
#include "../serializers/Serializer.h"
|
||||
#include "../ifcgeom/schema_agnostic/IfcGeomIterator.h"
|
||||
#include "../ifcgeom/schema_agnostic/IfcGeomElement.h"
|
||||
#include "../ifcgeom/settings.h"
|
||||
|
||||
class SerializerSettings : public IfcGeom::IteratorSettings
|
||||
class SerializerSettings : public ifcopenshell::geometry::settings
|
||||
{
|
||||
public:
|
||||
enum Setting
|
||||
{
|
||||
/// Use entity names instead of unique IDs for naming elements.
|
||||
/// Applicable for OBJ, DAE, and SVG output.
|
||||
USE_ELEMENT_NAMES = 1 << (IfcGeom::IteratorSettings::NUM_SETTINGS + 1),
|
||||
USE_ELEMENT_NAMES = 1 << (ifcopenshell::geometry::settings::NUM_SETTINGS + 1),
|
||||
/// Use entity GUIDs instead of unique IDs for naming elements.
|
||||
/// Applicable for OBJ, DAE, and SVG output.
|
||||
USE_ELEMENT_GUIDS = 1 << (IfcGeom::IteratorSettings::NUM_SETTINGS + 2),
|
||||
USE_ELEMENT_GUIDS = 1 << (ifcopenshell::geometry::settings::NUM_SETTINGS + 2),
|
||||
/// Use material names instead of unique IDs for naming materials.
|
||||
/// Applicable for OBJ and DAE output.
|
||||
USE_MATERIAL_NAMES = 1 << (IfcGeom::IteratorSettings::NUM_SETTINGS + 3),
|
||||
USE_MATERIAL_NAMES = 1 << (ifcopenshell::geometry::settings::NUM_SETTINGS + 3),
|
||||
/// Use element types instead of unique IDs for naming elements.
|
||||
/// Applicable for DAE output.
|
||||
USE_ELEMENT_TYPES = 1 << (IfcGeom::IteratorSettings::NUM_SETTINGS + 4),
|
||||
USE_ELEMENT_TYPES = 1 << (ifcopenshell::geometry::settings::NUM_SETTINGS + 4),
|
||||
/// Order the elements using their IfcBuildingStorey parent
|
||||
/// Applicable for DAE output
|
||||
USE_ELEMENT_HIERARCHY = 1 << (IfcGeom::IteratorSettings::NUM_SETTINGS + 5),
|
||||
USE_ELEMENT_HIERARCHY = 1 << (ifcopenshell::geometry::settings::NUM_SETTINGS + 5),
|
||||
/// Number of different setting flags.
|
||||
NUM_SETTINGS = 5
|
||||
};
|
||||
@@ -76,15 +76,15 @@ public:
|
||||
virtual ~GeometrySerializer() {}
|
||||
|
||||
virtual bool isTesselated() const = 0;
|
||||
virtual void write(const IfcGeom::TriangulationElement<real_t>* o) = 0;
|
||||
virtual void write(const IfcGeom::NativeElement<real_t>* o) = 0;
|
||||
virtual void write(const ifcopenshell::geometry::TriangulationElement* o) = 0;
|
||||
virtual void write(const ifcopenshell::geometry::NativeElement* o) = 0;
|
||||
virtual void setUnitNameAndMagnitude(const std::string& name, float magnitude) = 0;
|
||||
|
||||
const SerializerSettings& settings() const { return settings_; }
|
||||
SerializerSettings& settings() { return settings_; }
|
||||
|
||||
/// Returns ID for the object depending on the used setting.
|
||||
virtual std::string object_id(const IfcGeom::Element<real_t>* o)
|
||||
virtual std::string object_id(const ifcopenshell::geometry::Element* o)
|
||||
{
|
||||
if (settings_.get(SerializerSettings::USE_ELEMENT_GUIDS)) return o->guid();
|
||||
if (settings_.get(SerializerSettings::USE_ELEMENT_NAMES)) return o->name();
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
#ifndef OPENCASCADEBASEDSERIALIZER_H
|
||||
#define OPENCASCADEBASEDSERIALIZER_H
|
||||
|
||||
#include "../ifcgeom/schema_agnostic/IfcGeomIterator.h"
|
||||
#include "../ifcgeom/schema_agnostic/opencascade/OpenCascadeConversionResult.h"
|
||||
#include "../serializers/GeometrySerializer.h"
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
#include "../../ifcparse/IfcSIPrefix.h"
|
||||
#include "../../ifcparse/utils.h"
|
||||
#include "../../ifcgeom/kernels/opencascade/IfcGeom.h"
|
||||
#include "../../ifcgeom/abstract_mapping.h"
|
||||
|
||||
using boost::property_tree::ptree;
|
||||
|
||||
@@ -57,7 +57,7 @@ std::map<std::string, std::string> POSTFIX_SCHEMA(argument_name_map);
|
||||
|
||||
// Format an IFC attribute and maybe returns as string. Only literal scalar
|
||||
// values are converted. Things like entity instances and lists are omitted.
|
||||
boost::optional<std::string> format_attribute(const Argument* argument, IfcUtil::ArgumentType argument_type, const std::string& argument_name) {
|
||||
boost::optional<std::string> format_attribute(ifcopenshell::geometry::abstract_mapping* mapping, const Argument* argument, IfcUtil::ArgumentType argument_type, const std::string& argument_name) {
|
||||
boost::optional<std::string> value;
|
||||
|
||||
// Hard-code lat-lon as it represents an array
|
||||
@@ -106,7 +106,7 @@ boost::optional<std::string> format_attribute(const Argument* argument, IfcUtil:
|
||||
IfcUtil::IfcBaseClass* e = *argument;
|
||||
if (!e->declaration().as_entity()) {
|
||||
IfcUtil::IfcBaseType* f = (IfcUtil::IfcBaseType*) e;
|
||||
value = format_attribute(f->data().getArgument(0), f->data().getArgument(0)->type(), argument_name);
|
||||
value = format_attribute(mapping, f->data().getArgument(0), f->data().getArgument(0)->type(), argument_name);
|
||||
} else if (e->declaration().is(IfcSchema::IfcSIUnit::Class()) || e->declaration().is(IfcSchema::IfcConversionBasedUnit::Class())) {
|
||||
// Some string concatenation to have a unit name as a XML attribute.
|
||||
|
||||
@@ -125,21 +125,21 @@ boost::optional<std::string> format_attribute(const Argument* argument, IfcUtil:
|
||||
|
||||
value = unit_name;
|
||||
} else if (e->declaration().is(IfcSchema::IfcLocalPlacement::Class())) {
|
||||
IfcSchema::IfcLocalPlacement* placement = e->as<IfcSchema::IfcLocalPlacement>();
|
||||
gp_Trsf trsf;
|
||||
IfcGeom::POSTFIX_SCHEMA(Kernel) kernel;
|
||||
|
||||
if (kernel.convert(placement, trsf)) {
|
||||
std::stringstream stream;
|
||||
for (int i = 1; i < 5; ++i) {
|
||||
for (int j = 1; j < 4; ++j) {
|
||||
const double trsf_value = trsf.Value(j, i);
|
||||
stream << trsf_value << " ";
|
||||
}
|
||||
stream << ((i == 4) ? "1" : "0 ");
|
||||
auto placement = mapping->map(e);
|
||||
auto matrix = (ifcopenshell::geometry::taxonomy::matrix4*) placement;
|
||||
|
||||
std::stringstream stream;
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
const double trsf_value = matrix->components[i];
|
||||
stream << trsf_value;
|
||||
if (i != 15) {
|
||||
stream << " ";
|
||||
}
|
||||
value = stream.str();
|
||||
}
|
||||
}
|
||||
value = stream.str();
|
||||
|
||||
delete mapping;
|
||||
delete placement;
|
||||
}
|
||||
break; }
|
||||
default:
|
||||
@@ -149,7 +149,7 @@ boost::optional<std::string> format_attribute(const Argument* argument, IfcUtil:
|
||||
}
|
||||
|
||||
// Appends to a node with possibly existing attributes
|
||||
ptree& format_entity_instance(IfcUtil::IfcBaseEntity* instance, ptree& child, ptree& tree, bool as_link = false) {
|
||||
ptree& format_entity_instance(ifcopenshell::geometry::abstract_mapping* mapping, IfcUtil::IfcBaseEntity* instance, ptree& child, ptree& tree, bool as_link = false) {
|
||||
const unsigned n = instance->declaration().attribute_count();
|
||||
for (unsigned i = 0; i < n; ++i) {
|
||||
try {
|
||||
@@ -172,11 +172,9 @@ ptree& format_entity_instance(IfcUtil::IfcBaseEntity* instance, ptree& child, pt
|
||||
const std::string qualified_name = instance->declaration().name() + "." + argument_name;
|
||||
boost::optional<std::string> value;
|
||||
try {
|
||||
value = format_attribute(argument, argument_type, qualified_name);
|
||||
value = format_attribute(mapping, argument, argument_type, qualified_name);
|
||||
} catch (const std::exception& e) {
|
||||
Logger::Error(e);
|
||||
} catch (const Standard_ConstructionError& e) {
|
||||
Logger::Error(e.GetMessageString(), instance);
|
||||
}
|
||||
|
||||
if (value) {
|
||||
@@ -196,9 +194,9 @@ ptree& format_entity_instance(IfcUtil::IfcBaseEntity* instance, ptree& child, pt
|
||||
|
||||
// Formats an entity instances as a ptree node, and insert into the DOM. Recurses
|
||||
// over the entity attributes and writes them as xml attributes of the node.
|
||||
ptree& format_entity_instance(IfcUtil::IfcBaseEntity* instance, ptree& tree, bool as_link = false) {
|
||||
ptree& format_entity_instance(ifcopenshell::geometry::abstract_mapping* mapping, IfcUtil::IfcBaseEntity* instance, ptree& tree, bool as_link = false) {
|
||||
ptree child;
|
||||
return format_entity_instance(instance, child, tree, as_link);
|
||||
return format_entity_instance(mapping, instance, child, tree, as_link);
|
||||
}
|
||||
|
||||
std::string qualify_unrooted_instance(IfcUtil::IfcBaseClass* inst) {
|
||||
@@ -208,11 +206,11 @@ std::string qualify_unrooted_instance(IfcUtil::IfcBaseClass* inst) {
|
||||
// A function to be called recursively. Template specialization is used
|
||||
// to descend into decomposition, containment and property relationships.
|
||||
template <typename A>
|
||||
ptree& descend(A* instance, ptree& tree) {
|
||||
ptree& descend(ifcopenshell::geometry::abstract_mapping* mapping, A* instance, ptree& tree) {
|
||||
if (instance->declaration().is(IfcSchema::IfcObjectDefinition::Class())) {
|
||||
return descend(instance->template as<IfcSchema::IfcObjectDefinition>(), tree);
|
||||
return descend(mapping, instance->template as<IfcSchema::IfcObjectDefinition>(), tree);
|
||||
} else {
|
||||
return format_entity_instance(instance, tree);
|
||||
return format_entity_instance(mapping, instance, tree);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,8 +230,8 @@ typename V::list::ptr get_related(T* t, F f, G g) {
|
||||
// Descends into the tree by recursing into IfcRelContainedInSpatialStructure,
|
||||
// IfcRelDecomposes, IfcRelDefinesByType, IfcRelDefinesByProperties relations.
|
||||
template <>
|
||||
ptree& descend(IfcSchema::IfcObjectDefinition* product, ptree& tree) {
|
||||
ptree& child = format_entity_instance(product, tree);
|
||||
ptree& descend(ifcopenshell::geometry::abstract_mapping* mapping, IfcSchema::IfcObjectDefinition* product, ptree& tree) {
|
||||
ptree& child = format_entity_instance(mapping, product, tree);
|
||||
|
||||
if (product->declaration().is(IfcSchema::IfcSpatialStructureElement::Class())) {
|
||||
IfcSchema::IfcSpatialStructureElement* structure = (IfcSchema::IfcSpatialStructureElement*) product;
|
||||
@@ -243,7 +241,7 @@ ptree& descend(IfcSchema::IfcObjectDefinition* product, ptree& tree) {
|
||||
(structure, &IfcSchema::IfcSpatialStructureElement::ContainsElements, &IfcSchema::IfcRelContainedInSpatialStructure::RelatedElements);
|
||||
|
||||
for (IfcSchema::IfcObjectDefinition::list::it it = elements->begin(); it != elements->end(); ++it) {
|
||||
descend(*it, child);
|
||||
descend(mapping, *it, child);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -253,7 +251,7 @@ ptree& descend(IfcSchema::IfcObjectDefinition* product, ptree& tree) {
|
||||
element, &IfcSchema::IfcElement::HasOpenings, &IfcSchema::IfcRelVoidsElement::RelatedOpeningElement);
|
||||
|
||||
for (IfcSchema::IfcOpeningElement::list::it it = openings->begin(); it != openings->end(); ++it) {
|
||||
descend(*it, child);
|
||||
descend(mapping, *it, child);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -269,7 +267,7 @@ ptree& descend(IfcSchema::IfcObjectDefinition* product, ptree& tree) {
|
||||
|
||||
for (IfcSchema::IfcObjectDefinition::list::it it = structures->begin(); it != structures->end(); ++it) {
|
||||
IfcSchema::IfcObjectDefinition* ob = *it;
|
||||
descend(ob, child);
|
||||
descend(mapping, ob, child);
|
||||
}
|
||||
|
||||
if (product->declaration().is(IfcSchema::IfcObject::Class())) {
|
||||
@@ -282,13 +280,13 @@ ptree& descend(IfcSchema::IfcObjectDefinition* product, ptree& tree) {
|
||||
for (IfcSchema::IfcPropertySetDefinition::list::it it = property_sets->begin(); it != property_sets->end(); ++it) {
|
||||
IfcSchema::IfcPropertySetDefinition* pset = *it;
|
||||
if (pset->declaration().is(IfcSchema::IfcPropertySet::Class())) {
|
||||
format_entity_instance(pset, child, true);
|
||||
format_entity_instance(mapping, pset, child, true);
|
||||
}
|
||||
if (pset->declaration().is(IfcSchema::IfcElementQuantity::Class())) {
|
||||
format_entity_instance(pset, child, true);
|
||||
format_entity_instance(mapping, pset, child, true);
|
||||
}
|
||||
if (pset->declaration().is(IfcSchema::IfcElementQuantity::Class())) {
|
||||
format_entity_instance(pset, child, true);
|
||||
format_entity_instance(mapping, pset, child, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -304,19 +302,19 @@ ptree& descend(IfcSchema::IfcObjectDefinition* product, ptree& tree) {
|
||||
|
||||
for (IfcSchema::IfcTypeObject::list::it it = types->begin(); it != types->end(); ++it) {
|
||||
IfcSchema::IfcTypeObject* type = *it;
|
||||
format_entity_instance(type, child, true);
|
||||
format_entity_instance(mapping, type, child, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (product->declaration().is(IfcSchema::IfcProduct::Class())) {
|
||||
std::map<std::string, IfcUtil::IfcBaseEntity*> layers = IfcGeom::Kernel::get_layers(product);
|
||||
std::map<std::string, IfcUtil::IfcBaseEntity*> layers = mapping->get_layers(product);
|
||||
for (std::map<std::string, IfcUtil::IfcBaseEntity*>::const_iterator it = layers.begin(); it != layers.end(); ++it) {
|
||||
// IfcPresentationLayerAssignments don't have GUIDs (only optional Identifier) so use name as the ID.
|
||||
// Note that the IfcPresentationLayerAssignment passed here doesn't really matter as as_link is true
|
||||
// for the format_entity_instance() call.
|
||||
ptree node;
|
||||
node.put("<xmlattr>.xlink:href", "#" + it->first);
|
||||
format_entity_instance(it->second, node, child, true);
|
||||
format_entity_instance(mapping, it->second, node, child, true);
|
||||
}
|
||||
|
||||
IfcSchema::IfcRelAssociates::list::ptr associations = product->HasAssociations();
|
||||
@@ -325,7 +323,7 @@ ptree& descend(IfcSchema::IfcObjectDefinition* product, ptree& tree) {
|
||||
IfcSchema::IfcMaterialSelect* mat = (*it)->as<IfcSchema::IfcRelAssociatesMaterial>()->RelatingMaterial();
|
||||
ptree node;
|
||||
node.put("<xmlattr>.xlink:href", "#" + qualify_unrooted_instance(mat));
|
||||
format_entity_instance((IfcUtil::IfcBaseEntity*) mat, node, child, true);
|
||||
format_entity_instance(mapping, (IfcUtil::IfcBaseEntity*) mat, node, child, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -334,26 +332,26 @@ ptree& descend(IfcSchema::IfcObjectDefinition* product, ptree& tree) {
|
||||
}
|
||||
|
||||
// Format IfcProperty instances and insert into the DOM. IfcComplexProperties are flattened out.
|
||||
void format_properties(IfcSchema::IfcProperty::list::ptr properties, ptree& node) {
|
||||
void format_properties(ifcopenshell::geometry::abstract_mapping* mapping, IfcSchema::IfcProperty::list::ptr properties, ptree& node) {
|
||||
for (IfcSchema::IfcProperty::list::it it = properties->begin(); it != properties->end(); ++it) {
|
||||
IfcSchema::IfcProperty* p = *it;
|
||||
if (p->declaration().is(IfcSchema::IfcComplexProperty::Class())) {
|
||||
IfcSchema::IfcComplexProperty* complex = (IfcSchema::IfcComplexProperty*) p;
|
||||
format_properties(complex->HasProperties(), node);
|
||||
format_properties(mapping, complex->HasProperties(), node);
|
||||
} else {
|
||||
format_entity_instance(p, node);
|
||||
format_entity_instance(mapping, p, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Format IfcElementQuantity instances and insert into the DOM.
|
||||
void format_quantities(IfcSchema::IfcPhysicalQuantity::list::ptr quantities, ptree& node) {
|
||||
void format_quantities(ifcopenshell::geometry::abstract_mapping* mapping, IfcSchema::IfcPhysicalQuantity::list::ptr quantities, ptree& node) {
|
||||
for (IfcSchema::IfcPhysicalQuantity::list::it it = quantities->begin(); it != quantities->end(); ++it) {
|
||||
IfcSchema::IfcPhysicalQuantity* p = *it;
|
||||
ptree& node2 = format_entity_instance(p, node);
|
||||
ptree& node2 = format_entity_instance(mapping, p, node);
|
||||
if (p->declaration().is(IfcSchema::IfcPhysicalComplexQuantity::Class())) {
|
||||
IfcSchema::IfcPhysicalComplexQuantity* complex = (IfcSchema::IfcPhysicalComplexQuantity*)p;
|
||||
format_quantities(complex->HasQuantities(), node2);
|
||||
format_quantities(mapping, complex->HasQuantities(), node2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -435,22 +433,22 @@ void POSTFIX_SCHEMA(XmlSerializer)::finalize() {
|
||||
}
|
||||
|
||||
// Descend into the decomposition structure of the IFC file.
|
||||
descend(project, decomposition);
|
||||
descend(mapping_, project, decomposition);
|
||||
|
||||
// Write all property sets and values as XML nodes.
|
||||
IfcSchema::IfcPropertySet::list::ptr psets = file->instances_by_type<IfcSchema::IfcPropertySet>();
|
||||
for (IfcSchema::IfcPropertySet::list::it it = psets->begin(); it != psets->end(); ++it) {
|
||||
IfcSchema::IfcPropertySet* pset = *it;
|
||||
ptree& node = format_entity_instance(pset, properties);
|
||||
format_properties(pset->HasProperties(), node);
|
||||
ptree& node = format_entity_instance(mapping_, pset, properties);
|
||||
format_properties(mapping_, pset->HasProperties(), node);
|
||||
}
|
||||
|
||||
// Write all quantities and values as XML nodes.
|
||||
IfcSchema::IfcElementQuantity::list::ptr qtosets = file->instances_by_type<IfcSchema::IfcElementQuantity>();
|
||||
for (IfcSchema::IfcElementQuantity::list::it it = qtosets->begin(); it != qtosets->end(); ++it) {
|
||||
IfcSchema::IfcElementQuantity* qto = *it;
|
||||
ptree& node = format_entity_instance(qto, quantities);
|
||||
format_quantities(qto->Quantities(), node);
|
||||
ptree& node = format_entity_instance(mapping_, qto, quantities);
|
||||
format_quantities(mapping_, qto->Quantities(), node);
|
||||
}
|
||||
|
||||
|
||||
@@ -458,7 +456,7 @@ void POSTFIX_SCHEMA(XmlSerializer)::finalize() {
|
||||
IfcSchema::IfcTypeObject::list::ptr type_objects = file->instances_by_type<IfcSchema::IfcTypeObject>();
|
||||
for (IfcSchema::IfcTypeObject::list::it it = type_objects->begin(); it != type_objects->end(); ++it) {
|
||||
IfcSchema::IfcTypeObject* type_object = *it;
|
||||
ptree& node = descend(type_object, types);
|
||||
ptree& node = descend(mapping_, type_object, types);
|
||||
// ptree& node = format_entity_instance(type_object, types);
|
||||
|
||||
if (type_object->hasHasPropertySets()) {
|
||||
@@ -466,7 +464,7 @@ void POSTFIX_SCHEMA(XmlSerializer)::finalize() {
|
||||
for (IfcSchema::IfcPropertySetDefinition::list::it jt = property_sets->begin(); jt != property_sets->end(); ++jt) {
|
||||
IfcSchema::IfcPropertySetDefinition* pset = *jt;
|
||||
if (pset->declaration().is(IfcSchema::IfcPropertySet::Class())) {
|
||||
format_entity_instance(pset, node, true);
|
||||
format_entity_instance(mapping_, pset, node, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -477,10 +475,10 @@ void POSTFIX_SCHEMA(XmlSerializer)::finalize() {
|
||||
for (IfcEntityList::it it = unit_assignments->begin(); it != unit_assignments->end(); ++it) {
|
||||
if ((*it)->declaration().is(IfcSchema::IfcNamedUnit::Class())) {
|
||||
IfcSchema::IfcNamedUnit* named_unit = (*it)->as<IfcSchema::IfcNamedUnit>();
|
||||
ptree& node = format_entity_instance(named_unit, units);
|
||||
ptree& node = format_entity_instance(mapping, named_unit, units);
|
||||
node.put("<xmlattr>.SI_equivalent", IfcParse::get_SI_equivalent<IfcSchema>(named_unit));
|
||||
} else if ((*it)->declaration().is(IfcSchema::IfcMonetaryUnit::Class())) {
|
||||
format_entity_instance((*it)->as<IfcSchema::IfcMonetaryUnit>(), units);
|
||||
format_entity_instance(mapping_, (*it)->as<IfcSchema::IfcMonetaryUnit>(), units);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -495,7 +493,7 @@ void POSTFIX_SCHEMA(XmlSerializer)::finalize() {
|
||||
layer_names.insert(name);
|
||||
ptree node;
|
||||
node.put("<xmlattr>.id", name);
|
||||
format_entity_instance(*it, node, layers);
|
||||
format_entity_instance(mapping_, *it, node, layers);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -521,16 +519,16 @@ void POSTFIX_SCHEMA(XmlSerializer)::finalize() {
|
||||
if ((*jt)->hasMaterial()) {
|
||||
subnode.put("<xmlattr>.Name", (*jt)->Material()->Name());
|
||||
}
|
||||
format_entity_instance(*jt, subnode, node);
|
||||
format_entity_instance(mapping_, *jt, subnode, node);
|
||||
}
|
||||
} else if (mat->as<IfcSchema::IfcMaterialList>()) {
|
||||
IfcSchema::IfcMaterial::list::ptr mats = mat->as<IfcSchema::IfcMaterialList>()->Materials();
|
||||
for (IfcSchema::IfcMaterial::list::it jt = mats->begin(); jt != mats->end(); ++jt) {
|
||||
ptree subnode;
|
||||
format_entity_instance(*jt, subnode, node);
|
||||
format_entity_instance(mapping_, *jt, subnode, node);
|
||||
}
|
||||
}
|
||||
format_entity_instance((IfcUtil::IfcBaseEntity*) mat, node, materials);
|
||||
format_entity_instance(mapping_, (IfcUtil::IfcBaseEntity*) mat, node, materials);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#ifndef XMLSERIALIZERIMPL_H
|
||||
#define XMLSERIALIZERIMPL_H
|
||||
|
||||
#include "../../ifcgeom/abstract_mapping.h"
|
||||
#include "../../ifcparse/macros.h"
|
||||
#include "../../serializers/XmlSerializer.h"
|
||||
|
||||
@@ -29,10 +30,12 @@
|
||||
class POSTFIX_SCHEMA(XmlSerializer) : public XmlSerializer {
|
||||
private:
|
||||
IfcParse::IfcFile* file;
|
||||
ifcopenshell::geometry::abstract_mapping* mapping_;
|
||||
|
||||
public:
|
||||
POSTFIX_SCHEMA(XmlSerializer)(IfcParse::IfcFile* file, const std::string& xml_filename)
|
||||
: XmlSerializer(0, "")
|
||||
, mapping_(ifcopenshell::geometry::impl::mapping_implementations().construct(file))
|
||||
{
|
||||
this->file = file;
|
||||
this->xml_filename = xml_filename;
|
||||
|
||||
Reference in New Issue
Block a user