Proceed with merge

This commit is contained in:
Thomas Krijnen
2023-03-21 20:15:01 +01:00
parent cfb0eda067
commit c78b2893de
194 changed files with 105325 additions and 7785 deletions
+42 -44
View File
@@ -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<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>& /**<@todo 'materials' unused, remove? */,
const std::vector<int>& material_ids, const std::vector<ifcopenshell::geometry::taxonomy::style>& /**<@todo 'materials' unused, remove? */,
const std::vector<double>& uvs, const std::vector<std::string>& material_references)
{
openMesh(mesh_id);
@@ -194,27 +194,25 @@ 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* relative_trsf = 0;
const IfcGeom::Transformation* transformation_towrite = &transformation;
auto transformation_towrite = transformation.data().ccomponents();
// If this is not the first parent, get the relative placement
if (parentNodes.size() > 0)
{
relative_trsf = new IfcGeom::Transformation(matrixStack.top().multiplied(transformation));
transformation_towrite = relative_trsf;
// @todo check order
transformation_towrite = matrixStack.top().ccomponents() * transformation_towrite;
}
const std::vector<double>& posmatrix = transformation_towrite->matrix().data();
const auto& posmatrix = transformation_towrite;
// @todo check
double matrix_array[4][4] = {
{ (double)posmatrix[0], (double)posmatrix[3], (double)posmatrix[6], (double)posmatrix[9] },
{ (double)posmatrix[1], (double)posmatrix[4], (double)posmatrix[7], (double)posmatrix[10] },
{ (double)posmatrix[2], (double)posmatrix[5], (double)posmatrix[8], (double)posmatrix[11] },
{ 0, 0, 0, 1 }
{ (double)posmatrix(0,0), (double)posmatrix(0,1), (double)posmatrix(0,2), (double)posmatrix(0,3) },
{ (double)posmatrix(1,0), (double)posmatrix(1,1), (double)posmatrix(1,2), (double)posmatrix(1,3) },
{ (double)posmatrix(2,0), (double)posmatrix(2,1), (double)posmatrix(2,2), (double)posmatrix(2,3) },
{ (double)posmatrix(3,0), (double)posmatrix(3,1), (double)posmatrix(3,2), (double)posmatrix(3,3) }
};
delete relative_trsf;
node.start();
node.addMatrix(matrix_array);
COLLADASW::InstanceGeometry instanceGeometry(mSW);
@@ -240,23 +238,21 @@ void ColladaSerializer::ColladaExporter::ColladaScene::addParent(const IfcGeom::
const IfcGeom::Transformation& parent_trsf = parent.transformation();
IfcGeom::Transformation* relative_trsf = 0;
const IfcGeom::Transformation* transformation_towrite = &parent_trsf;
auto transformation_towrite = parent_trsf.data().ccomponents();
// If this is not the first parent, get the relative placement
if (parentNodes.size() > 0)
{
relative_trsf = new IfcGeom::Transformation(matrixStack.top().multiplied(parent_trsf));
transformation_towrite = relative_trsf;
if (parentNodes.size() > 0) {
// @todo check order
transformation_towrite = matrixStack.top().ccomponents() * transformation_towrite;
}
const std::vector<double>& parentMatrix = transformation_towrite->matrix().data();
const auto& posmatrix = transformation_towrite;
double matrix_array[4][4] = {
{ (double)parentMatrix[0], (double)parentMatrix[3], (double)parentMatrix[6], (double)parentMatrix[9] },
{ (double)parentMatrix[1], (double)parentMatrix[4], (double)parentMatrix[7], (double)parentMatrix[10] },
{ (double)parentMatrix[2], (double)parentMatrix[5], (double)parentMatrix[8], (double)parentMatrix[11] },
{ 0, 0, 0, 1 }
{ (double)posmatrix(0,0), (double)posmatrix(1,0), (double)posmatrix(2,0), (double)posmatrix(3,0) },
{ (double)posmatrix(0,1), (double)posmatrix(1,1), (double)posmatrix(2,1), (double)posmatrix(3,1) },
{ (double)posmatrix(0,2), (double)posmatrix(1,2), (double)posmatrix(2,2), (double)posmatrix(3,2) },
{ (double)posmatrix(0,3), (double)posmatrix(1,3), (double)posmatrix(2,3), (double)posmatrix(3,3) }
};
std::string name = serializer->object_id(&parent);
@@ -272,7 +268,7 @@ void ColladaSerializer::ColladaExporter::ColladaScene::addParent(const IfcGeom::
current_node->addMatrix(matrix_array);
// Add the node to the parent stack
matrixStack.push(parent_trsf.inverted());
matrixStack.push(ifcopenshell::geometry::taxonomy::matrix4(parent_trsf.data().ccomponents().inverse()));
parentNodes.push(current_node);
serializer->parentStackId.push(parent.id());
}
@@ -306,24 +302,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();
effect.setDiffuse(COLLADASW::ColorOrTexture(COLLADASW::Color(diffuse[0],diffuse[1],diffuse[2])));
if (material.diffuse) {
const auto& diffuse = material.diffuse.ccomponents();
effect.setDiffuse(COLLADASW::ColorOrTexture(COLLADASW::Color(diffuse(0),diffuse(1),diffuse(2))));
}
if (material.hasSpecular()) {
const double* specular = material.specular();
effect.setSpecular(COLLADASW::ColorOrTexture(COLLADASW::Color(specular[0],specular[1],specular[2])));
if (material.specular) {
const auto& specular = material.specular.ccomponents();
effect.setSpecular(COLLADASW::ColorOrTexture(COLLADASW::Color(specular(0),specular(1),specular(2))));
}
if (material.hasSpecularity()) {
effect.setShininess(material.specularity());
if (material.specularity == material.specularity) {
effect.setShininess(material.specularity);
}
if (material.hasTransparency()) {
const double transparency = material.transparency();
if (material.transparency == 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.
@@ -338,13 +334,15 @@ 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());
// std::string material_name = (serializer->settings().get(SerializerSettings::USE_MATERIAL_NAMES)
// ? material.original_name() : material.name());
// @todo
std::string material_name = material.name;
if (material_name.empty()) {
material_name = "missing-material-" + material.name();
material_name = "missing-material-" + material.name;
}
collada_id(material_name);
@@ -355,19 +353,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);
@@ -401,7 +399,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);
+11 -11
View File
@@ -41,10 +41,10 @@
#pragma GCC diagnostic pop
#endif
#include "../ifcgeom_schema_agnostic/IfcGeomIterator.h"
#include "../ifcgeom/Iterator.h"
#include "../serializers/serializers_api.h"
#include "../ifcgeom_schema_agnostic/GeometrySerializer.h"
#include "../ifcgeom/GeometrySerializer.h"
#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/io.hpp>
@@ -75,7 +75,7 @@ private:
const std::string &mesh_id, const std::string &default_material_name,
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<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;
@@ -89,7 +89,7 @@ private:
const std::string scene_id;
bool scene_opened;
std::stack<COLLADASW::Node*> parentNodes;
std::stack<IfcGeom::Transformation> matrixStack;
std::stack<ifcopenshell::geometry::taxonomy::matrix4> matrixStack;
public:
ColladaScene(const std::string& scene_id, COLLADASW::StreamWriter& stream, ColladaSerializer *_serializer)
: COLLADASW::LibraryVisualScenes(&stream)
@@ -118,11 +118,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)
@@ -130,9 +130,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;
@@ -165,14 +165,14 @@ private:
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<double> uvs;
std::vector<const IfcGeom::Element*> parents_;
DeferredObject(const std::string& unique_id, const std::string& representation_id, const std::string& type, const IfcGeom::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<IfcGeom::Material>& materials,
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)
+14 -13
View File
@@ -78,29 +78,29 @@ void GltfSerializer::writeHeader() {
json_["materials"] = json::array();
}
int GltfSerializer::writeMaterial(const IfcGeom::Material& style) {
auto it = materials_.find(style.name());
int GltfSerializer::writeMaterial(const ifcopenshell::geometry::taxonomy::style& style) {
auto it = materials_.find(style.name);
if (it != materials_.end()) {
return it->second;
}
int idx = json_["materials"].size();
materials_[style.name()] = idx;
materials_[style.name] = idx;
std::array<double, 4> base;
base.fill(1.0);
if (style.hasDiffuse()) {
if (style.diffuse) {
for (int i = 0; i < 3; ++i) {
base[i] = style.diffuse()[i];
base[i] = style.diffuse.ccomponents()(i);
}
}
if (style.hasTransparency()) {
base[3] = 1. - style.transparency();
if (style.transparency == style.transparency) {
base[3] = 1. - style.transparency;
}
json_["materials"].push_back({ {"pbrMetallicRoughness", {{"baseColorFactor", base}, {"metallicFactor", 0}}} });
if (style.hasTransparency() && style.transparency() > 1.e-9) {
if (style.transparency == style.transparency && style.transparency > 1.e-9) {
json_["materials"].back()["alphaMode"] = "BLEND";
}
@@ -164,13 +164,14 @@ void GltfSerializer::write(const IfcGeom::TriangulationElement* o) {
node_array_.push_back(json_["nodes"].size());
const std::vector<double>& m = o->transformation().matrix().data();
const auto& m = o->transformation().data().ccomponents();
// nb: note that this contains the Y-UP transform as well.
// @todo check
const std::array<double, 16> matrix_flat = {
m[0], m[ 2], -m[ 1], 0,
m[3], m[ 5], -m[ 4], 0,
m[6], m[ 8], -m[ 7], 0,
m[9], m[11], -m[10], 1
m(0,0), m(2,0), -m(1,0), m(3,0),
m(0,1), m(2,1), -m(1,1), m(3,1),
m(0,2), m(2,2), -m(1,2), m(3,2),
m(0,3), m(2,3), -m(1,3), m(3,3)
};
static const std::array<double, 16> identity_matrix = {1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1};
+2 -2
View File
@@ -23,7 +23,7 @@
#ifdef WITH_GLTF
#include "../serializers/serializers_api.h"
#include "../ifcgeom_schema_agnostic/GeometrySerializer.h"
#include "../ifcgeom/GeometrySerializer.h"
#include <nlohmann/json.hpp>
using json = nlohmann::json;
@@ -37,7 +37,7 @@ private:
std::map<std::string, int> materials_, meshes_;
json json_, node_array_;
int writeMaterial(const IfcGeom::Material& style);
int writeMaterial(const ifcopenshell::geometry::taxonomy::style& style);
public:
GltfSerializer(const std::string& filename, const SerializerSettings& settings);
virtual ~GltfSerializer();
+54 -110
View File
@@ -21,7 +21,8 @@
#include "HdfSerializer.h"
#include "../ifcgeom_schema_agnostic/IfcGeomRenderStyles.h"
#include "../ifcgeom/IfcGeomRenderStyles.h"
#include "../ifcgeom/kernels/opencascade/OpenCascadeConversionResult.h"
#include "../ifcparse/utils.h"
@@ -232,28 +233,19 @@ namespace {
}
}
void HdfSerializer::read_surface_style(surface_style_serialization& s, std::shared_ptr<IfcGeom::SurfaceStyle>& style_ptr) {
void HdfSerializer::read_surface_style(surface_style_serialization& s, ifcopenshell::geometry::taxonomy::style& gss) {
if (strlen(s.name) || s.id) {
if (strlen(s.name) && s.id) {
style_ptr = std::make_shared<IfcGeom::SurfaceStyle>(s.id, s.name);
} else if (strlen(s.name)) {
style_ptr = std::make_shared<IfcGeom::SurfaceStyle>(s.name);
} else if (s.id) {
style_ptr = std::make_shared<IfcGeom::SurfaceStyle>(s.id);
}
auto& gss = *style_ptr;
if (s.diffuse[0] == s.diffuse[0]) {
gss.Diffuse().emplace(s.diffuse[0], s.diffuse[1], s.diffuse[2]);
gss.diffuse = ifcopenshell::geometry::taxonomy::colour(s.diffuse[0], s.diffuse[1], s.diffuse[2]);
}
if (s.specular[0] == s.specular[0]) {
gss.Specular().emplace(s.specular[0], s.specular[1], s.specular[2]);
gss.specular = ifcopenshell::geometry::taxonomy::colour(s.specular[0], s.specular[1], s.specular[2]);
}
if (s.transparency == s.transparency) {
gss.Transparency() = s.transparency;
gss.transparency = s.transparency;
}
if (s.specularity == s.specularity) {
gss.Specularity() = s.specularity;
gss.specularity = s.specularity;
}
}
@@ -282,15 +274,12 @@ IfcGeom::Element* HdfSerializer::read(IfcParse::IfcFile& f, const std::string& g
std::string context = read_scalar_attribute<std::string>(element_group, "context");
std::string unique_id = read_scalar_attribute<std::string>(element_group, "unique_id");
gp_Trsf trsf;
ifcopenshell::geometry::taxonomy::matrix4 trsf;
auto placeds = element_group.openDataSet(DATASET_NAME_PLACEMENT);
double m44[4][4];
placeds.read(m44, H5::PredType::NATIVE_DOUBLE);
trsf.SetValues(
m44[0][0], m44[0][1], m44[0][2], m44[0][3],
m44[1][0], m44[1][1], m44[1][2], m44[1][3],
m44[2][0], m44[2][1], m44[2][2], m44[2][3]
);
// @todo check
trsf.components() << Eigen::Map<Eigen::Matrix4d>(&m44[0][0]);
auto representation_group = element_group.openGroup(representation_id_str);
std::string geom_id = read_scalar_attribute<std::string>(representation_group, "geom_id");
@@ -353,66 +342,27 @@ IfcGeom::Element* HdfSerializer::read(IfcParse::IfcFile& f, const std::string& g
brepDataset.read(parts.data(), compound);
}
IfcGeom::IfcRepresentationShapeItems shapes;
IfcGeom::ConversionResults shapes;
for (auto& part : parts) {
TopoDS_Shape shp = read_shape(part.shape_serialization);
// The gp_GTrsf(Mat, V) constructor isn't very smart in that
// it sets the Form to gp_Other. This, in turn, then means that
// in IfcOpenShell when the BRepElement is cast to a TopoDS_Compound
// (happens e.g in SVG and Python), and the trsf is multiplied into
// the shape, it is automatically converted to a Nurbs object.
// For this reason we do a quick identity check so that we in that
// case can keep the Form at gp_Identity. Better yet would be to
// do a full decomposition of the matrix in Translation Rotation and
// Scale components and use the OCCT APIs to reconstruct the Trsf
// from that.
// @todo check
ifcopenshell::geometry::taxonomy::matrix4 matrix;
matrix.components() << Eigen::Map<Eigen::Matrix4d>(&part.matrix[0][0]);
gp_Mat M(
part.matrix[0][0], part.matrix[0][1], part.matrix[0][2],
part.matrix[1][0], part.matrix[1][1], part.matrix[1][2],
part.matrix[2][0], part.matrix[2][1], part.matrix[2][2]
);
bool is_identity = true;
// quick identity test
for (int i = 1; i < 4; ++i) {
for (int j = 1; j < 4; ++j) {
if (std::fabs(M.Row(i).Coord(j) - ((i == j) ? 1.0 : 0.0)) > 1.e-9) {
is_identity = false;
}
}
}
gp_XYZ V(
part.matrix[3][0], part.matrix[3][1], part.matrix[3][2]
);
if (gp_Pnt(V).Distance(gp::Origin()) > 1.e-9) {
is_identity = false;
}
gp_GTrsf trsf;
auto style_ptr = new ifcopenshell::geometry::taxonomy::style;
read_surface_style(part.surface_style, *style_ptr);
if (!is_identity) {
trsf = gp_GTrsf(M, V);
trsf.SetForm();
}
std::shared_ptr<IfcGeom::SurfaceStyle> style_ptr;
read_surface_style(part.surface_style, style_ptr);
shapes.push_back(IfcGeom::IfcRepresentationShapeItem(part.id, trsf, shp, style_ptr));
shapes.push_back(IfcGeom::ConversionResult(part.id, matrix, new ifcopenshell::geometry::OpenCascadeShape(shp), style_ptr));
}
// World coordinates can be applied post-hoc
if (settings_.get(IfcGeom::IteratorSettings::USE_WORLD_COORDS) && !(stored_settings & IfcGeom::IteratorSettings::USE_WORLD_COORDS)) {
for (IfcGeom::IfcRepresentationShapeItems::iterator it = shapes.begin(); it != shapes.end(); ++it) {
for (IfcGeom::ConversionResults::iterator it = shapes.begin(); it != shapes.end(); ++it) {
it->prepend(trsf);
}
trsf = gp_Trsf();
trsf = ifcopenshell::geometry::taxonomy::matrix4();
}
brep_geometry = boost::shared_ptr<IfcGeom::Representation::BRep>(new IfcGeom::Representation::BRep(element_settings, geom_id, shapes));
@@ -456,7 +406,7 @@ IfcGeom::Element* HdfSerializer::read(IfcParse::IfcFile& f, const std::string& g
ds.read(surface_styles.data(), style_compound);
}
std::vector<std::shared_ptr<IfcGeom::SurfaceStyle>> surface_style_ptrs(surface_styles.size());
std::vector<ifcopenshell::geometry::taxonomy::style> surface_style_ptrs(surface_styles.size());
for (size_t i = 0; i < surface_styles.size(); ++i) {
read_surface_style(surface_styles[i], surface_style_ptrs[i]);
@@ -497,21 +447,6 @@ IfcGeom::Element* HdfSerializer::read(IfcParse::IfcFile& f, const std::string& g
}
}
namespace {
std::array<std::array<double, 4>, 4> gtrsf_to_matrix(const gp_GTrsf& trsf) {
std::array<std::array<double, 4>, 4> arr;
for (int i = 1; i < 5; ++i) {
for (int j = 1; j < 4; ++j) {
arr[i-1][j-1] = trsf.Value(j, i);
}
arr[i - 1][3] = i == 4 ? 1.0 : 0.0;
}
return arr;
}
}
H5::Group HdfSerializer::write(const IfcGeom::Element* o) {
try {
return file.openGroup(o->guid());
@@ -552,12 +487,13 @@ H5::Group HdfSerializer::write(const IfcGeom::Element* o) {
H5::DataSpace dataspace_4x4(2, dims_4x4);
auto placement_dataset = element_group.createDataSet(DATASET_NAME_PLACEMENT, H5::PredType::NATIVE_DOUBLE, dataspace_4x4);
const std::vector<double>& m43 = o->transformation().matrix().data();
const auto& m = o->transformation().data().ccomponents();
// @todo check, is this needed, can we use the storage of Eigen?
double m44[4][4] = {
{ m43[0], m43[3], m43[6], m43[9] },
{ m43[1], m43[4], m43[7], m43[10] },
{ m43[2], m43[5], m43[8], m43[11] },
{ 0, 0, 0, 1 }
{ m(0,0), m(1,0), m(2,0), m(3,0) },
{ m(0,1), m(1,1), m(2,1), m(3,1) },
{ m(0,2), m(1,2), m(2,2), m(3,2) },
{ m(0,3), m(1,3), m(2,3), m(3,3) }
};
placement_dataset.write(m44, H5::PredType::NATIVE_DOUBLE);
@@ -588,25 +524,26 @@ H5::Group HdfSerializer::createRepresentationGroup(const H5::Group& element_grou
return representation_group;
}
void HdfSerializer::write_style(surface_style_serialization& data, const IfcGeom::SurfaceStyle& s) {
data.name = s.Name().c_str();
data.original_name = s.original_name().c_str();
data.id = s.Id().get_value_or(0);
if (s.Diffuse()) {
data.diffuse[0] = s.Diffuse()->R();
data.diffuse[1] = s.Diffuse()->G();
data.diffuse[2] = s.Diffuse()->B();
void HdfSerializer::write_style(surface_style_serialization& data, const ifcopenshell::geometry::taxonomy::style& s) {
data.name = s.name.c_str();
// @todo
data.original_name = s.name.c_str();
data.id = s.instance->data().id();
if (s.diffuse) {
data.diffuse[0] = s.diffuse.ccomponents()(0);
data.diffuse[1] = s.diffuse.ccomponents()(1);
data.diffuse[2] = s.diffuse.ccomponents()(2);
}
if (s.Specular()) {
data.specular[0] = s.Specular()->R();
data.specular[1] = s.Specular()->G();
data.specular[2] = s.Specular()->B();
if (s.specular) {
data.specular[0] = s.specular.ccomponents()(0);
data.specular[1] = s.specular.ccomponents()(1);
data.specular[2] = s.specular.ccomponents()(2);
}
if (s.Transparency()) {
data.transparency = *s.Transparency();
if (s.transparency == s.transparency) {
data.transparency = s.transparency;
}
if (s.Specularity()) {
data.specularity = *s.Specularity();
if (s.specularity == s.specularity) {
data.specularity = s.specularity;
}
}
@@ -636,13 +573,20 @@ void HdfSerializer::write(const IfcGeom::BRepElement* o) {
size_t i = 0;
for (auto it = o->geometry().begin(); it != o->geometry().end(); ++it, ++i) {
parts[i].id = it->ItemId();
std::array<std::array<double, 4>, 4> arr = gtrsf_to_matrix(it->Placement());
const auto& m = o->transformation().data().ccomponents();
// @todo check, is this needed, can we use the storage of Eigen?
std::array<std::array<double, 4>, 4> arr = { {
{ { m(0,0), m(1,0), m(2,0), m(3,0) } },
{ { m(0,1), m(1,1), m(2,1), m(3,1) } },
{ { m(0,2), m(1,2), m(2,2), m(3,2) } },
{ { m(0,3), m(1,3), m(2,3), m(3,3) } }
} };
for (int j = 0; j < 4; ++j) {
std::copy(arr[j].begin(), arr[j].end(), parts[i].matrix[j]);
}
brep_strings.emplace_back();
write_shape(it->Shape(), brep_strings.back());
write_shape(((ifcopenshell::geometry::OpenCascadeShape*)it->Shape())->shape(), brep_strings.back());
parts[i].surface_style = { "", "", 0, {nan,nan,nan}, {nan,nan,nan}, nan, nan };
if (it->hasStyle()) {
@@ -710,7 +654,7 @@ void HdfSerializer::write(const IfcGeom::TriangulationElement* o) {
data.reserve(ts.size());
for (auto& m : ts) {
data.emplace_back();
write_style(data.back(), m.get_style());
write_style(data.back(), m);
}
auto ds = meshGroup.createDataSet(DATASET_NAME_MATERIALS, dt, dataspace);
+3 -3
View File
@@ -29,7 +29,7 @@
#include "H5Cpp.h"
#include "../serializers/serializers_api.h"
#include "../ifcgeom_schema_agnostic/GeometrySerializer.h"
#include "../ifcgeom/GeometrySerializer.h"
#define USE_BINARY
@@ -88,8 +88,8 @@ private:
std::map<std::string, std::string> group_cache_;
H5::Group createRepresentationGroup(const H5::Group& element_group, const std::string& gid);
void read_surface_style(surface_style_serialization& sss, std::shared_ptr<IfcGeom::SurfaceStyle>& style_ptr);
void write_style(surface_style_serialization& data, const IfcGeom::SurfaceStyle& s);
void read_surface_style(surface_style_serialization& sss, ifcopenshell::geometry::taxonomy::style& style_ptr);
void write_style(surface_style_serialization& data, const ifcopenshell::geometry::taxonomy::style& s);
public:
HdfSerializer(const std::string& hdf_filename, const SerializerSettings& settings, bool read_only=false);
@@ -20,6 +20,7 @@
#include "OpenCascadeBasedSerializer.h"
#include "../ifcparse/utils.h"
#include "../ifcgeom/kernels/opencascade/OpenCascadeConversionResult.h"
#include <string>
#include <fstream>
@@ -37,13 +38,10 @@ bool OpenCascadeBasedSerializer::ready() {
}
void OpenCascadeBasedSerializer::write(const IfcGeom::BRepElement* o) {
TopoDS_Shape compound = o->geometry().as_compound();
gp_Trsf trsf = o->transformation().data();
const IfcGeom::ElementSettings& settings = o->geometry().settings();
if (settings.get(IfcGeom::IteratorSettings::CONVERT_BACK_UNITS) && settings.unit_magnitude() != 1.0) {
trsf.SetTranslationPart(trsf.TranslationPart() / settings.unit_magnitude());
}
writeShape(object_id(o), compound.Moved(trsf));
auto itm = o->geometry().as_compound();
TopoDS_Shape compound = ((ifcopenshell::geometry::OpenCascadeShape*)itm)->shape();
writeShape(object_id(o), compound);
delete itm;
}
#define RATHER_SMALL (1e-3)
+2 -2
View File
@@ -21,9 +21,9 @@
#define OPENCASCADEBASEDSERIALIZER_H
#include "../serializers/serializers_api.h"
#include "../ifcgeom_schema_agnostic/IfcGeomIterator.h"
#include "../ifcgeom/Iterator.h"
#include "../ifcgeom_schema_agnostic/GeometrySerializer.h"
#include "../ifcgeom/GeometrySerializer.h"
class SERIALIZERS_API OpenCascadeBasedSerializer : public WriteOnlyGeometrySerializer {
OpenCascadeBasedSerializer(const OpenCascadeBasedSerializer&); //N/A
+1 -1
View File
@@ -23,7 +23,7 @@
#include <STEPControl_Writer.hxx>
#include <Interface_Static.hxx>
#include "../ifcgeom_schema_agnostic/IfcGeomIterator.h"
#include "../ifcgeom/Iterator.h"
#include "../serializers/OpenCascadeBasedSerializer.h"
+47 -21
View File
@@ -19,7 +19,7 @@
* *
********************************************************************************/
#include "../ifcgeom_schema_agnostic/Kernel.h"
#include "../ifcgeom/abstract_mapping.h"
#include <string>
#include <fstream>
@@ -78,7 +78,8 @@
#include <Extrema_ExtPElS.hxx>
#include "../ifcparse/IfcGlobalId.h"
#include "../ifcgeom_schema_agnostic/base_utils.h"
#include "../ifcgeom/kernels/opencascade/base_utils.h"
#include "../ifcgeom/kernels/opencascade/OpenCascadeConversionResult.h"
#include <boost/format.hpp>
#include <boost/tokenizer.hpp>
@@ -353,7 +354,7 @@ void SvgSerializer::write(path_object& p, const TopoDS_Shape& comp_or_wire, boos
p.second.push_back(path);
}
SvgSerializer::path_object& SvgSerializer::start_path(const gp_Pln& pln, IfcUtil::IfcBaseEntity* storey, const std::string& id) {
SvgSerializer::path_object& SvgSerializer::start_path(const gp_Pln& pln, const IfcUtil::IfcBaseEntity* storey, const std::string& id) {
auto key = std::make_pair(std::make_pair(storey, ""), path_object());
SvgSerializer::path_object& p = paths.insert(key)->second;
drawing_metadata[key.first].pln_3d = pln;
@@ -370,7 +371,7 @@ SvgSerializer::path_object& SvgSerializer::start_path(const gp_Pln& pln, const s
}
namespace {
boost::optional<std::pair<IfcUtil::IfcBaseEntity*, double>> storey_elevation_from_element(const IfcGeom::BRepElement* o) {
boost::optional<std::pair<const IfcUtil::IfcBaseEntity*, double>> storey_elevation_from_element(const IfcGeom::BRepElement* o) {
for (const auto& p : o->parents()) {
if (p->type() == "IfcBuildingStorey") {
try {
@@ -476,7 +477,7 @@ namespace {
};
template <typename It>
void enumerate_string_properties(IfcUtil::IfcBaseEntity* product, It output_it) {
void enumerate_string_properties(const IfcUtil::IfcBaseEntity* product, It output_it) {
auto rels = product->get_inverse("IsDefinedBy");
for (auto& rel : *rels) {
if (rel->declaration().is("IfcRelDefinesByProperties")) {
@@ -543,7 +544,10 @@ void SvgSerializer::write(const IfcGeom::BRepElement* brep_obj) {
std::vector<boost::optional<std::vector<double>>> dash_arrays;
TopoDS_Shape compound_local = brep_obj->geometry().as_compound();
auto itm = brep_obj->geometry().as_compound();
TopoDS_Shape compound_local = ((ifcopenshell::geometry::OpenCascadeShape*)itm)->shape();
delete itm;
for (auto& x : brep_obj->geometry()) {
dash_arrays.emplace_back();
@@ -574,7 +578,14 @@ void SvgSerializer::write(const IfcGeom::BRepElement* brep_obj) {
}
}
const gp_Trsf& trsf = brep_obj->transformation().data();
gp_Trsf trsf;
// @todo
const auto& m = brep_obj->transformation().data().ccomponents();
trsf.SetValues(
m(0, 0), m(0, 1), m(0, 2), m(0, 3),
m(1, 0), m(1, 1), m(1, 2), m(1, 3),
m(2, 0), m(2, 1), m(2, 2), m(2, 3)
);
const bool is_section = (section_ref_ && object_type && *section_ref_ == *object_type);
bool is_elevation = false;
@@ -693,7 +704,7 @@ void SvgSerializer::write(const IfcGeom::BRepElement* brep_obj) {
}
auto p = storey_elevation_from_element(brep_obj);
IfcUtil::IfcBaseEntity* storey = p ? p->first : nullptr;
const IfcUtil::IfcBaseEntity* storey = p ? p->first : nullptr;
double elev = p ? p->second : std::numeric_limits<double>::quiet_NaN();
// @todo is it correct to call nameElement() here with a single storey (what if this element spans multiple?)
geometry_data data{ compound_local, dash_arrays, trsf, brep_obj->product(), storey, elev, brep_obj->name(), nameElement(storey, brep_obj) };
@@ -891,7 +902,7 @@ void SvgSerializer::write(const geometry_data& data) {
gp_Vec projection_direction;
gp_Pln projection_plane;
IfcUtil::IfcBaseEntity* storey = nullptr;
const IfcUtil::IfcBaseEntity* storey = nullptr;
std::string drawing_name;
bool use_hlr = always_project_;
@@ -1874,9 +1885,19 @@ void SvgSerializer::addTextAnnotations(const drawing_key& k) {
auto desc = (std::string) *ds;
if (object_type == "Text") {
IfcGeom::Kernel kernel(file);
gp_Trsf trsf;
if (kernel.convert_placement(*pl, trsf)) {
auto mapping = ifcopenshell::geometry::impl::mapping_implementations().construct(file, settings_);
auto item = mapping->map(*pl);
auto matrix = (ifcopenshell::geometry::taxonomy::matrix4*) item;
delete mapping;
if (item) {
gp_Trsf trsf;
auto& m = matrix->ccomponents();
trsf.SetValues(
m(0, 0), m(0, 1), m(0, 2), m(0, 3),
m(1, 0), m(1, 1), m(1, 2), m(1, 3),
m(2, 0), m(2, 1), m(2, 2), m(2, 3)
);
delete matrix;
auto v = gp_Pnt(trsf.TranslationPart());
@@ -2319,8 +2340,7 @@ void SvgSerializer::setFile(IfcParse::IfcFile* f) {
auto storeys = f->instances_by_type("IfcBuildingStorey");
if (!storeys || storeys->size() == 0) {
IfcGeom::Kernel kernel(f);
auto mapping = ifcopenshell::geometry::impl::mapping_implementations().construct(file, settings_);
std::vector<const IfcParse::declaration*> to_derive_from;
to_derive_from.push_back(f->schema()->declaration_by_name("IfcBuilding"));
@@ -2331,9 +2351,13 @@ void SvgSerializer::setFile(IfcParse::IfcFile* f) {
for (auto jt = insts->begin(); jt != insts->end(); ++jt) {
IfcUtil::IfcBaseEntity* product = (IfcUtil::IfcBaseEntity*) *jt;
if (!product->get("ObjectPlacement")->isNull()) {
auto item = mapping->map(*product->get("ObjectPlacement"));
auto matrix = (ifcopenshell::geometry::taxonomy::matrix4*) item;
gp_Trsf trsf;
if (kernel.convert_placement(*product->get("ObjectPlacement"), trsf)) {
setSectionHeight(trsf.TranslationPart().Z() + 1.);
if (matrix) {
// @todo shouldn't this take into account configurable section height?
setSectionHeight(matrix->translation_part()(3) + 1.);
delete matrix;
Logger::Warning("No building storeys encountered, used for reference:", product);
return;
}
@@ -2342,11 +2366,13 @@ void SvgSerializer::setFile(IfcParse::IfcFile* f) {
}
}
delete mapping;
Logger::Warning("No building storeys encountered, output might be invalid or missing");
}
}
void SvgSerializer::setSectionHeight(double h, IfcUtil::IfcBaseEntity* storey) {
void SvgSerializer::setSectionHeight(double h, const IfcUtil::IfcBaseEntity* storey) {
section_data_.emplace();
section_data_->push_back(horizontal_plan{ storey, h, 0., std::numeric_limits<double>::infinity() });
}
@@ -2401,11 +2427,11 @@ namespace {
std::string SvgSerializer::writeMetadata(const drawing_meta& m) {
gp_Trsf trsf;
trsf.SetTransformation(m.pln_3d.Position(), gp::XOY());
auto m43 = IfcGeom::Matrix(IfcGeom::ElementSettings(IfcGeom::IteratorSettings(), 1., ""), trsf).data();
// @todo
std::array<std::array<double, 4>, 4> m4 = {{
{{ (double)m43[0], (double)m43[3], (double)m43[6], (double)m43[9] }},
{{ (double)m43[1], (double)m43[4], (double)m43[7], (double)m43[10] }},
{{ (double)m43[2], (double)m43[5], (double)m43[8], (double)m43[11] }},
{{ 1, 0, 0, 0 }},
{{ 0, 1, 0, 0 }},
{{ 0, 0, 1, 0 }},
{{ 0, 0, 0, 1 }}
}};
return namespace_prefix_ + "plane=\""+ array_to_string(m4) +"\" " +
+10 -10
View File
@@ -22,7 +22,7 @@
#ifndef SVGSERIALIZER_H
#define SVGSERIALIZER_H
#include "../ifcgeom_schema_agnostic/GeometrySerializer.h"
#include "../ifcgeom/GeometrySerializer.h"
#include "../serializers/serializers_api.h"
#include "../serializers/util.h"
@@ -44,7 +44,7 @@
#include <string>
#include <limits>
typedef std::pair<IfcUtil::IfcBaseEntity*, std::string> drawing_key;
typedef std::pair<const IfcUtil::IfcBaseEntity*, std::string> drawing_key;
struct storey_sorter {
bool operator()(const drawing_key& ad, const drawing_key& bd) const {
@@ -88,12 +88,12 @@ struct storey_sorter {
}
}
}
return std::less<IfcUtil::IfcBaseEntity*>()(a, b);
return std::less<const IfcUtil::IfcBaseEntity*>()(a, b);
}
};
struct horizontal_plan {
IfcUtil::IfcBaseEntity* storey;
const IfcUtil::IfcBaseEntity* storey;
double elevation, offset, next_elevation;
};
@@ -113,8 +113,8 @@ struct geometry_data {
TopoDS_Shape compound_local;
std::vector<boost::optional<std::vector<double>>> dash_arrays;
gp_Trsf trsf;
IfcUtil::IfcBaseEntity* product;
IfcUtil::IfcBaseEntity* storey;
const IfcUtil::IfcBaseEntity* product;
const IfcUtil::IfcBaseEntity* storey;
double storey_elevation;
std::string ifc_name, svg_name;
};
@@ -169,10 +169,10 @@ protected:
int profile_threshold_;
IfcParse::IfcFile* file;
IfcUtil::IfcBaseEntity* storey_;
const IfcUtil::IfcBaseEntity* storey_;
std::multimap<drawing_key, path_object, storey_sorter> paths;
std::map<drawing_key, drawing_meta> drawing_metadata;
std::map<IfcUtil::IfcBaseEntity*, hlr_t> storey_hlr;
std::map<const IfcUtil::IfcBaseEntity*, hlr_t> storey_hlr;
float_item_list xcoords, ycoords, radii;
size_t xcoords_begin, ycoords_begin, radii_begin;
@@ -235,14 +235,14 @@ public:
void write(const IfcGeom::BRepElement* o);
void write(path_object& p, const TopoDS_Shape& wire, boost::optional<std::vector<double>> dash_array=boost::none);
void write(const geometry_data& data);
path_object& start_path(const gp_Pln& p, IfcUtil::IfcBaseEntity* storey, const std::string& id);
path_object& start_path(const gp_Pln& p, const IfcUtil::IfcBaseEntity* storey, const std::string& id);
path_object& start_path(const gp_Pln& p, const std::string& drawing_name, const std::string& id);
bool isTesselated() const { return false; }
void finalize();
void setUnitNameAndMagnitude(const std::string& /*name*/, float /*magnitude*/) {}
void setFile(IfcParse::IfcFile* f);
void setBoundingRectangle(double width, double height);
void setSectionHeight(double h, IfcUtil::IfcBaseEntity* storey = 0);
void setSectionHeight(double h, const IfcUtil::IfcBaseEntity* storey = 0);
void setSectionHeightsFromStoreys(double offset=1.2);
void setPrintSpaceNames(bool b) { print_space_names_ = b; }
void setPrintSpaceAreas(bool b) { print_space_areas_ = b; }
+29 -23
View File
@@ -20,7 +20,7 @@
#include "WavefrontObjSerializer.h"
#include "../ifcgeom_schema_agnostic/IfcGeomRenderStyles.h"
#include "../ifcgeom/IfcGeomRenderStyles.h"
#include "../ifcparse/utils.h"
@@ -59,26 +59,28 @@ void WaveFrontOBJSerializer::writeHeader() {
mtl_stream.stream << "# File generated by IfcOpenShell " << IFCOPENSHELL_VERSION << "\n";
}
void WaveFrontOBJSerializer::writeMaterial(const IfcGeom::Material& style)
void WaveFrontOBJSerializer::writeMaterial(const ifcopenshell::geometry::taxonomy::style& style)
{
std::string material_name = (settings().get(SerializerSettings::USE_MATERIAL_NAMES)
? style.original_name() : style.name());
// std::string material_name = (settings().get(SerializerSettings::USE_MATERIAL_NAMES)
// ? style.original_name() : style.name());
// @todo original_name
std::string material_name = style.name;
IfcUtil::sanitate_material_name(material_name);
mtl_stream.stream << "newmtl " << material_name << "\n";
if (style.hasDiffuse()) {
const double* diffuse = style.diffuse();
mtl_stream.stream << "Kd " << diffuse[0] << " " << diffuse[1] << " " << diffuse[2] << "\n";
{
auto& diffuse = style.diffuse.ccomponents();
mtl_stream.stream << "Kd " << diffuse(0) << " " << diffuse(1) << " " << diffuse(2) << "\n";
}
if (style.hasSpecular()) {
const double* specular = style.specular();
mtl_stream.stream << "Ks " << specular[0] << " " << specular[1] << " " << specular[2] << "\n";
if (style.specular) {
auto& specular = style.specular.ccomponents();
mtl_stream.stream << "Ks " << specular(0) << " " << specular(1) << " " << specular(2) << "\n";
}
if (style.hasSpecularity()) {
mtl_stream.stream << "Ns " << style.specularity() << "\n";
if (style.specularity == style.specularity) {
mtl_stream.stream << "Ns " << style.specularity << "\n";
}
if (style.hasTransparency()) {
const double transparency = 1.0 - style.transparency();
if (style.transparency == style.transparency) {
const double transparency = 1.0 - style.transparency;
if (transparency < 1) {
mtl_stream.stream << "d " << transparency << "\n";
}
@@ -94,7 +96,7 @@ void WaveFrontOBJSerializer::write(const IfcGeom::TriangulationElement* o)
const IfcGeom::Representation::Triangulation& mesh = o->geometry();
const int vcount = (int)mesh.verts().size() / 3;
for ( std::vector<double>::const_iterator it = mesh.verts().begin(); it != mesh.verts().end(); ) {
for (auto it = mesh.verts().begin(); it != mesh.verts().end();) {
const double x = *(it++);
const double y = *(it++);
const double z = *(it++);
@@ -106,14 +108,14 @@ void WaveFrontOBJSerializer::write(const IfcGeom::TriangulationElement* o)
}
}
for ( std::vector<double>::const_iterator it = mesh.normals().begin(); it != mesh.normals().end(); ) {
for (auto it = mesh.normals().begin(); it != mesh.normals().end();) {
const double x = *(it++);
const double y = *(it++);
const double z = *(it++);
obj_stream.stream << "vn " << x << " " << y << " " << z << "\n";
}
for (std::vector<double>::const_iterator it = mesh.uvs().begin(); it != mesh.uvs().end();) {
for (auto it = mesh.uvs().begin(); it != mesh.uvs().end();) {
const double u = *it++;
const double v = *it++;
obj_stream.stream << "vt " << u << " " << v << "\n";
@@ -128,9 +130,11 @@ void WaveFrontOBJSerializer::write(const IfcGeom::TriangulationElement* o)
const int material_id = *(material_it++);
if (material_id != previous_material_id) {
const IfcGeom::Material& material = mesh.materials()[material_id];
std::string material_name = (settings().get(SerializerSettings::USE_MATERIAL_NAMES)
? material.original_name() : material.name());
const ifcopenshell::geometry::taxonomy::style& material = mesh.materials()[material_id];
// std::string material_name = (settings().get(SerializerSettings::USE_MATERIAL_NAMES)
// ? material.original_name() : material.name());
// @todo original_name
std::string material_name = material.name;
IfcUtil::sanitate_material_name(material_name);
obj_stream.stream << "usemtl " << material_name << "\n";
if (materials.find(material_name) == materials.end()) {
@@ -172,9 +176,11 @@ void WaveFrontOBJSerializer::write(const IfcGeom::TriangulationElement* o)
const int material_id = *(material_it++);
if (material_id != previous_material_id) {
const IfcGeom::Material& material = mesh.materials()[material_id];
std::string material_name = (settings().get(SerializerSettings::USE_MATERIAL_NAMES)
? material.original_name() : material.name());
const ifcopenshell::geometry::taxonomy::style& material = mesh.materials()[material_id];
// std::string material_name = (settings().get(SerializerSettings::USE_MATERIAL_NAMES)
// ? material.original_name() : material.name());
// @todo original_name
std::string material_name = material.name;
IfcUtil::sanitate_material_name(material_name);
obj_stream.stream << "usemtl " << material_name << "\n";
if (materials.find(material_name) == materials.end()) {
+2 -2
View File
@@ -25,7 +25,7 @@
#include <fstream>
#include "../serializers/serializers_api.h"
#include "../ifcgeom_schema_agnostic/GeometrySerializer.h"
#include "../ifcgeom/GeometrySerializer.h"
// http://people.sc.fsu.edu/~jburkardt/txt/obj_format.txt
class SERIALIZERS_API WaveFrontOBJSerializer : public WriteOnlyGeometrySerializer {
@@ -39,7 +39,7 @@ public:
virtual ~WaveFrontOBJSerializer() {}
bool ready();
void writeHeader();
void writeMaterial(const IfcGeom::Material& style);
void writeMaterial(const ifcopenshell::geometry::taxonomy::style& style);
void write(const IfcGeom::TriangulationElement* o);
void write(const IfcGeom::BRepElement* /*o*/) {}
void finalize() {}
+2 -2
View File
@@ -5,10 +5,10 @@
#include <boost/algorithm/string/case_conv.hpp>
#define EXTERNAL_DEFS(r, data, elem) \
extern void BOOST_PP_CAT(init_XmlSerializerIfc, elem)(XmlSerializerFactory::Factory*);
extern void BOOST_PP_CAT(init_XmlSerializer_Ifc, elem)(XmlSerializerFactory::Factory*);
#define CALL_DEFS(r, data, elem) \
BOOST_PP_CAT(init_XmlSerializerIfc, elem)(this);
BOOST_PP_CAT(init_XmlSerializer_Ifc, elem)(this);
BOOST_PP_SEQ_FOR_EACH(EXTERNAL_DEFS, , SCHEMA_SEQ)
+1 -1
View File
@@ -1,7 +1,7 @@
#define SCHEMA_METHOD
#include "../serializers/serializers_api.h"
#include "../ifcgeom_schema_agnostic/Serializer.h"
#include "../ifcgeom/Serializer.h"
#include "../ifcparse/IfcFile.h"
#include <boost/function.hpp>
@@ -27,7 +27,6 @@
#include <algorithm>
#include "../../ifcparse/IfcSIPrefix.h"
#include "../../ifcgeom/IfcGeom.h"
#include "../../ifcparse/utils.h"
using boost::property_tree::ptree;
@@ -35,9 +34,9 @@ using boost::property_tree::ptree;
#include "XmlSerializer.h"
namespace {
struct MAKE_TYPE_NAME(factory_t) {
struct POSTFIX_SCHEMA(factory_t) {
XmlSerializer* operator()(IfcParse::IfcFile* file, const std::string& xml_filename) const {
MAKE_TYPE_NAME(XmlSerializer)* s = new MAKE_TYPE_NAME(XmlSerializer)(file, xml_filename);
POSTFIX_SCHEMA(XmlSerializer)* s = new POSTFIX_SCHEMA(XmlSerializer)(file, xml_filename);
s->setFile(file);
return s;
}
@@ -46,18 +45,18 @@ namespace {
void MAKE_INIT_FN(XmlSerializer)(XmlSerializerFactory::Factory* mapping) {
static const std::string schema_name = STRINGIFY(IfcSchema);
MAKE_TYPE_NAME(factory_t) factory;
POSTFIX_SCHEMA(factory_t) factory;
mapping->bind(schema_name, factory);
}
namespace {
// TODO: Make this a member of XmlSerializer?
std::map<std::string, std::string> MAKE_TYPE_NAME(argument_name_map);
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 +105,7 @@ boost::optional<std::string> format_attribute(const Argument* argument, IfcUtil:
IfcUtil::IfcBaseClass* e = *argument;
if (!e->declaration().as_entity()) {
IfcUtil::IfcBaseType* f = e->as<IfcUtil::IfcBaseType>();
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.
@@ -126,20 +125,20 @@ 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::MAKE_TYPE_NAME(Kernel) kernel;
auto item = mapping->map(e);
auto matrix = (ifcopenshell::geometry::taxonomy::matrix4*) item;
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 << std::setprecision (std::numeric_limits< double >::max_digits10) << trsf_value << " ";
}
stream << ((i == 4) ? "1" : "0 ");
std::stringstream stream;
for (int i = 1; i < 5; ++i) {
for (int j = 1; j < 4; ++j) {
const double trsf_value = matrix->ccomponents()(j, i);
stream << std::setprecision (std::numeric_limits< double >::max_digits10) << trsf_value << " ";
}
value = stream.str();
}
stream << ((i == 4) ? "1" : "0 ");
}
value = stream.str();
delete item;
}
break; }
default:
@@ -149,7 +148,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 {
@@ -163,8 +162,8 @@ ptree* format_entity_instance(IfcUtil::IfcBaseEntity* instance, ptree& child, pt
std::string argument_name = instance->declaration().attribute_by_index(i)->name();
std::map<std::string, std::string>::const_iterator argument_name_it;
argument_name_it = MAKE_TYPE_NAME(argument_name_map).find(argument_name);
if (argument_name_it != MAKE_TYPE_NAME(argument_name_map).end()) {
argument_name_it = POSTFIX_SCHEMA(argument_name_map).find(argument_name);
if (argument_name_it != POSTFIX_SCHEMA(argument_name_map).end()) {
argument_name = argument_name_it->second;
}
const IfcUtil::ArgumentType argument_type = instance->data().getArgument(i)->type();
@@ -172,11 +171,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 +193,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::IfcBaseInterface* inst) {
@@ -208,11 +205,11 @@ std::string qualify_unrooted_instance(IfcUtil::IfcBaseInterface* 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, IfcUtil::IfcBaseClass* parent=nullptr) {
ptree* descend(ifcopenshell::geometry::abstract_mapping* mapping, A* instance, ptree& tree, IfcUtil::IfcBaseClass* parent=nullptr) {
if (instance->declaration().is(IfcSchema::IfcObjectDefinition::Class())) {
return descend(instance->template as<IfcSchema::IfcObjectDefinition>(), tree, parent);
return descend(mapping, instance->template as<IfcSchema::IfcObjectDefinition>(), tree, parent);
} else {
return format_entity_instance(instance, tree);
return format_entity_instance(mapping, instance, tree);
}
}
@@ -236,7 +233,7 @@ 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, IfcUtil::IfcBaseClass* parent) {
ptree* descend(ifcopenshell::geometry::abstract_mapping* mapping, IfcSchema::IfcObjectDefinition* product, ptree& tree, IfcUtil::IfcBaseClass* parent) {
if (product->declaration().is(IfcSchema::IfcElement::Class())) {
auto voids = product->as<IfcSchema::IfcElement>()->FillsVoids();
if (voids && voids->size() == 1 && (*voids->begin())->RelatingOpeningElement() != parent) {
@@ -245,7 +242,7 @@ ptree* descend(IfcSchema::IfcObjectDefinition* product, ptree& tree, IfcUtil::If
}
}
ptree& child = *format_entity_instance(product, tree);
ptree& child = *format_entity_instance(mapping, product, tree);
if (product->declaration().is(IfcSchema::IfcOpeningElement::Class())) {
IfcSchema::IfcOpeningElement* opening = product->as<IfcSchema::IfcOpeningElement>();
@@ -253,7 +250,7 @@ ptree* descend(IfcSchema::IfcObjectDefinition* product, ptree& tree, IfcUtil::If
opening, &IfcSchema::IfcOpeningElement::HasFillings, &IfcSchema::IfcRelFillsElement::RelatedBuildingElement);
for (IfcSchema::IfcElement::list::it it = fills->begin(); it != fills->end(); ++it) {
descend(*it, child, product);
descend(mapping, *it, child, product);
}
}
@@ -265,7 +262,7 @@ ptree* descend(IfcSchema::IfcObjectDefinition* product, ptree& tree, IfcUtil::If
(structure, &IfcSchema::IfcSpatialStructureElement::ContainsElements, &IfcSchema::IfcRelContainedInSpatialStructure::RelatedElements);
for (IfcSchema::IfcObjectDefinition::list::it it = elements->begin(); it != elements->end(); ++it) {
descend(*it, child, product);
descend(mapping, *it, child, product);
}
}
@@ -275,7 +272,7 @@ ptree* descend(IfcSchema::IfcObjectDefinition* product, ptree& tree, IfcUtil::If
element, &IfcSchema::IfcElement::HasOpenings, &IfcSchema::IfcRelVoidsElement::RelatedOpeningElement);
for (IfcSchema::IfcOpeningElement::list::it it = openings->begin(); it != openings->end(); ++it) {
descend(*it, child, product);
descend(mapping, *it, child, product);
}
}
@@ -295,7 +292,7 @@ ptree* descend(IfcSchema::IfcObjectDefinition* product, ptree& tree, IfcUtil::If
for (IfcSchema::IfcObjectDefinition::list::it it = structures->begin(); it != structures->end(); ++it) {
IfcSchema::IfcObjectDefinition* ob = *it;
descend(ob, child, product);
descend(mapping, ob, child, product);
}
if (product->declaration().is(IfcSchema::IfcObject::Class())) {
@@ -308,9 +305,9 @@ ptree* descend(IfcSchema::IfcObjectDefinition* product, ptree& tree, IfcUtil::If
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);
} else if (pset->declaration().is(IfcSchema::IfcElementQuantity::Class())) {
format_entity_instance(pset, child, true);
format_entity_instance(mapping, pset, child, true);
}
}
@@ -326,19 +323,19 @@ ptree* descend(IfcSchema::IfcObjectDefinition* product, ptree& tree, IfcUtil::If
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();
@@ -347,7 +344,7 @@ ptree* descend(IfcSchema::IfcObjectDefinition* product, ptree& tree, IfcUtil::If
IfcSchema::IfcMaterialSelect* mat = (*it)->as<IfcSchema::IfcRelAssociatesMaterial>()->RelatingMaterial();
ptree node;
node.put("<xmlattr>.xlink:href", "#" + qualify_unrooted_instance(mat));
format_entity_instance(mat->as<IfcUtil::IfcBaseEntity>(), node, child, true);
format_entity_instance(mapping, mat->as<IfcUtil::IfcBaseEntity>(), node, child, true);
}
}
}
@@ -356,19 +353,19 @@ ptree* descend(IfcSchema::IfcObjectDefinition* product, ptree& tree, IfcUtil::If
}
// 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 = p->as<IfcSchema::IfcComplexProperty>();
format_properties(complex->HasProperties(), node);
format_properties(mapping, complex->HasProperties(), node);
} else {
format_entity_instance(p, node);
format_entity_instance(mapping, p, node);
}
}
}
void writeGroupToNode(IfcSchema::IfcGroup* group, ptree& node, std::set<std::string>notRootGroups) {
void writeGroupToNode(ifcopenshell::geometry::abstract_mapping* mapping, IfcSchema::IfcGroup* group, ptree& node, std::set<std::string>notRootGroups) {
// @todo tfk: instead of a set<string> shouldn't we just have a set<IfcGroup>, the current approach
// might not work with non-unique or NIL group names.
@@ -381,7 +378,7 @@ void writeGroupToNode(IfcSchema::IfcGroup* group, ptree& node, std::set<std::str
return;
}
// Write one group to root
ptree* node2 = descend(group, node);
ptree* node2 = descend(mapping, group, node);
auto father = group->IsGroupedBy();
for (auto iter = father->begin(); iter != father->end(); iter++)
{
@@ -390,39 +387,39 @@ void writeGroupToNode(IfcSchema::IfcGroup* group, ptree& node, std::set<std::str
for (auto objit = objs->begin(); objit != objs->end(); objit++) {
auto entity = *objit;
if (entity->declaration().is(IfcSchema::IfcGroup::Class()) && entity->Name()) {
writeGroupToNode(entity->as<IfcSchema::IfcGroup>(), *node2, notRootGroups);
writeGroupToNode(mapping, entity->as<IfcSchema::IfcGroup>(), *node2, notRootGroups);
notRootGroups.emplace(*entity->Name());
}
else {
// Write child to father group
descend(entity, *node2);
descend(mapping, entity, *node2);
}
}
}
}
// 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 (node2 && p->declaration().is(IfcSchema::IfcPhysicalComplexQuantity::Class())) {
IfcSchema::IfcPhysicalComplexQuantity* complex = p->as<IfcSchema::IfcPhysicalComplexQuantity>();
format_quantities(complex->HasQuantities(), *node2);
format_quantities(mapping, complex->HasQuantities(), *node2);
}
}
}
// Format IfcTask instances and insert into the DOM.
void format_tasks(IfcSchema::IfcTask* task, ptree& node) {
ptree* ntask = format_entity_instance(task, node);
void format_tasks(ifcopenshell::geometry::abstract_mapping* mapping, IfcSchema::IfcTask* task, ptree& node) {
ptree* ntask = format_entity_instance(mapping, task, node);
if (ntask) {
#ifdef SCHEMA_IfcTask_HAS_TaskTime
IfcSchema::IfcTaskTime* task_time = task->TaskTime();
if (task_time)
{
format_entity_instance(task_time, *ntask);
format_entity_instance(mapping, task_time, *ntask);
}
#endif
@@ -455,10 +452,10 @@ void format_tasks(IfcSchema::IfcTask* task, ptree& node) {
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, *ntask, true);
format_entity_instance(mapping, pset, *ntask, true);
}
else if (pset->declaration().is(IfcSchema::IfcElementQuantity::Class())) {
format_entity_instance(pset, *ntask, true);
format_entity_instance(mapping, pset, *ntask, true);
}
}
@@ -521,7 +518,7 @@ void format_tasks(IfcSchema::IfcTask* task, ptree& node) {
continue;
}
IfcSchema::IfcTask* task2 = (*it2)->as<IfcSchema::IfcTask>();
format_tasks(task2, *ntask);
format_tasks(mapping, task2, *ntask);
}
}
#endif
@@ -530,8 +527,8 @@ void format_tasks(IfcSchema::IfcTask* task, ptree& node) {
} // ~unnamed namespace
void MAKE_TYPE_NAME(XmlSerializer)::finalize() {
MAKE_TYPE_NAME(argument_name_map).insert(std::make_pair("GlobalId", "id"));
void POSTFIX_SCHEMA(XmlSerializer)::finalize() {
POSTFIX_SCHEMA(argument_name_map).insert(std::make_pair("GlobalId", "id"));
IfcSchema::IfcProject::list::ptr projects = file->instances_by_type<IfcSchema::IfcProject>();
if (projects->size() != 1) {
@@ -605,15 +602,15 @@ void MAKE_TYPE_NAME(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);
ptree* node = format_entity_instance(mapping_, pset, properties);
if (node) {
format_properties(pset->HasProperties(), *node);
format_properties(mapping_, pset->HasProperties(), *node);
}
}
@@ -621,7 +618,7 @@ void MAKE_TYPE_NAME(XmlSerializer)::finalize() {
IfcSchema::IfcGroup::list::ptr gsets = file->instances_by_type<IfcSchema::IfcGroup>();
std::set<std::string> notRootGroups; //selfname, fathername
for (IfcSchema::IfcGroup::list::it it = gsets->begin(); it != gsets->end(); ++it) {
writeGroupToNode(*it, groups, notRootGroups);
writeGroupToNode(mapping_, *it, groups, notRootGroups);
}
for (auto it = groups.begin(); it != groups.end();) {
if (notRootGroups.find(it->second.get<std::string>("<xmlattr>.Name")) != notRootGroups.end()) {
@@ -635,9 +632,9 @@ void MAKE_TYPE_NAME(XmlSerializer)::finalize() {
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);
ptree* node = format_entity_instance(mapping_, qto, quantities);
if (node) {
format_quantities(qto->Quantities(), *node);
format_quantities(mapping_, qto->Quantities(), *node);
}
}
@@ -646,7 +643,7 @@ void MAKE_TYPE_NAME(XmlSerializer)::finalize() {
IfcSchema::IfcWorkSchedule::list::ptr pschedules = file->instances_by_type<IfcSchema::IfcWorkSchedule>();
for (IfcSchema::IfcWorkSchedule::list::it it = pschedules->begin(); it != pschedules->end(); ++it) {
IfcSchema::IfcWorkSchedule* schedule = *it;
ptree* nschedule = format_entity_instance(schedule, pwork_schedules);
ptree* nschedule = format_entity_instance(mapping_, schedule, pwork_schedules);
if(nschedule) {
IfcSchema::IfcRelAssignsToControl::list::ptr controls = schedule->Controls();
@@ -659,7 +656,7 @@ void MAKE_TYPE_NAME(XmlSerializer)::finalize() {
if (object && object->declaration().is(IfcSchema::IfcTask::Class())) {
IfcSchema::IfcTask* task = object->as<IfcSchema::IfcTask>();
format_tasks(task, *nschedule);
format_tasks(mapping_, task, *nschedule);
}
}
}
@@ -672,7 +669,7 @@ void MAKE_TYPE_NAME(XmlSerializer)::finalize() {
IfcSchema::IfcWorkPlan::list::ptr pplans = file->instances_by_type<IfcSchema::IfcWorkPlan>();
for (IfcSchema::IfcWorkPlan::list::it it = pplans->begin(); it != pplans->end(); ++it) {
IfcSchema::IfcWorkPlan* plan = *it;
ptree* nschedule = format_entity_instance(plan, pwork_plans);
ptree* nschedule = format_entity_instance(mapping_, plan, pwork_plans);
if (nschedule) {
#ifdef SCHEMA_IfcObjectDefinition_HAS_IsDecomposedBy
@@ -698,7 +695,7 @@ void MAKE_TYPE_NAME(XmlSerializer)::finalize() {
IfcSchema::IfcWorkCalendar::list::ptr pcalendars = file->instances_by_type<IfcSchema::IfcWorkCalendar>();
for (IfcSchema::IfcWorkCalendar::list::it it = pcalendars->begin(); it != pcalendars->end(); ++it) {
IfcSchema::IfcWorkCalendar* calendar = *it;
ptree* ncalendar = format_entity_instance(calendar, calendars);
ptree* ncalendar = format_entity_instance(mapping_, calendar, calendars);
if (ncalendar) {
IfcSchema::IfcWorkTime::list::ptr working_times = calendar->WorkingTimes().value_or(nullptr);
@@ -706,7 +703,7 @@ void MAKE_TYPE_NAME(XmlSerializer)::finalize() {
for (IfcSchema::IfcWorkTime::list::it it2 = working_times->begin(); it2 != working_times->end(); ++it2)
{
IfcSchema::IfcWorkTime* working_time = *it2;
format_entity_instance(working_time, *ncalendar);
format_entity_instance(mapping_, working_time, *ncalendar);
}
}
}
@@ -717,13 +714,13 @@ void MAKE_TYPE_NAME(XmlSerializer)::finalize() {
for (IfcSchema::IfcRelConnectsElements::list::it it = pconnections->begin(); it != pconnections->end(); ++it) {
IfcSchema::IfcRelConnectsElements* connection = *it;
ptree* nconnection = format_entity_instance(connection, connections);
ptree* nconnection = format_entity_instance(mapping_, connection, connections);
ptree nrelatedElement;
ptree nrelatingElement;
format_entity_instance(connection->RelatedElement(), nrelatedElement, true);
format_entity_instance(connection->RelatingElement(), nrelatingElement, true);
format_entity_instance(mapping_,connection->RelatedElement(), nrelatedElement, true);
format_entity_instance(mapping_,connection->RelatingElement(), nrelatingElement, true);
nconnection->add_child("RelatedElement", nrelatedElement);
nconnection->add_child("RelatingElement", nrelatingElement);
@@ -733,14 +730,14 @@ void MAKE_TYPE_NAME(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);
if (node && type_object->HasPropertySets()) {
IfcSchema::IfcPropertySetDefinition::list::ptr property_sets = *type_object->HasPropertySets();
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);
}
}
}
@@ -751,12 +748,12 @@ void MAKE_TYPE_NAME(XmlSerializer)::finalize() {
for (aggregate_of_instance::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);
if (node) {
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);
}
}
@@ -771,7 +768,7 @@ void MAKE_TYPE_NAME(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);
}
}
@@ -797,16 +794,16 @@ void MAKE_TYPE_NAME(XmlSerializer)::finalize() {
if ((*jt)->Material()) {
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(mat->as<IfcUtil::IfcBaseEntity>(), node, materials);
format_entity_instance(mapping_, mat->as<IfcUtil::IfcBaseEntity>(), node, materials);
}
}
@@ -20,19 +20,28 @@
#ifndef XMLSERIALIZERIMPL_H
#define XMLSERIALIZERIMPL_H
#include "../../ifcgeom/abstract_mapping.h"
#include "../../ifcparse/macros.h"
#include "../../serializers/XmlSerializer.h"
#define INCLUDE_PARENT_PARENT_DIR(x) STRINGIFY(../../ifcparse/x.h)
#include INCLUDE_PARENT_PARENT_DIR(IfcSchema)
#undef INCLUDE_PARENT_PARENT_DIR
#define INCLUDE_PARENT_PARENT_DIR(x) STRINGIFY(../../ifcparse/x-definitions.h)
#include INCLUDE_PARENT_PARENT_DIR(IfcSchema)
class MAKE_TYPE_NAME(XmlSerializer) : public XmlSerializer {
class POSTFIX_SCHEMA(XmlSerializer) : public XmlSerializer {
private:
IfcParse::IfcFile* file;
// @todo
IfcGeom::IteratorSettings settings_;
ifcopenshell::geometry::abstract_mapping* mapping_;
public:
MAKE_TYPE_NAME(XmlSerializer)(IfcParse::IfcFile* file, const std::string& xml_filename)
POSTFIX_SCHEMA(XmlSerializer)(IfcParse::IfcFile* file, const std::string& xml_filename)
: XmlSerializer(0, "")
, mapping_(ifcopenshell::geometry::impl::mapping_implementations().construct(file, settings_))
{
this->file = file;
this->xml_filename = xml_filename;