Last minute refactoring

This commit is contained in:
Thomas Krijnen
2026-08-08 07:42:45 +02:00
parent 8870ffb018
commit af58eaf79f
300 changed files with 5230 additions and 5150 deletions
+38 -38
View File
@@ -43,7 +43,7 @@ static std::string& collada_id(std::string& s)
return s;
}
void ColladaSerializer::ColladaExporter::ColladaGeometries::addFloatSource(const std::string& mesh_id,
void collada_serializer::collada_exporter::collada_geometries::addFloatSource(const std::string& mesh_id,
const std::string& suffix, const std::vector<double>& floats, const char* coords /* = "XYZ" */)
{
COLLADASW::FloatSource source(mSW);
@@ -62,11 +62,11 @@ void ColladaSerializer::ColladaExporter::ColladaGeometries::addFloatSource(const
source.finish();
}
void ColladaSerializer::ColladaExporter::ColladaGeometries::write(
void collada_serializer::collada_exporter::collada_geometries::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<ifcopenshell::geometry::taxonomy::style::ptr>& /**<@todo 'materials' unused, remove? */,
const std::vector<int>& material_ids, const std::vector<ifcopenshell::geom::taxonomy::style::ptr>& /**<@todo 'materials' unused, remove? */,
const std::vector<double>& uvs, const std::vector<std::string>& material_references)
{
openMesh(mesh_id);
@@ -173,13 +173,13 @@ void ColladaSerializer::ColladaExporter::ColladaGeometries::write(
closeGeometry();
}
void ColladaSerializer::ColladaExporter::ColladaGeometries::close() {
void collada_serializer::collada_exporter::collada_geometries::close() {
closeLibrary();
}
void ColladaSerializer::ColladaExporter::ColladaScene::add(
void collada_serializer::collada_exporter::collada_scene::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& transformation)
const std::vector<std::string>& material_ids, const ifcopenshell::geom::transformation& transformation)
{
if (!scene_opened) {
openVisualScene(scene_id);
@@ -228,14 +228,14 @@ void ColladaSerializer::ColladaExporter::ColladaScene::add(
node.end();
}
void ColladaSerializer::ColladaExporter::ColladaScene::addParent(const IfcGeom::Element& parent){
void collada_serializer::collada_exporter::collada_scene::addParent(const ifcopenshell::geom::element& parent){
//we open the visual scene tag if it's not.
if (!scene_opened) {
openVisualScene(scene_id);
scene_opened = true;
}
const IfcGeom::Transformation& parent_trsf = parent.transformation();
const ifcopenshell::geom::transformation& parent_trsf = parent.transformation();
auto transformation_towrite = parent_trsf.data()->ccomponents();
@@ -267,12 +267,12 @@ void ColladaSerializer::ColladaExporter::ColladaScene::addParent(const IfcGeom::
current_node->addMatrix(matrix_array);
// Add the node to the parent stack
matrixStack.push(ifcopenshell::geometry::taxonomy::matrix4(parent_trsf.data()->ccomponents().inverse()));
matrixStack.push(ifcopenshell::geom::taxonomy::matrix4(parent_trsf.data()->ccomponents().inverse()));
parentNodes.push(current_node);
serializer->parentStackId.push(parent.id());
}
void ColladaSerializer::ColladaExporter::ColladaScene::closeParent()
void collada_serializer::collada_exporter::collada_scene::closeParent()
{
// Get the top element
COLLADASW::Node *current_node = parentNodes.top();
@@ -290,7 +290,7 @@ void ColladaSerializer::ColladaExporter::ColladaScene::closeParent()
current_node = NULL;
}
void ColladaSerializer::ColladaExporter::ColladaScene::write() {
void collada_serializer::collada_exporter::collada_scene::write() {
if (scene_opened) {
closeVisualScene();
closeLibrary();
@@ -300,8 +300,8 @@ void ColladaSerializer::ColladaExporter::ColladaScene::write() {
}
}
void ColladaSerializer::ColladaExporter::ColladaMaterials::ColladaEffects::write(
const ifcopenshell::geometry::taxonomy::style::ptr &material, const std::string &material_uri)
void collada_serializer::collada_exporter::collada_materials::collada_effects::write(
const ifcopenshell::geom::taxonomy::style::ptr &material, const std::string &material_uri)
{
openEffect(material_uri + "-fx");
COLLADASW::EffectProfile effect(mSW);
@@ -329,11 +329,11 @@ void ColladaSerializer::ColladaExporter::ColladaMaterials::ColladaEffects::write
closeEffect();
}
void ColladaSerializer::ColladaExporter::ColladaMaterials::ColladaEffects::close() {
void collada_serializer::collada_exporter::collada_materials::collada_effects::close() {
closeLibrary();
}
void ColladaSerializer::ColladaExporter::ColladaMaterials::add(const ifcopenshell::geometry::taxonomy::style::ptr& material) {
void collada_serializer::collada_exporter::collada_materials::add(const ifcopenshell::geom::taxonomy::style::ptr& material) {
if (!contains(material)) {
std::string material_name = material->name;
@@ -349,19 +349,19 @@ void ColladaSerializer::ColladaExporter::ColladaMaterials::add(const ifcopenshel
}
}
std::string ColladaSerializer::ColladaExporter::ColladaMaterials::getMaterialUri(const ifcopenshell::geometry::taxonomy::style::ptr& material) {
std::vector<ifcopenshell::geometry::taxonomy::style::ptr>::iterator it = std::find(materials.begin(), materials.end(), material);
std::string collada_serializer::collada_exporter::collada_materials::getMaterialUri(const ifcopenshell::geom::taxonomy::style::ptr& material) {
std::vector<ifcopenshell::geom::taxonomy::style::ptr>::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 ifcopenshell::geometry::taxonomy::style::ptr& material) {
bool collada_serializer::collada_exporter::collada_materials::contains(const ifcopenshell::geom::taxonomy::style::ptr& material) {
return std::find(materials.begin(), materials.end(), material) != materials.end();
}
void ColladaSerializer::ColladaExporter::ColladaMaterials::write() {
void collada_serializer::collada_exporter::collada_materials::write() {
effects.close();
BOOST_FOREACH(const ifcopenshell::geometry::taxonomy::style::ptr& material, materials) {
BOOST_FOREACH(const ifcopenshell::geom::taxonomy::style::ptr& material, materials) {
std::string material_name = getMaterialUri(material);
openMaterial(material_name);
@@ -374,7 +374,7 @@ void ColladaSerializer::ColladaExporter::ColladaMaterials::write() {
closeLibrary();
}
void ColladaSerializer::ColladaExporter::startDocument(const std::string& unit_name, float unit_magnitude) {
void collada_serializer::collada_exporter::startDocument(const std::string& unit_name, float unit_magnitude) {
stream.startDocument();
COLLADASW::Asset asset(&stream);
@@ -384,9 +384,9 @@ void ColladaSerializer::ColladaExporter::startDocument(const std::string& unit_n
asset.add();
}
void ColladaSerializer::ColladaExporter::write(const IfcGeom::TriangulationElement* o)
void collada_serializer::collada_exporter::write(const ifcopenshell::geom::triangulation_element* o)
{
const IfcGeom::Representation::Triangulation& mesh = o->geometry();
const ifcopenshell::geom::Representation::triangulation& mesh = o->geometry();
std::string name = serializer->object_id(o);
collada_id(name);
@@ -395,24 +395,24 @@ void ColladaSerializer::ColladaExporter::write(const IfcGeom::TriangulationEleme
collada_id(representation_id);
std::vector<std::string> material_references;
BOOST_FOREACH(const ifcopenshell::geometry::taxonomy::style::ptr& material, mesh.materials()) {
BOOST_FOREACH(const ifcopenshell::geom::taxonomy::style::ptr& material, mesh.materials()) {
materials.add(material);
std::string material_name = materials.getMaterialUri(material);
material_references.push_back(material_name);
}
DeferredObject deferred(name, representation_id, o->type(), o->transformation(), mesh.verts(), mesh.normals(),
deferred_object deferred(name, representation_id, o->type(), o->transformation(), mesh.verts(), mesh.normals(),
mesh.faces(), mesh.edges(), mesh.material_ids(), mesh.materials(), material_references, mesh.uvs());
if (serializer->geometry_settings().get<ifcopenshell::geometry::settings::UseElementHierarchy>().get()) {
if (serializer->settings().get<ifcopenshell::geom::settings::UseElementHierarchy>().get()) {
deferred.parents() = o->parents();
}
deferreds.push_back(deferred);
}
std::string ColladaSerializer::differentiateSlabTypes(const express::Entity& slab)
std::string collada_serializer::differentiateSlabTypes(const express::entity& slab)
{
auto value = slab.get("PredefinedType");
@@ -445,22 +445,22 @@ std::string ColladaSerializer::differentiateSlabTypes(const express::Entity& sla
return result;
}
std::string ColladaSerializer::object_id(const IfcGeom::Element* o) /*override*/
std::string collada_serializer::object_id(const ifcopenshell::geom::element* o) /*override*/
{
if (settings_.get<ifcopenshell::geometry::settings::UseElementTypes>().get()) {
if (settings_.get<ifcopenshell::geom::settings::UseElementTypes>().get()) {
const std::string slabSuffix = (o->product() && o->product().declaration().name() == "IfcSlab")
? differentiateSlabTypes(o->product())
: "";
return o->type() + slabSuffix;
}
return GeometrySerializer::object_id(o);
return geometry_serializer::object_id(o);
}
void ColladaSerializer::ColladaExporter::endDocument() {
void collada_serializer::collada_exporter::endDocument() {
// In fact due the XML based nature of Collada and its dependency on library nodes,
// only at this point all objects are written to the stream.
materials.write();
bool use_hierarchy = serializer->geometry_settings().get<ifcopenshell::geometry::settings::UseElementHierarchy>().get();
bool use_hierarchy = serializer->settings().get<ifcopenshell::geom::settings::UseElementHierarchy>().get();
std::set<std::string> geometries_written;
@@ -470,7 +470,7 @@ void ColladaSerializer::ColladaExporter::endDocument() {
std::sort(deferreds.begin(), deferreds.end());
}
for (std::vector<DeferredObject>::const_iterator it = deferreds.begin(); it != deferreds.end(); ++it) {
for (std::vector<deferred_object>::const_iterator it = deferreds.begin(); it != deferreds.end(); ++it) {
if (geometries_written.find(it->representation_id) != geometries_written.end()) {
continue;
}
@@ -480,7 +480,7 @@ void ColladaSerializer::ColladaExporter::endDocument() {
}
geometries.close();
for (std::vector<DeferredObject>::const_iterator it = deferreds.begin(); it != deferreds.end(); ++it){
for (std::vector<deferred_object>::const_iterator it = deferreds.begin(); it != deferreds.end(); ++it){
const std::string object_name = it->unique_id;
if (use_hierarchy)
@@ -530,19 +530,19 @@ void ColladaSerializer::ColladaExporter::endDocument() {
stream.endDocument();
}
bool ColladaSerializer::ready() {
bool collada_serializer::ready() {
return true;
}
void ColladaSerializer::writeHeader() {
void collada_serializer::writeHeader() {
exporter.startDocument(unit_name, unit_magnitude);
}
void ColladaSerializer::write(const IfcGeom::TriangulationElement* o) {
void collada_serializer::write(const ifcopenshell::geom::triangulation_element* o) {
exporter.write(o);
}
void ColladaSerializer::finalize() {
void collada_serializer::finalize() {
exporter.endDocument();
}
+59 -59
View File
@@ -50,97 +50,97 @@
#include <boost/numeric/ublas/io.hpp>
class SERIALIZERS_API ColladaSerializer : public WriteOnlyGeometrySerializer
class SERIALIZERS_API collada_serializer : public write_only_geometry_serializer
{
// TODO The vast amount of implement details of ColladaSerializer could be hidden to the cpp file.
// TODO The vast amount of implement details of collada_serializer could be hidden to the cpp file.
private:
std::stack<int> parentStackId;
class ColladaExporter
class collada_exporter
{
private:
class ColladaGeometries : public COLLADASW::LibraryGeometries
class collada_geometries : public COLLADASW::LibraryGeometries
{
ColladaGeometries(const ColladaGeometries&); //N/A
ColladaGeometries& operator =(const ColladaGeometries&); //N/A
collada_geometries(const collada_geometries&); //N/A
collada_geometries& operator =(const collada_geometries&); //N/A
public:
explicit ColladaGeometries(COLLADASW::StreamWriter& stream, ColladaSerializer *_serializer)
explicit collada_geometries(COLLADASW::StreamWriter& stream, collada_serializer *_serializer)
: COLLADASW::LibraryGeometries(&stream)
, serializer(_serializer)
{}
void addFloatSource(const std::string& mesh_id, const std::string& suffix,
const std::vector<double>& floats, const char* coords = "XYZ");
/// @todo pass simply DeferredObject?
/// @todo pass simply deferred_object?
void write(
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<ifcopenshell::geometry::taxonomy::style::ptr>& materials,
const std::vector<int>& material_ids, const std::vector<ifcopenshell::geom::taxonomy::style::ptr>& materials,
const std::vector<double>& uvs, const std::vector<std::string>& material_references);
void close();
ColladaSerializer *serializer;
collada_serializer *serializer;
};
class ColladaScene : public COLLADASW::LibraryVisualScenes
class collada_scene : public COLLADASW::LibraryVisualScenes
{
private:
ColladaScene(const ColladaScene&); //N/A
ColladaScene& operator =(const ColladaScene&); //N/A
collada_scene(const collada_scene&); //N/A
collada_scene& operator =(const collada_scene&); //N/A
const std::string scene_id;
bool scene_opened;
std::stack<COLLADASW::Node*> parentNodes;
std::stack<ifcopenshell::geometry::taxonomy::matrix4> matrixStack;
std::stack<ifcopenshell::geom::taxonomy::matrix4> matrixStack;
public:
ColladaScene(const std::string& scene_id, COLLADASW::StreamWriter& stream, ColladaSerializer *_serializer)
collada_scene(const std::string& scene_id, COLLADASW::StreamWriter& stream, collada_serializer *_serializer)
: COLLADASW::LibraryVisualScenes(&stream)
, scene_id(scene_id)
, scene_opened(false)
, 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& matrix);
void addParent(const IfcGeom::Element& parent);
const std::vector<std::string>& material_ids, const ifcopenshell::geom::transformation& matrix);
void addParent(const ifcopenshell::geom::element& parent);
void closeParent();
COLLADASW::Node* GetDirectParent();
void write();
ColladaSerializer *serializer;
collada_serializer *serializer;
};
class ColladaMaterials : public COLLADASW::LibraryMaterials
class collada_materials : public COLLADASW::LibraryMaterials
{
ColladaMaterials(const ColladaMaterials&); //N/A
ColladaMaterials& operator =(const ColladaMaterials&); //N/A
collada_materials(const collada_materials&); //N/A
collada_materials& operator =(const collada_materials&); //N/A
private:
class ColladaEffects : public COLLADASW::LibraryEffects
class collada_effects : public COLLADASW::LibraryEffects
{
ColladaEffects(const ColladaEffects&); //N/A
ColladaEffects& operator =(const ColladaEffects&); //N/A
collada_effects(const collada_effects&); //N/A
collada_effects& operator =(const collada_effects&); //N/A
public:
explicit ColladaEffects(COLLADASW::StreamWriter& stream)
explicit collada_effects(COLLADASW::StreamWriter& stream)
: COLLADASW::LibraryEffects(&stream)
{}
void write(const ifcopenshell::geometry::taxonomy::style::ptr& material, const std::string &material_uri);
void write(const ifcopenshell::geom::taxonomy::style::ptr& material, const std::string &material_uri);
void close();
ColladaSerializer *serializer;
collada_serializer *serializer;
};
std::vector<ifcopenshell::geometry::taxonomy::style::ptr> materials;
std::vector<ifcopenshell::geom::taxonomy::style::ptr> materials;
std::vector<std::string> material_uris;
public:
explicit ColladaMaterials(COLLADASW::StreamWriter& stream, ColladaSerializer *_serializer)
explicit collada_materials(COLLADASW::StreamWriter& stream, collada_serializer *_serializer)
: COLLADASW::LibraryMaterials(&stream)
, serializer(_serializer)
, effects(stream)
{}
void add(const ifcopenshell::geometry::taxonomy::style::ptr& material);
std::string getMaterialUri(const ifcopenshell::geometry::taxonomy::style::ptr& material);
bool contains(const ifcopenshell::geometry::taxonomy::style::ptr& material);
void add(const ifcopenshell::geom::taxonomy::style::ptr& material);
std::string getMaterialUri(const ifcopenshell::geom::taxonomy::style::ptr& material);
bool contains(const ifcopenshell::geom::taxonomy::style::ptr& material);
void write();
ColladaSerializer *serializer;
ColladaEffects effects;
collada_serializer *serializer;
collada_effects effects;
};
class DeferredObject {
class deferred_object {
friend bool operator < (const DeferredObject& def_obj1, const DeferredObject& def_obj2) {
friend bool operator < (const deferred_object& def_obj1, const deferred_object& def_obj2) {
size_t size = (def_obj1.parents_.size() < def_obj2.parents_.size() ? def_obj1.parents_.size() : def_obj2.parents_.size());
size_t cpt = 0;
@@ -159,20 +159,20 @@ private:
public:
std::string unique_id, representation_id, type;
IfcGeom::Transformation transformation;
ifcopenshell::geom::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<ifcopenshell::geometry::taxonomy::style::ptr> materials;
std::vector<ifcopenshell::geom::taxonomy::style::ptr> materials;
std::vector<std::string> material_references;
std::vector<double> uvs;
std::vector<const IfcGeom::Element*> parents_;
std::vector<const ifcopenshell::geom::element*> parents_;
DeferredObject(const std::string& unique_id, const std::string& representation_id, const std::string& type, const IfcGeom::Transformation& transformation,
deferred_object(const std::string& unique_id, const std::string& representation_id, const std::string& type, const ifcopenshell::geom::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::ptr>& materials,
const std::vector<int>& edges, const std::vector<int>& material_ids, const std::vector<ifcopenshell::geom::taxonomy::style::ptr>& materials,
const std::vector<std::string>& material_references, const std::vector<double>& uvs)
: unique_id(unique_id)
, representation_id(representation_id)
@@ -188,15 +188,15 @@ private:
, uvs(uvs)
{}
std::vector<const IfcGeom::Element*>& parents() { return parents_; }
const std::vector<const IfcGeom::Element*>& parents() const { return parents_; }
std::vector<const ifcopenshell::geom::element*>& parents() { return parents_; }
const std::vector<const ifcopenshell::geom::element*>& parents() const { return parents_; }
};
COLLADABU::NativeString filename;
COLLADASW::StreamWriter stream;
ColladaScene scene;
collada_scene scene;
public:
/// @param double_precision Whether to use "double precision" (up to 16 decimals) or not (6 or 7 decimals).
ColladaExporter(const std::string& scene_name, const std::string& fn, ColladaSerializer *_serializer,
collada_exporter(const std::string& scene_name, const std::string& fn, collada_serializer *_serializer,
bool double_precision)
: filename(fn)
, stream(COLLADASW::NativeString(filename.c_str(), COLLADASW::NativeString::ENCODING_UTF8), double_precision)
@@ -206,22 +206,22 @@ private:
, serializer(_serializer)
{
}
ColladaMaterials materials;
ColladaGeometries geometries;
ColladaSerializer *serializer;
std::vector<DeferredObject> deferreds;
virtual ~ColladaExporter() {}
collada_materials materials;
collada_geometries geometries;
collada_serializer *serializer;
std::vector<deferred_object> deferreds;
virtual ~collada_exporter() {}
void startDocument(const std::string& unit_name, float unit_magnitude);
void write(const IfcGeom::TriangulationElement* o);
void write(const ifcopenshell::geom::triangulation_element* o);
void endDocument();
};
ColladaExporter exporter;
collada_exporter exporter;
std::string unit_name;
float unit_magnitude;
public:
ColladaSerializer(const std::string& dae_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, ::logger* logger = nullptr)
: WriteOnlyGeometrySerializer(geometry_settings, settings, logger)
, exporter("IfcOpenShell", dae_filename, this, settings.get<ifcopenshell::geometry::settings::FloatingPointDigits>().get() >= 15)
collada_serializer(const std::string& dae_filename, const ifcopenshell::geom::settings& settings, ::logger* logger = nullptr)
: write_only_geometry_serializer(settings, logger)
, exporter("IfcOpenShell", dae_filename, this, settings.get<ifcopenshell::geom::settings::FloatingPointDigits>().get() >= 15)
{
exporter.serializer = this;
exporter.materials.serializer = this;
@@ -230,8 +230,8 @@ public:
}
bool ready();
void writeHeader();
void write(const IfcGeom::TriangulationElement* o);
void write(const IfcGeom::BRepElement* /*o*/) {}
void write(const ifcopenshell::geom::triangulation_element* o);
void write(const ifcopenshell::geom::brep_element* /*o*/) {}
void finalize();
bool isTesselated() const { return true; }
void setUnitNameAndMagnitude(const std::string& name, float magnitude) {
@@ -240,10 +240,10 @@ public:
}
void setFile(ifcopenshell::file&) {}
std::string object_id(const IfcGeom::Element* o) /*override*/;
std::string object_id(const ifcopenshell::geom::element* o) /*override*/;
private:
static std::string differentiateSlabTypes(const express::Entity& slab);
static std::string differentiateSlabTypes(const express::entity& slab);
};
#endif
+29 -29
View File
@@ -53,8 +53,8 @@ static const uint32_t PRIM_TRIANGLE_FAN = 6;
static const uint32_t ELEMENT_ARRAY_BUFFER = 34963;
static const uint32_t ARRAY_BUFFER = 34962;
GltfSerializer::GltfSerializer(const std::string& filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, ::logger* logger)
: WriteOnlyGeometrySerializer(geometry_settings, settings, logger)
gltf_serializer::gltf_serializer(const std::string& filename, const ifcopenshell::geom::settings& settings, ::logger* logger)
: write_only_geometry_serializer(settings, logger)
, filename_(filename)
, tmp_filename1_(filename + ".indices.tmp")
, tmp_filename2_(filename + ".vertices.tmp")
@@ -64,18 +64,18 @@ GltfSerializer::GltfSerializer(const std::string& filename, const ifcopenshell::
, bufferViewId(0)
{}
GltfSerializer::~GltfSerializer() {
gltf_serializer::~gltf_serializer() {
tmp_fstream1_.close();
tmp_fstream2_.close();
ifcopenshell::path::delete_file(tmp_filename1_);
ifcopenshell::path::delete_file(tmp_filename2_);
}
bool GltfSerializer::ready() {
bool gltf_serializer::ready() {
return fstream_.is_open() && tmp_fstream1_.is_open() && tmp_fstream2_.is_open();
}
void GltfSerializer::writeHeader() {
void gltf_serializer::writeHeader() {
json_["asset"]["generator"] = "IfcOpenShell IfcConvert " + std::string(IFCOPENSHELL_VERSION);
json_["asset"]["version"] = "2.0";
json_["scene"] = 0;
@@ -88,7 +88,7 @@ void GltfSerializer::writeHeader() {
json_["materials"] = json::array();
}
int GltfSerializer::writeMaterial(const ifcopenshell::geometry::taxonomy::style::ptr style) {
int gltf_serializer::writeMaterial(const ifcopenshell::geom::taxonomy::style::ptr style) {
auto it = materials_.find(style->name);
if (it != materials_.end()) {
return it->second;
@@ -181,7 +181,7 @@ size_t write_accessor(json& j, std::ofstream& ofs, It begin, It end, int bufferV
return j["accessors"].size() - 1;
}
void GltfSerializer::write(const IfcGeom::TriangulationElement* o) {
void gltf_serializer::write(const ifcopenshell::geom::triangulation_element* o) {
if (o->geometry().material_ids().empty()) {
return;
}
@@ -221,7 +221,7 @@ void GltfSerializer::write(const IfcGeom::TriangulationElement* o) {
json parent_node = json::object();
std::array<double, 16> matrix_flat;
if (settings_.get<ifcopenshell::geometry::settings::SeparateZUpNode>().get() || settings_.get<ifcopenshell::geometry::settings::WriteGltfEcef>().get() || !is_root) {
if (settings_.get<ifcopenshell::geom::settings::SeparateZUpNode>().get() || settings_.get<ifcopenshell::geom::settings::WriteGltfEcef>().get() || !is_root) {
// y-up transform is only accounted for on root
matrix_flat = {
mm(0,0), mm(1,0), mm(2,0), mm(3,0),
@@ -264,7 +264,7 @@ void GltfSerializer::write(const IfcGeom::TriangulationElement* o) {
json node;
{
std::array<double, 16> matrix_flat;
if (settings_.get<ifcopenshell::geometry::settings::SeparateZUpNode>().get() || settings_.get<ifcopenshell::geometry::settings::WriteGltfEcef>().get() || !o->parents().empty()) {
if (settings_.get<ifcopenshell::geom::settings::SeparateZUpNode>().get() || settings_.get<ifcopenshell::geom::settings::WriteGltfEcef>().get() || !o->parents().empty()) {
// y-up transform is only accounted for on root
matrix_flat = {
m(0,0), m(1,0), m(2,0), m(3,0),
@@ -416,9 +416,9 @@ void write_block(std::ostream& fs, It begin, It end) {
write_padding<iden>(fs, N);
}
void GltfSerializer::finalize() {
void gltf_serializer::finalize() {
// separate z up
if (settings_.get<ifcopenshell::geometry::settings::SeparateZUpNode>().get()) {
if (settings_.get<ifcopenshell::geom::settings::SeparateZUpNode>().get()) {
z_up_transform_ = json::object();
(*z_up_transform_)["name"] = "Z_UP";
static const std::array<double, 16> z_up_matrix = {
@@ -461,7 +461,7 @@ void GltfSerializer::finalize() {
}
json scene_0;
if (geometry_settings().get<ifcopenshell::geometry::settings::UseElementHierarchy>().get()) {
if (settings().get<ifcopenshell::geom::settings::UseElementHierarchy>().get()) {
scene_0["nodes"] = roots_;
} else if (north_rotation_ || ecef_transform_ || z_up_transform_) {
scene_0["nodes"] = std::array<size_t, 1>{json_["nodes"].size() - 1};
@@ -530,8 +530,8 @@ namespace {
}
}
void GltfSerializer::setFile(ifcopenshell::file& f) {
if (!settings_.get<ifcopenshell::geometry::settings::WriteGltfEcef>().get()) {
void gltf_serializer::setFile(ifcopenshell::file& f) {
if (!settings_.get<ifcopenshell::geom::settings::WriteGltfEcef>().get()) {
return;
}
@@ -539,17 +539,17 @@ void GltfSerializer::setFile(ifcopenshell::file& f) {
std::optional<std::array<double, 3>> crs_x_axis;
std::optional<std::array<double, 3>> eastings_northings_elevation;
std::vector<express::Base> coordops;
std::vector<express::base> coordops;
try {
coordops = f.instances_by_type("IfcCoordinateOperation");
} catch (ifcopenshell::exception&) {
// Ignored. Schema likely doesn't support IfcCoordinateOperation.
}
for (auto& coordop : coordops) {
express::Base source_crs = coordop.as<express::Entity>().get("SourceCRS");
express::base source_crs = coordop.as<express::entity>().get("SourceCRS");
if (source_crs.declaration().is("IfcGeometricRepresentationContext")) {
express::Base target_crs = coordop.as<express::Entity>().get("TargetCRS");
auto name_attr = target_crs.as<express::Entity>().get("Name");
express::base target_crs = coordop.as<express::entity>().get("TargetCRS");
auto name_attr = target_crs.as<express::entity>().get("Name");
if (coordop.declaration().is("IfcMapConversion")) {
if (!name_attr.isNull()) {
@@ -557,15 +557,15 @@ void GltfSerializer::setFile(ifcopenshell::file& f) {
crs_epsg = epsg_code;
// @todo in which unit are these?
double eastings = coordop.as<express::Entity>().get("Eastings");
double northings = coordop.as<express::Entity>().get("Northings");
double height = coordop.as<express::Entity>().get("OrthogonalHeight");
double eastings = coordop.as<express::entity>().get("Eastings");
double northings = coordop.as<express::entity>().get("Northings");
double height = coordop.as<express::entity>().get("OrthogonalHeight");
height = 0.;
eastings_northings_elevation = { { eastings, northings, height} };
auto xaxis_attr = coordop.as<express::Entity>().get("XAxisAbscissa");
auto yaxis_attr = coordop.as<express::Entity>().get("XAxisOrdinate");
auto xaxis_attr = coordop.as<express::entity>().get("XAxisAbscissa");
auto yaxis_attr = coordop.as<express::entity>().get("XAxisOrdinate");
if (!xaxis_attr.isNull() && !yaxis_attr.isNull()) {
double xaxis = xaxis_attr;
double yaxis = yaxis_attr;
@@ -581,8 +581,8 @@ void GltfSerializer::setFile(ifcopenshell::file& f) {
auto sites = f.instances_by_type("IfcSite");
if (sites.size() == 1) {
auto lat_attr = sites.front().as<express::Entity>().get("RefLatitude");
auto lon_attr = sites.front().as<express::Entity>().get("RefLongitude");
auto lat_attr = sites.front().as<express::entity>().get("RefLatitude");
auto lon_attr = sites.front().as<express::entity>().get("RefLongitude");
if (!lat_attr.isNull() && !lon_attr.isNull()) {
std::vector<int64_t> lat_dms = lat_attr;
@@ -601,7 +601,7 @@ void GltfSerializer::setFile(ifcopenshell::file& f) {
double elev = 0.;
/*
auto elev_attr = (*sites->begin()).as<express::Entity>().get("RefElevation");
auto elev_attr = (*sites->begin()).as<express::entity>().get("RefElevation");
if (!elev_attr->isNull()) {
elev = *elev_attr;
}
@@ -616,12 +616,12 @@ void GltfSerializer::setFile(ifcopenshell::file& f) {
auto contexts = f.instances_by_type_excl_subtypes("IfcGeometricRepresentationContext");
if (!contexts.empty()) {
auto context = contexts.front().as<express::Entity>();
auto context = contexts.front().as<express::entity>();
auto north_attr = context.get("TrueNorth");
if (!north_attr.isNull()) {
express::Base north = north_attr;
express::base north = north_attr;
if (north.declaration().is("IfcDirection")) {
std::vector<double> ratios = north.as<express::Entity>().get("DirectionRatios");
std::vector<double> ratios = north.as<express::entity>().get("DirectionRatios");
crs_x_axis = { { ratios[1], -ratios[0], 0. } };
}
}
+7 -7
View File
@@ -30,7 +30,7 @@ using json = nlohmann::json;
#include <map>
class SERIALIZERS_API GltfSerializer : public WriteOnlyGeometrySerializer {
class SERIALIZERS_API gltf_serializer : public write_only_geometry_serializer {
private:
std::string filename_, tmp_filename1_, tmp_filename2_;
std::ofstream fstream_, tmp_fstream1_, tmp_fstream2_;
@@ -38,17 +38,17 @@ private:
json json_, node_array_;
std::optional<json> ecef_transform_, north_rotation_, z_up_transform_;
int bufferViewId;
std::map<express::Base, size_t> node_indices_;
std::map<express::base, size_t> node_indices_;
std::vector<size_t> roots_;
int writeMaterial(const ifcopenshell::geometry::taxonomy::style::ptr style);
int writeMaterial(const ifcopenshell::geom::taxonomy::style::ptr style);
public:
GltfSerializer(const std::string& filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, ::logger* logger = nullptr);
virtual ~GltfSerializer();
gltf_serializer(const std::string& filename, const ifcopenshell::geom::settings& settings, ::logger* logger = nullptr);
virtual ~gltf_serializer();
bool ready();
void writeHeader();
void write(const IfcGeom::TriangulationElement* o);
void write(const IfcGeom::BRepElement* /*o*/) {}
void write(const ifcopenshell::geom::triangulation_element* o);
void write(const ifcopenshell::geom::brep_element* /*o*/) {}
void finalize();
bool isTesselated() const { return true; }
void setUnitNameAndMagnitude(const std::string& /*name*/, float /*magnitude*/) {}
+5 -5
View File
@@ -33,17 +33,17 @@
#include <Interface_Static.hxx>
#endif
class IgesSerializer : public OpenCascadeBasedSerializer
class iges_serializer : public open_cascade_based_serializer
{
private:
IGESControl_Writer writer;
public:
/// @note IGESControl_Controller::Init() must be called prior to instantiating IgesSerializer.
/// @note IGESControl_Controller::Init() must be called prior to instantiating iges_serializer.
/// See http://tracker.dev.opencascade.org/view.php?id=23679 for more information.
IgesSerializer(const std::string& out_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, ::logger* logger = nullptr)
: OpenCascadeBasedSerializer(out_filename, geometry_settings, settings, logger)
iges_serializer(const std::string& out_filename, const ifcopenshell::geom::settings& settings, ::logger* logger = nullptr)
: open_cascade_based_serializer(out_filename, settings, logger)
{}
virtual ~IgesSerializer() {}
virtual ~iges_serializer() {}
void writeShape(const std::string&, const TopoDS_Shape& shape) {
writer.AddShape(shape);
}
+4 -4
View File
@@ -11,20 +11,20 @@
#include <boost/shared_ptr.hpp>
class JsonSerializer : public Serializer {
class json_serializer : public serializer {
public:
enum Dialect {
JSON_DIALECT_CREOOX
};
private:
boost::shared_ptr<Serializer> implementation_;
boost::shared_ptr<serializer> implementation_;
protected:
std::string json_filename;
Dialect dialect_;
public:
JsonSerializer(ifcopenshell::file* file, const std::string& json_filename, Dialect dialect = Dialect::JSON_DIALECT_CREOOX, ::logger& logger = ::logger::root())
json_serializer(ifcopenshell::file* file, const std::string& json_filename, Dialect dialect = Dialect::JSON_DIALECT_CREOOX, ::logger& logger = ::logger::root())
: json_filename(json_filename)
, dialect_(dialect)
{
@@ -40,7 +40,7 @@ class JsonSerializer : public Serializer {
implementation_ = ifcopenshell::serializers::document_serializer_registry_instance().create("json", context);
}
virtual ~JsonSerializer() {}
virtual ~json_serializer() {}
bool ready() { return true; }
void writeHeader() {}
@@ -31,7 +31,7 @@
#include <Standard_Version.hxx>
#include <BRepBuilderAPI_Transform.hxx>
bool OpenCascadeBasedSerializer::ready() {
bool open_cascade_based_serializer::ready() {
std::ofstream test_file(ifcopenshell::path::from_utf8(out_filename).c_str(), std::ios_base::binary);
bool succeeded = test_file.is_open();
test_file.close();
@@ -39,9 +39,9 @@ bool OpenCascadeBasedSerializer::ready() {
return succeeded;
}
void OpenCascadeBasedSerializer::write(const IfcGeom::BRepElement* o) {
void open_cascade_based_serializer::write(const ifcopenshell::geom::brep_element* o) {
auto itm = o->geometry().as_compound();
TopoDS_Shape compound = ((ifcopenshell::geometry::OpenCascadeShape*)itm)->shape();
TopoDS_Shape compound = ((ifcopenshell::geom::open_cascade_shape*)itm)->shape();
writeShape(object_id(o), compound);
delete itm;
}
@@ -49,7 +49,7 @@ void OpenCascadeBasedSerializer::write(const IfcGeom::BRepElement* o) {
#define RATHER_SMALL (1e-3)
#define APPROXIMATELY_THE_SAME(a,b) (fabs(a-b) < RATHER_SMALL)
const char* OpenCascadeBasedSerializer::getSymbolForUnitMagnitude(float mag) {
const char* open_cascade_based_serializer::getSymbolForUnitMagnitude(float mag) {
if (APPROXIMATELY_THE_SAME(mag, 0.001f)) {
return "MM";
} else if (APPROXIMATELY_THE_SAME(mag, 0.01f)) {
+8 -8
View File
@@ -29,23 +29,23 @@
#include <TopoDS_Shape.hxx>
class SERIALIZERS_API OpenCascadeBasedSerializer : public WriteOnlyGeometrySerializer {
OpenCascadeBasedSerializer(const OpenCascadeBasedSerializer&); //N/A
OpenCascadeBasedSerializer& operator =(const OpenCascadeBasedSerializer&); //N/A
class SERIALIZERS_API open_cascade_based_serializer : public write_only_geometry_serializer {
open_cascade_based_serializer(const open_cascade_based_serializer&); //N/A
open_cascade_based_serializer& operator =(const open_cascade_based_serializer&); //N/A
protected:
const std::string out_filename;
const char* getSymbolForUnitMagnitude(float mag);
public:
explicit OpenCascadeBasedSerializer(const std::string& out_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, ::logger* logger = nullptr)
: WriteOnlyGeometrySerializer(geometry_settings, settings, logger)
explicit open_cascade_based_serializer(const std::string& out_filename, const ifcopenshell::geom::settings& settings, ::logger* logger = nullptr)
: write_only_geometry_serializer(settings, logger)
, out_filename(out_filename)
{}
virtual ~OpenCascadeBasedSerializer() {}
virtual ~open_cascade_based_serializer() {}
void writeHeader() {}
bool ready();
virtual void writeShape(const std::string& name, const TopoDS_Shape& shape) = 0;
void write(const IfcGeom::TriangulationElement* /*o*/) {}
void write(const IfcGeom::BRepElement* o);
void write(const ifcopenshell::geom::triangulation_element* /*o*/) {}
void write(const ifcopenshell::geom::brep_element* o);
bool isTesselated() const { return false; }
void setFile(ifcopenshell::file&) {}
};
+12 -12
View File
@@ -22,14 +22,14 @@ namespace {
{
auto s = sizeof(size_t);
val.resize(s + 2);
val[0] = TypeEncoder::encode_type<express::Base>();
val[0] = type_encoder::encode_type<express::base>();
// 1 = entity - stored by id (entity name)
// 2 = type - stored by identity (internal counter in class)
val[1] = t.index() == 0 ? 'i' : 't';
size_t iden;
if (auto* name = std::get_if<ifcopenshell::instance_reference>(&t)) {
iden = *name;
} else if (auto* inst = std::get_if<express::Base>(&t)) {
} else if (auto* inst = std::get_if<express::base>(&t)) {
iden = (*inst).identity();
}
memcpy(val.data() + 2, &iden, s);
@@ -40,7 +40,7 @@ namespace {
{
// no attempt at alignment
val.resize(t.size() * (sizeof(size_t) + 1) + 1);
val[0] = TypeEncoder::encode_type<std::vector<express::Base>>();
val[0] = type_encoder::encode_type<std::vector<express::base>>();
char* ptr = val.data() + 1;
for (auto it = t.begin(); it != t.end(); ++it) {
*ptr = it->index() == 0 ? 'i' : 't';
@@ -48,7 +48,7 @@ namespace {
size_t iden = 0;
if (auto* name = std::get_if<ifcopenshell::instance_reference>(&*it)) {
iden = *name;
} else if (auto* inst = std::get_if<express::Base>(&*it)) {
} else if (auto* inst = std::get_if<express::base>(&*it)) {
iden = (*inst).identity();
}
memcpy(ptr, &iden, sizeof(size_t));
@@ -60,7 +60,7 @@ namespace {
bool serialize(std::string& val, const std::vector<std::vector<ifcopenshell::reference_or_simple_type>>& t)
{
std::ostringstream oss;
oss.put(TypeEncoder::encode_type<std::vector<std::vector<express::Base>>>());
oss.put(type_encoder::encode_type<std::vector<std::vector<express::base>>>());
auto write_size = [&oss](size_t sz) {
std::string size_str;
@@ -82,7 +82,7 @@ namespace {
size_t iden = 0;
if (auto* name = std::get_if<ifcopenshell::instance_reference>(&*jt)) {
iden = *name;
} else if (auto* inst = std::get_if<express::Base>(&*jt)) {
} else if (auto* inst = std::get_if<express::base>(&*jt)) {
iden = (*inst).identity();
}
std::string iden_str;
@@ -148,13 +148,13 @@ void RocksDbSerializer::write_streaming_() {
}
}
std::vector<express::Base> simple_type_instances;
std::vector<express::base> simple_type_instances;
for (size_t i = 0; i < data->storage_->size(); i++) {
auto val = data->get_attribute_value(i);
val.apply_visitor([&](const auto& t) {
using T = std::decay_t<decltype(t)>;
if constexpr (std::is_same_v<T, express::Base>) {
if constexpr (std::is_same_v<T, express::base>) {
// instance is per definition a simple type here, because instance
// references are not resolved yet, but provided in vector of
// references
@@ -174,7 +174,7 @@ void RocksDbSerializer::write_streaming_() {
(is_header ? decl->name() : std::to_string(p.first.name_)) + "|" +
std::to_string(index);
if (storage.db->Get(storage.ropts, key, &tmp) == rocksdb::Status::OK() && tmp.size() == (sizeof(size_t) + 2) && tmp[0] == TypeEncoder::encode_type<express::Base>() && tmp[1] == 't')
if (storage.db->Get(storage.ropts, key, &tmp) == rocksdb::Status::OK() && tmp.size() == (sizeof(size_t) + 2) && tmp[0] == type_encoder::encode_type<express::base>() && tmp[1] == 't')
{
size_t iden;
memcpy(&iden, tmp.data() + 2, sizeof(size_t));
@@ -188,20 +188,20 @@ void RocksDbSerializer::write_streaming_() {
using T = std::decay_t<decltype(v)>;
if constexpr (std::is_same_v<T, ifcopenshell::reference_or_simple_type>) {
if (auto* inst = std::get_if<express::Base>(&v)) {
if (auto* inst = std::get_if<express::base>(&v)) {
// So this never happens?
simple_type_instances.push_back(*inst);
}
} else if constexpr (std::is_same_v<T, std::vector<ifcopenshell::reference_or_simple_type>>) {
for (auto const& inner : v) {
if (auto* inst = std::get_if<express::Base>(&inner)) {
if (auto* inst = std::get_if<express::base>(&inner)) {
simple_type_instances.push_back(*inst);
}
}
} else if constexpr (std::is_same_v<T, std::vector<std::vector<ifcopenshell::reference_or_simple_type>>>) {
for (auto const& inner : v) {
for (auto const& innermost : inner) {
if (auto* inst = std::get_if<express::Base>(&innermost)) {
if (auto* inst = std::get_if<express::base>(&innermost)) {
simple_type_instances.push_back(*inst);
}
}
+1 -1
View File
@@ -8,7 +8,7 @@
#include <string>
#include <vector>
class SERIALIZERS_API RocksDbSerializer : public Serializer {
class SERIALIZERS_API RocksDbSerializer : public serializer {
private:
std::string input_filename_;
std::string rocksdb_filename_;
+4 -4
View File
@@ -29,15 +29,15 @@
#include "../serializers/OpenCascadeBasedSerializer.h"
class StepSerializer : public OpenCascadeBasedSerializer
class step_serializer : public open_cascade_based_serializer
{
private:
STEPControl_Writer writer;
public:
explicit StepSerializer(const std::string& out_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& serializer_settings, ::logger* logger = nullptr)
: OpenCascadeBasedSerializer(out_filename, geometry_settings, serializer_settings, logger)
explicit step_serializer(const std::string& out_filename, const ifcopenshell::geom::settings& settings, ::logger* logger = nullptr)
: open_cascade_based_serializer(out_filename, settings, logger)
{}
virtual ~StepSerializer() {}
virtual ~step_serializer() {}
void writeShape(const std::string& name, const TopoDS_Shape& shape) {
std::stringstream ss;
std::streambuf *sb = std::cout.rdbuf(ss.rdbuf());
+136 -140
View File
@@ -152,110 +152,108 @@ subtract_before_project parse_subtract_before_project(const std::string& value)
throw std::runtime_error("Invalid use of --svg-subtract-before, expected auto|slabs-and-walls|always");
}
SvgSerializer::storey_height_display_types parse_storey_height_display(const std::string& value) {
svg_serializer::storey_height_display_types parse_storey_height_display(const std::string& value) {
const auto display = boost::to_lower_copy(value);
if (display == "none") {
return SvgSerializer::SH_NONE;
return svg_serializer::SH_NONE;
}
if (display == "full") {
return SvgSerializer::SH_FULL;
return svg_serializer::SH_FULL;
}
if (display == "left") {
return SvgSerializer::SH_LEFT;
return svg_serializer::SH_LEFT;
}
throw std::runtime_error("Invalid use of --draw-storey-heights, expected none|full|left");
}
}
bool SvgSerializer::ready() {
bool svg_serializer::ready() {
return true;
}
void SvgSerializer::apply_settings() {
using namespace ifcopenshell::geometry::settings;
if (settings().get<SvgBounds>().has()) {
const auto bounds = parse_svg_bounds(settings().get<SvgBounds>().get());
void svg_serializer::apply_settings() {
if (settings().get<ifcopenshell::geom::settings::SvgBounds>().has()) {
const auto bounds = parse_svg_bounds(settings().get<ifcopenshell::geom::settings::SvgBounds>().get());
setBoundingRectangle(bounds.first, bounds.second);
}
if (settings().get<SvgScale>().has()) {
setScale(parse_svg_scale(settings().get<SvgScale>().get()));
if (settings().get<ifcopenshell::geom::settings::SvgScale>().has()) {
setScale(parse_svg_scale(settings().get<ifcopenshell::geom::settings::SvgScale>().get()));
}
if (settings().get<SvgCenter>().has()) {
const auto center = parse_svg_center(settings().get<SvgCenter>().get());
if (settings().get<ifcopenshell::geom::settings::SvgCenter>().has()) {
const auto center = parse_svg_center(settings().get<ifcopenshell::geom::settings::SvgCenter>().get());
setDrawingCenter(center.first, center.second);
}
if (settings().get<SvgSectionHeightFromStoreys>().get() && file) {
if (settings().get<SvgSectionHeight>().has()) {
setSectionHeightsFromStoreys(settings().get<SvgSectionHeight>().get());
if (settings().get<ifcopenshell::geom::settings::SvgSectionHeightFromStoreys>().get() && file) {
if (settings().get<ifcopenshell::geom::settings::SvgSectionHeight>().has()) {
setSectionHeightsFromStoreys(settings().get<ifcopenshell::geom::settings::SvgSectionHeight>().get());
} else {
setSectionHeightsFromStoreys();
}
} else if (settings().get<SvgSectionHeight>().has()) {
setSectionHeight(settings().get<SvgSectionHeight>().get());
} else if (settings().get<ifcopenshell::geom::settings::SvgSectionHeight>().has()) {
setSectionHeight(settings().get<ifcopenshell::geom::settings::SvgSectionHeight>().get());
}
setPrintSpaceNames(settings().get<SvgPrintSpaceNames>().get());
setPrintSpaceAreas(settings().get<SvgPrintSpaceAreas>().get());
setDrawDoorArcs(settings().get<SvgDoorArcs>().get());
setAutoSection(settings().get<SvgAutoSection>().get());
setAutoElevation(settings().get<SvgAutoElevation>().get());
setUseNamespace(settings().get<SvgUseNamespace>().get());
setUseHlrPoly(settings().get<SvgUseHlrPoly>().get());
setUsePrefiltering(settings().get<SvgUsePrefiltering>().get());
setUnifyInputs(settings().get<SvgUnifyInputs>().get());
setSegmentProjection(settings().get<SvgSegmentProjection>().get());
setPolygonal(settings().get<SvgPolygonal>().get());
setAlwaysProject(settings().get<SvgAlwaysProject>().get());
setWithoutStoreys(settings().get<SvgWithoutStoreys>().get());
setNoCSS(settings().get<SvgNoCss>().get());
setMirrorY(settings().get<SvgMirrorY>().get());
setMirrorX(settings().get<SvgMirrorX>().get());
setProfileThreshold(settings().get<SvgProfileThreshold>().get());
setPrintSpaceNames(settings().get<ifcopenshell::geom::settings::SvgPrintSpaceNames>().get());
setPrintSpaceAreas(settings().get<ifcopenshell::geom::settings::SvgPrintSpaceAreas>().get());
setDrawDoorArcs(settings().get<ifcopenshell::geom::settings::SvgDoorArcs>().get());
setAutoSection(settings().get<ifcopenshell::geom::settings::SvgAutoSection>().get());
setAutoElevation(settings().get<ifcopenshell::geom::settings::SvgAutoElevation>().get());
setUseNamespace(settings().get<ifcopenshell::geom::settings::SvgUseNamespace>().get());
setUseHlrPoly(settings().get<ifcopenshell::geom::settings::SvgUseHlrPoly>().get());
setUsePrefiltering(settings().get<ifcopenshell::geom::settings::SvgUsePrefiltering>().get());
setUnifyInputs(settings().get<ifcopenshell::geom::settings::SvgUnifyInputs>().get());
setSegmentProjection(settings().get<ifcopenshell::geom::settings::SvgSegmentProjection>().get());
setPolygonal(settings().get<ifcopenshell::geom::settings::SvgPolygonal>().get());
setAlwaysProject(settings().get<ifcopenshell::geom::settings::SvgAlwaysProject>().get());
setWithoutStoreys(settings().get<ifcopenshell::geom::settings::SvgWithoutStoreys>().get());
setNoCSS(settings().get<ifcopenshell::geom::settings::SvgNoCss>().get());
setMirrorY(settings().get<ifcopenshell::geom::settings::SvgMirrorY>().get());
setMirrorX(settings().get<ifcopenshell::geom::settings::SvgMirrorX>().get());
setProfileThreshold(settings().get<ifcopenshell::geom::settings::SvgProfileThreshold>().get());
if (settings().get<SvgSubtractBefore>().has()) {
setSubtractionSettings(parse_subtract_before_project(settings().get<SvgSubtractBefore>().get()));
if (settings().get<ifcopenshell::geom::settings::SvgSubtractBefore>().has()) {
setSubtractionSettings(parse_subtract_before_project(settings().get<ifcopenshell::geom::settings::SvgSubtractBefore>().get()));
}
if (settings().get<SvgDrawStoreyHeights>().has()) {
setDrawStoreyHeights(parse_storey_height_display(settings().get<SvgDrawStoreyHeights>().get()));
if (settings().get<ifcopenshell::geom::settings::SvgDrawStoreyHeights>().has()) {
setDrawStoreyHeights(parse_storey_height_display(settings().get<ifcopenshell::geom::settings::SvgDrawStoreyHeights>().get()));
}
if (settings().get<SvgStoreyHeightLineLength>().has()) {
setStoreyHeightLineLength(settings().get<SvgStoreyHeightLineLength>().get());
if (settings().get<ifcopenshell::geom::settings::SvgStoreyHeightLineLength>().has()) {
setStoreyHeightLineLength(settings().get<ifcopenshell::geom::settings::SvgStoreyHeightLineLength>().get());
}
if (settings().get<SvgSpaceNameTransform>().has()) {
setSpaceNameTransform(settings().get<SvgSpaceNameTransform>().get());
if (settings().get<ifcopenshell::geom::settings::SvgSpaceNameTransform>().has()) {
setSpaceNameTransform(settings().get<ifcopenshell::geom::settings::SvgSpaceNameTransform>().get());
}
if (settings().get<SvgSectionRef>().has()) {
setSectionRef(settings().get<SvgSectionRef>().get());
if (settings().get<ifcopenshell::geom::settings::SvgSectionRef>().has()) {
setSectionRef(settings().get<ifcopenshell::geom::settings::SvgSectionRef>().get());
}
if (settings().get<SvgElevationRef>().has()) {
setElevationRef(settings().get<SvgElevationRef>().get());
if (settings().get<ifcopenshell::geom::settings::SvgElevationRef>().has()) {
setElevationRef(settings().get<ifcopenshell::geom::settings::SvgElevationRef>().get());
}
if (settings().get<SvgElevationRefGuid>().has()) {
setElevationRefGuid(settings().get<SvgElevationRefGuid>().get());
if (settings().get<ifcopenshell::geom::settings::SvgElevationRefGuid>().has()) {
setElevationRefGuid(settings().get<ifcopenshell::geom::settings::SvgElevationRefGuid>().get());
}
// SVG edge classification (issue #3668): geometry settings, read here so the
// ctor's apply_settings() call applies them for all callers (Bonsai/SWIG + IfcConvert).
svg_ridge_angle_min_deg_ = geometry_settings().get<ifcopenshell::geometry::settings::SvgRidgeAngleMinDegrees>().get();
svg_valley_angle_min_deg_ = geometry_settings().get<ifcopenshell::geometry::settings::SvgValleyAngleMinDegrees>().get();
svg_emit_flush_edges_ = geometry_settings().get<ifcopenshell::geometry::settings::SvgEmitFlushEdges>().get();
svg_use_edge_classification_ = geometry_settings().get<ifcopenshell::geometry::settings::SvgUseEdgeClassification>().get();
svg_render_crease_edges_ = geometry_settings().get<ifcopenshell::geometry::settings::SvgRenderCreaseEdges>().get();
svg_render_sharp_edges_ = geometry_settings().get<ifcopenshell::geometry::settings::SvgRenderSharpEdges>().get();
svg_ridge_angle_min_deg_ = settings().get<ifcopenshell::geom::settings::SvgRidgeAngleMinDegrees>().get();
svg_valley_angle_min_deg_ = settings().get<ifcopenshell::geom::settings::SvgValleyAngleMinDegrees>().get();
svg_emit_flush_edges_ = settings().get<ifcopenshell::geom::settings::SvgEmitFlushEdges>().get();
svg_use_edge_classification_ = settings().get<ifcopenshell::geom::settings::SvgUseEdgeClassification>().get();
svg_render_crease_edges_ = settings().get<ifcopenshell::geom::settings::SvgRenderCreaseEdges>().get();
svg_render_sharp_edges_ = settings().get<ifcopenshell::geom::settings::SvgRenderSharpEdges>().get();
}
void SvgSerializer::write(path_object& p, const TopoDS_Shape& comp_or_wire, std::optional<std::vector<double>> dash_array, std::optional<std::string> css_class) {
void svg_serializer::write(path_object& p, const TopoDS_Shape& comp_or_wire, std::optional<std::vector<double>> dash_array, std::optional<std::string> css_class) {
/* ShapeFix_Wire fix;
Handle(ShapeExtend_WireData) data = new ShapeExtend_WireData;
for (TopExp_Explorer edges(result, TopAbs_EDGE); edges.More(); edges.Next()) {
@@ -472,7 +470,7 @@ void SvgSerializer::write(path_object& p, const TopoDS_Shape& comp_or_wire, std:
ycoords.push_back(path.add(p2.Y()));
} else if (ty != STANDARD_TYPE(Geom_Line)) {
BRepAdaptor_Curve crv(edge);
GCPnts_QuasiUniformDeflection tessellater(crv, geometry_settings().get<ifcopenshell::geometry::settings::MesherLinearDeflection>().get());
GCPnts_QuasiUniformDeflection tessellater(crv, settings().get<ifcopenshell::geom::settings::MesherLinearDeflection>().get());
// NB: Start at 2: 1-based and skip the first point, assume it coincides with p1.
for (int i = 2; i <= tessellater.NbPoints(); ++i) {
gp_Pnt pi = tessellater.Value(i);
@@ -525,29 +523,29 @@ void SvgSerializer::write(path_object& p, const TopoDS_Shape& comp_or_wire, std:
}
}
SvgSerializer::path_object& SvgSerializer::start_path(const gp_Pln& pln, const express::Base& storey, const std::string& id) {
svg_serializer::path_object& svg_serializer::start_path(const gp_Pln& pln, const express::base& storey, const std::string& id) {
auto key = std::make_pair(std::make_pair(storey, ""), path_object());
SvgSerializer::path_object& p = paths.insert(key)->second;
svg_serializer::path_object& p = paths.insert(key)->second;
drawing_metadata[key.first].pln_3d = pln;
p.first = id;
return p;
}
SvgSerializer::path_object& SvgSerializer::start_path(const gp_Pln& pln, const std::string& drawing_name, const std::string& id) {
auto key = std::make_pair(std::make_pair(express::Base{}, drawing_name), path_object());
SvgSerializer::path_object& p = paths.insert(key)->second;
svg_serializer::path_object& svg_serializer::start_path(const gp_Pln& pln, const std::string& drawing_name, const std::string& id) {
auto key = std::make_pair(std::make_pair(express::base{}, drawing_name), path_object());
svg_serializer::path_object& p = paths.insert(key)->second;
drawing_metadata[key.first].pln_3d = pln;
p.first = id;
return p;
}
namespace {
std::optional<std::pair<express::Base, double>> storey_elevation_from_element(const IfcGeom::BRepElement* o) {
std::optional<std::pair<express::base, double>> storey_elevation_from_element(const ifcopenshell::geom::brep_element* o) {
for (const auto& p : o->parents()) {
if (p->type() == "IfcBuildingStorey") {
try {
double e = p->product().get("Elevation");
double storey_elevation = e * o->geometry().settings().get<ifcopenshell::geometry::settings::LengthUnit>().get();
double storey_elevation = e * o->geometry().settings().get<ifcopenshell::geom::settings::LengthUnit>().get();
return std::make_pair(p->product(), storey_elevation);
} catch (...) {
continue;
@@ -619,7 +617,7 @@ namespace {
*/
auto& shell = compound;
if (IfcGeom::util::count(shell, TopAbs_FACE) != 6) {
if (ifcopenshell::geom::util::count(shell, TopAbs_FACE) != 6) {
return std::nullopt;
}
@@ -655,11 +653,11 @@ namespace {
};
template <typename It>
void enumerate_string_properties(const express::Base& product, It output_it) {
auto rels = product.as<express::Entity>().get_inverse("IsDefinedBy");
void enumerate_string_properties(const express::base& product, It output_it) {
auto rels = product.as<express::entity>().get_inverse("IsDefinedBy");
for (auto& rel : rels) {
if (rel.declaration().is("IfcRelDefinesByProperties")) {
auto pset = ((express::Base)rel.get("RelatingPropertyDefinition")).as<express::Entity>();
auto pset = ((express::base)rel.get("RelatingPropertyDefinition")).as<express::entity>();
if (!pset.declaration().is("IfcPropertySet")) {
continue;
}
@@ -667,14 +665,14 @@ namespace {
if (!pset.get("Name").isNull()) {
pset_name = (std::string) pset.get("Name");
}
std::vector<express::Base> props = pset.get("HasProperties");
std::vector<express::base> props = pset.get("HasProperties");
for (auto& prop : props) {
if (prop.declaration().is("IfcPropertySingleValue")) {
std::string name = prop.as<express::Entity>().get("Name");
if (prop.as<express::Entity>().get("NominalValue").isNull()) {
std::string name = prop.as<express::entity>().get("Name");
if (prop.as<express::entity>().get("NominalValue").isNull()) {
continue;
}
express::Base v = prop.as<express::Entity>().get("NominalValue");
express::base v = prop.as<express::entity>().get("NominalValue");
auto value = v.get_attribute_value(0);
if (value.type() == ifcopenshell::Argument_STRING) {
std::string v_str = value;
@@ -688,20 +686,20 @@ namespace {
}
namespace {
std::optional<std::string> get_curve_style_name(const express::Base& item) {
auto refs = item.as<express::Entity>().get_inverse("StyledByItem");
std::optional<std::string> get_curve_style_name(const express::base& item) {
auto refs = item.as<express::entity>().get_inverse("StyledByItem");
for (auto& ref : refs) {
if (ref.declaration().is("IfcStyledItem")) {
std::vector<express::Base> styles = ref.as<express::Entity>().get("Styles");
std::vector<express::base> styles = ref.as<express::entity>().get("Styles");
for (auto& s : styles) {
std::vector<express::Entity> pss;
std::vector<express::entity> pss;
if (s.declaration().is("IfcPresentationStyleAssignment")) {
std::vector<express::Base> pstyles = s.as<express::Entity>().get("Styles");
std::vector<express::base> pstyles = s.as<express::entity>().get("Styles");
for (auto& ssss : pstyles) {
pss.push_back(ssss.as<express::Entity>());
pss.push_back(ssss.as<express::entity>());
}
} else {
pss.push_back(s.as<express::Entity>());
pss.push_back(s.as<express::entity>());
}
for (auto& ps : pss) {
if (ps.declaration().is("IfcCurveStyle")) {
@@ -718,7 +716,7 @@ namespace {
}
}
void SvgSerializer::write(const IfcGeom::BRepElement* brep_obj) {
void svg_serializer::write(const ifcopenshell::geom::brep_element* brep_obj) {
std::optional<std::string> object_type;
if (!brep_obj->product().get("ObjectType").isNull()) {
@@ -728,7 +726,7 @@ void SvgSerializer::write(const IfcGeom::BRepElement* brep_obj) {
std::vector<std::optional<std::vector<double>>> dash_arrays;
auto itm = brep_obj->geometry().as_compound();
TopoDS_Shape compound_local = ((ifcopenshell::geometry::OpenCascadeShape*)itm)->shape();
TopoDS_Shape compound_local = ((ifcopenshell::geom::open_cascade_shape*)itm)->shape();
delete itm;
for (auto& x : brep_obj->geometry()) {
@@ -854,7 +852,7 @@ void SvgSerializer::write(const IfcGeom::BRepElement* brep_obj) {
if (pln) {
// Move pln to have projection of origin at plane center.
// This is necessary to have Poly and BRep HLR at the same position
// This is necessary to have Poly and brep HLR at the same position
// (Poly) is wrong otherwise.
double pu, pv;
Extrema_ExtPElS ext;
@@ -889,12 +887,12 @@ void SvgSerializer::write(const IfcGeom::BRepElement* brep_obj) {
}
auto p = storey_elevation_from_element(brep_obj);
auto storey = p ? p->first : express::Base{};
auto storey = p ? p->first : express::base{};
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?)
if (unify_inputs_) {
compound_local = IfcGeom::util::unify(compound_local, 1.e-6);
compound_local = ifcopenshell::geom::util::unify(compound_local, 1.e-6);
}
{
@@ -906,9 +904,9 @@ void SvgSerializer::write(const IfcGeom::BRepElement* brep_obj) {
for (; it.More(); it.Next()) {
auto& s = it.Value();
if (s.ShapeType() == TopAbs_WIRE && s.Closed()) {
IfcGeom::util::wire_tolerance_settings wts{ false, false, Precision::Confusion(), Precision::Confusion() };
ifcopenshell::geom::util::wire_tolerance_settings wts{ false, false, Precision::Confusion(), Precision::Confusion() };
TopoDS_Compound faces;
IfcGeom::util::convert_wire_to_faces(TopoDS::Wire(s), faces, wts);
ifcopenshell::geom::util::convert_wire_to_faces(TopoDS::Wire(s), faces, wts);
BB.Add(comp2, faces);
any_wires_converted_to_face = true;
} else {
@@ -918,7 +916,7 @@ void SvgSerializer::write(const IfcGeom::BRepElement* brep_obj) {
compound_local = comp2;
}
if (only_valid_ && !IfcGeom::util::validate_shape(compound_local)) {
if (only_valid_ && !ifcopenshell::geom::util::validate_shape(compound_local)) {
return;
}
@@ -1058,7 +1056,7 @@ namespace {
// curves back towards the solid's interior relative to f0 -- a convex fold, like a box
// corner. This avoids relying on TopoDS_Edge/wire orientation semantics (which proved
// unreliable in practice: an earlier attempt using edge.Orientation() combined with
// cross(n0, n1) gave a self-consistent-looking but wrong sign on real BRep topology --
// cross(n0, n1) gave a self-consistent-looking but wrong sign on real brep topology --
// verified against known-convex geometry, e.g. every edge of a convex icosphere, where
// that approach misclassified a majority of edges as concave).
double deviation_deg = std::acos(clamp_dot(n0.Dot(n1))) * 180.0 / M_PI;
@@ -1126,7 +1124,7 @@ namespace {
}
}
void SvgSerializer::write(const geometry_data& data) {
void svg_serializer::write(const geometry_data& data) {
std::vector<section_data> section_heights_storage;
const std::vector<section_data>* section_heights_used = &section_heights_storage;
@@ -1180,20 +1178,20 @@ void SvgSerializer::write(const geometry_data& data) {
std::optional<std::string> operation_type;
try {
std::vector<express::Entity> rels;
std::vector<express::entity> rels;
if (data.product.declaration().schema()->name() == "IFC2X3") {
rels = data.product.as<express::Entity>().get_inverse("IsDefinedBy");
rels = data.product.as<express::entity>().get_inverse("IsDefinedBy");
} else {
// Damn you, IFC
rels = data.product.as<express::Entity>().get_inverse("IsTypedBy");
rels = data.product.as<express::entity>().get_inverse("IsTypedBy");
}
for (auto& rel : rels) {
if (rel.declaration().name() == "IfcRelDefinesByType") {
express::Base ty = rel.as<express::Entity>().get("RelatingType");
express::base ty = rel.as<express::entity>().get("RelatingType");
const std::string& ty_entity_name = ty.declaration().name();
// Damn you, IFC
if (ty_entity_name == "IfcDoorStyle" || ty_entity_name == "IfcDoorType") {
operation_type = ty.as<express::Entity>().get("OperationType");
operation_type = ty.as<express::entity>().get("OperationType");
}
}
}
@@ -1275,7 +1273,7 @@ void SvgSerializer::write(const geometry_data& data) {
gp_Vec projection_direction;
gp_Pln projection_plane;
express::Base storey;
express::base storey;
std::string drawing_name;
bool use_hlr = always_project_;
@@ -1708,7 +1706,7 @@ void SvgSerializer::write(const geometry_data& data) {
auto proj = projection_direction ^ bbdif ^ projection_direction;
std::string object_type;
auto ot_arg = data.product.as<express::Entity>().get("ObjectType");
auto ot_arg = data.product.as<express::entity>().get("ObjectType");
if (!ot_arg.isNull()) {
object_type = (std::string) ot_arg;
object_type.erase(std::remove_if(object_type.begin(), object_type.end(), [](char c) { return !std::isalnum(c); }), object_type.end());
@@ -1911,12 +1909,12 @@ void SvgSerializer::write(const geometry_data& data) {
}
if (file && data.product.declaration().is("IfcBuildingStorey") && storey_height_display_ != SH_NONE && wires->Length() == 1 && IfcGeom::util::count(wire, TopAbs_EDGE) == 1) {
if (file && data.product.declaration().is("IfcBuildingStorey") && storey_height_display_ != SH_NONE && wires->Length() == 1 && ifcopenshell::geom::util::count(wire, TopAbs_EDGE) == 1) {
std::string elev_str;
const double lu = file->get_unit("LENGTHUNIT").second;
auto a = data.product.as<express::Entity>().get("Elevation");
auto a = data.product.as<express::entity>().get("Elevation");
if (!a.isNull()) {
double elev = a;
@@ -2062,7 +2060,7 @@ void SvgSerializer::write(const geometry_data& data) {
labels.push_back(data.ifc_name);
}
if (print_space_names_ && data.product.declaration().is("IfcSpace")) {
auto attr = data.product.as<express::Entity>().get("LongName");
auto attr = data.product.as<express::entity>().get("LongName");
if (!attr.isNull()) {
std::string long_name = attr;
if (!long_name.empty()) {
@@ -2121,11 +2119,11 @@ void SvgSerializer::write(const geometry_data& data) {
}
}
void SvgSerializer::setBoundingRectangle(double width, double height) {
void svg_serializer::setBoundingRectangle(double width, double height) {
size_ = std::make_pair(width, height);
}
std::array<std::array<double, 3>, 3> SvgSerializer::resize() {
std::array<std::array<double, 3>, 3> svg_serializer::resize() {
// identity matrix;
std::array<std::array<double, 3>, 3> m = {{ {{1,0,0}},{{0,1,0}},{{0,0,1}} }};
@@ -2189,7 +2187,7 @@ std::array<std::array<double, 3>, 3> SvgSerializer::resize() {
return m;
}
void SvgSerializer::draw_hlr(const gp_Pln& pln, const drawing_key& drawing_name) {
void svg_serializer::draw_hlr(const gp_Pln& pln, const drawing_key& drawing_name) {
hlr_t& hlr_source = drawing_name.first ? this->storey_hlr.find(drawing_name.first)->second : *hlr;
auto hlr_items = hlr_source.build();
@@ -2200,10 +2198,10 @@ void SvgSerializer::draw_hlr(const gp_Pln& pln, const drawing_key& drawing_name)
// product (one per non-empty class bucket); keep a single path_object/group per product so
// per-path classes survive Bonsai's merge_linework_and_add_metadata untouched, rather than
// creating a <g> per class (see plan notes on why that clobbers classes in Python).
std::map<express::Base, path_object*> group_by_product;
std::map<express::base, path_object*> group_by_product;
for (auto& item : hlr_items) {
express::Base product = std::get<0>(item);
express::base product = std::get<0>(item);
const std::string& cls = std::get<1>(item);
const TopoDS_Shape& hlr_compound_unmirrored = std::get<2>(item);
@@ -2273,7 +2271,7 @@ void SvgSerializer::draw_hlr(const gp_Pln& pln, const drawing_key& drawing_name)
}
}
void SvgSerializer::resetScale() {
void svg_serializer::resetScale() {
// reset the bounding box, as a subsequent drawing (elevation, section) will be centered, but use the same scale.
// this is a separate call now as we first need to read drawing extents for automatically positioning sections and
// elevations
@@ -2283,7 +2281,7 @@ void SvgSerializer::resetScale() {
ymax = -std::numeric_limits<double>::infinity();
}
void SvgSerializer::addTextAnnotations(const drawing_key& k) {
void svg_serializer::addTextAnnotations(const drawing_key& k) {
auto& meta = drawing_metadata[k];
std::optional<std::pair<double, double>> range;
@@ -2299,12 +2297,12 @@ void SvgSerializer::addTextAnnotations(const drawing_key& k) {
}
}
std::vector<express::Base> annotations;
std::vector<express::base> annotations;
if (file) {
annotations = file->instances_by_type("IfcAnnotation");
}
for (auto& ann_ : annotations) {
auto ann = ann_.as<express::Entity>();
auto ann = ann_.as<express::entity>();
auto ot = ann.get("ObjectType");
auto nm = ann.get("Name");
@@ -2317,9 +2315,9 @@ void SvgSerializer::addTextAnnotations(const drawing_key& k) {
auto desc = (std::string) ds;
if (object_type == "Text") {
auto mapping = ifcopenshell::geometry::impl::mapping_implementations().construct(file, geometry_settings_, logger());
auto mapping = ifcopenshell::geom::impl::mapping_implementations().construct(file, settings_, logger());
auto item = mapping->map(pl);
auto matrix = ifcopenshell::geometry::taxonomy::cast<ifcopenshell::geometry::taxonomy::matrix4>(item);
auto matrix = ifcopenshell::geom::taxonomy::cast<ifcopenshell::geom::taxonomy::matrix4>(item);
delete mapping;
if (item) {
gp_Trsf trsf;
@@ -2428,7 +2426,7 @@ void SvgSerializer::addTextAnnotations(const drawing_key& k) {
}
}
void SvgSerializer::finalize() {
void svg_serializer::finalize() {
doWriteHeader();
for (auto& p : drawing_metadata) {
@@ -2532,16 +2530,16 @@ void SvgSerializer::finalize() {
const auto& section = boost::get<vertical_section>(sd);
const auto& ax = section.plane.Position();
draw_hlr(ax, { express::Base{}, drawing_name });
draw_hlr(ax, { express::base{}, drawing_name });
}
addTextAnnotations({express::Base{}, drawing_name});
addTextAnnotations({express::base{}, drawing_name});
if (file && storey_height_display_ != SH_NONE && pln && std::abs(pln->Position().Direction().Z()) < 1.e-5) {
auto storeys = file->instances_by_type("IfcBuildingStorey");
const double lu = file->get_unit("LENGTHUNIT").second;
for (auto& s : storeys) {
auto storey = s.as<express::Entity>();
auto storey = s.as<express::entity>();
auto a = storey.get("Elevation");
if (!a.isNull()) {
double elev = a;
@@ -2587,7 +2585,7 @@ void SvgSerializer::finalize() {
auto m3 = resize();
auto k = std::make_pair(express::Base{}, drawing_name);
auto k = std::make_pair(express::base{}, drawing_name);
drawing_metadata[k].matrix_3 = m3;
resetScale();
@@ -2634,12 +2632,12 @@ void SvgSerializer::finalize() {
svg_file.stream << "</svg>" << std::endl;
}
void SvgSerializer::writeHeader() {
void svg_serializer::writeHeader() {
// This doesn't do anything anymore because there is now the option that an
// IfcAnnotation[ObjectType=DRAWING] defines the SVG viewBox and dimensions
}
void SvgSerializer::doWriteHeader() {
void svg_serializer::doWriteHeader() {
svg_file.stream << "<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"";
if (use_namespace_) {
svg_file.stream << " xmlns:ifc=\"http://www.ifcopenshell.org/ns\"";
@@ -2750,34 +2748,34 @@ return oss.str();
}
}
std::string SvgSerializer::nameElement(express::Base storey, const IfcGeom::Element* elem) {
std::string svg_serializer::nameElement(express::base storey, const ifcopenshell::geom::element* elem) {
auto n = elem->name();
ifcopenshell::escape_xml(n);
return nameElement_({
{"id", with_section_heights_from_storey_ ? object_id(storey, elem) : GeometrySerializer::object_id(elem)},
{"id", with_section_heights_from_storey_ ? object_id(storey, elem) : geometry_serializer::object_id(elem)},
{"class", elem->type()},
{namespace_prefix_ + "name", n},
{namespace_prefix_ + "guid", elem->guid()}
});
}
std::string SvgSerializer::idElement(express::Base elem_) {
auto elem = elem_.as<express::Entity>();
std::string svg_serializer::idElement(express::base elem_) {
auto elem = elem_.as<express::entity>();
const std::string type = elem.declaration().is("IfcBuildingStorey") ? "storey" : "product";
const std::string name =
(settings().get<ifcopenshell::geometry::settings::UseElementGuids>().get()
(settings().get<ifcopenshell::geom::settings::UseElementGuids>().get()
? static_cast<std::string>(elem.get("GlobalId"))
: ((settings().get<ifcopenshell::geometry::settings::UseElementNames>().get() && !elem.get("Name").isNull()))
: ((settings().get<ifcopenshell::geom::settings::UseElementNames>().get() && !elem.get("Name").isNull()))
? static_cast<std::string>(elem.get("Name"))
: (settings().get<ifcopenshell::geometry::settings::UseElementStepIds>().get())
: (settings().get<ifcopenshell::geom::settings::UseElementStepIds>().get())
? ("id-" + boost::lexical_cast<std::string>(elem.id()))
: ifcopenshell::global_id(elem.get("GlobalId")).formatted());
return type + "-" + name;
}
std::string SvgSerializer::nameElement(express::Base elem_) {
auto elem = elem_.as<express::Entity>();
std::string svg_serializer::nameElement(express::base elem_) {
auto elem = elem_.as<express::entity>();
if (!elem) { return ""; }
const std::string& entity = elem.declaration().name();
@@ -2795,14 +2793,12 @@ std::string SvgSerializer::nameElement(express::Base elem_) {
});
}
void SvgSerializer::setFile(ifcopenshell::file& f) {
using namespace ifcopenshell::geometry::settings;
void svg_serializer::setFile(ifcopenshell::file& f) {
file = &f;
auto apply_section_heights_from_storeys = [&]() {
if (settings().get<SvgSectionHeightFromStoreys>().get()) {
if (settings().get<SvgSectionHeight>().has()) {
setSectionHeightsFromStoreys(settings().get<SvgSectionHeight>().get());
if (settings().get<ifcopenshell::geom::settings::SvgSectionHeightFromStoreys>().get()) {
if (settings().get<ifcopenshell::geom::settings::SvgSectionHeight>().has()) {
setSectionHeightsFromStoreys(settings().get<ifcopenshell::geom::settings::SvgSectionHeight>().get());
} else {
setSectionHeightsFromStoreys();
}
@@ -2811,7 +2807,7 @@ void SvgSerializer::setFile(ifcopenshell::file& f) {
auto storeys = f.instances_by_type("IfcBuildingStorey");
if (storeys.empty()) {
auto mapping = ifcopenshell::geometry::impl::mapping_implementations().construct(file, geometry_settings_, logger());
auto mapping = ifcopenshell::geom::impl::mapping_implementations().construct(file, settings_, logger());
std::vector<const ifcopenshell::declaration*> to_derive_from;
to_derive_from.push_back(f.schema()->declaration_by_name("IfcBuilding"));
@@ -2819,10 +2815,10 @@ void SvgSerializer::setFile(ifcopenshell::file& f) {
for (auto it = to_derive_from.begin(); it != to_derive_from.end(); ++it) {
auto insts = f.instances_by_type(*it);
for (auto& inst : insts) {
auto product = inst.as<express::Entity>();
auto product = inst.as<express::entity>();
if (!product.get("ObjectPlacement").isNull()) {
auto item = mapping->map(product.get("ObjectPlacement"));
auto matrix = ifcopenshell::geometry::taxonomy::cast<ifcopenshell::geometry::taxonomy::matrix4>(item);
auto matrix = ifcopenshell::geom::taxonomy::cast<ifcopenshell::geom::taxonomy::matrix4>(item);
gp_Trsf trsf;
if (matrix) {
// @todo shouldn't this take into account configurable section height?
@@ -2846,12 +2842,12 @@ void SvgSerializer::setFile(ifcopenshell::file& f) {
apply_section_heights_from_storeys();
}
void SvgSerializer::setSectionHeight(double h, express::Base storey) {
void svg_serializer::setSectionHeight(double h, express::base storey) {
section_data_.emplace();
section_data_->push_back(horizontal_plan{ storey, h, 0., std::numeric_limits<double>::infinity() });
}
void SvgSerializer::setSectionHeightsFromStoreys(double offset) {
void svg_serializer::setSectionHeightsFromStoreys(double offset) {
if (!file) {
logger().error("SER", 32, "No file specified");
return;
@@ -2862,7 +2858,7 @@ void SvgSerializer::setSectionHeightsFromStoreys(double offset) {
const double lu = file->get_unit("LENGTHUNIT").second;
if (!storeys.empty()) {
for (auto& s : storeys) {
auto attr_value = s.as<express::Entity>().get("Elevation");
auto attr_value = s.as<express::entity>().get("Elevation");
if (!attr_value.isNull()) {
double elev;
try {
@@ -2898,7 +2894,7 @@ namespace {
}
}
std::string SvgSerializer::writeMetadata(const drawing_meta& m) {
std::string svg_serializer::writeMetadata(const drawing_meta& m) {
gp_Trsf trsf;
trsf.SetTransformation(m.pln_3d.Position(), gp::XOY());
NCollection_Mat4<double> mat4;
+38 -38
View File
@@ -58,7 +58,7 @@
#include <array>
#include <tuple>
typedef std::pair<express::Base, std::string> drawing_key;
typedef std::pair<express::base, std::string> drawing_key;
struct storey_sorter {
bool operator()(const drawing_key& ad, const drawing_key& bd) const {
@@ -78,8 +78,8 @@ struct storey_sorter {
if (a_is_storey && b_is_storey) {
std::optional<double> a_elev, b_elev;
try {
a_elev = static_cast<double>(a.as<express::Entity>().get("Elevation"));
b_elev = static_cast<double>(b.as<express::Entity>().get("Elevation"));
a_elev = static_cast<double>(a.as<express::entity>().get("Elevation"));
b_elev = static_cast<double>(b.as<express::entity>().get("Elevation"));
} catch (...) {};
if (a_elev && b_elev) {
if (std::equal_to<double>()(*a_elev, *b_elev)) {
@@ -91,8 +91,8 @@ struct storey_sorter {
std::optional<std::string> a_name, b_name;
try {
a_name = static_cast<std::string>(a.as<express::Entity>().get("Name"));
b_name = static_cast<std::string>(b.as<express::Entity>().get("Name"));
a_name = static_cast<std::string>(a.as<express::entity>().get("Name"));
b_name = static_cast<std::string>(b.as<express::entity>().get("Name"));
} catch (...) {};
if (a_name && b_name) {
if (std::equal_to<std::string>()(*a_name, *b_name)) {
@@ -102,12 +102,12 @@ struct storey_sorter {
}
}
}
return std::less<express::Base>()(a, b);
return std::less<express::base>()(a, b);
}
};
struct horizontal_plan {
express::Base storey;
express::base storey;
double elevation, offset, next_elevation;
};
@@ -127,8 +127,8 @@ struct geometry_data {
TopoDS_Shape compound_local;
std::vector<std::optional<std::vector<double>>> dash_arrays;
gp_Trsf trsf;
express::Base product;
express::Base storey;
express::base product;
express::base storey;
double storey_elevation;
std::string ifc_name, svg_name;
};
@@ -212,23 +212,23 @@ namespace {
class hlr_calc {
private:
const HLRAlgo_Projector& projector_;
const std::list<std::pair<express::Base, TopoDS_Shape>>* product_shapes_ = nullptr;
const std::list<std::pair<express::base, TopoDS_Shape>>* product_shapes_ = nullptr;
// SVG edge classification (issue #3668): per-(product, class) edge-only sub-shapes,
// classified pre-HLR on the original (real-face) topology. Empty class string means
// "unclassified" (used for the two fallback cases below).
const std::list<std::tuple<express::Base, std::string, TopoDS_Shape>>* classified_shapes_ = nullptr;
const std::list<std::tuple<express::base, std::string, TopoDS_Shape>>* classified_shapes_ = nullptr;
public:
typedef std::list<std::tuple<express::Base, std::string, TopoDS_Shape>> result_type;
typedef std::list<std::tuple<express::base, std::string, TopoDS_Shape>> result_type;
hlr_calc(const HLRAlgo_Projector& projector) : projector_(projector)
{}
void set_product_shape(const std::list<std::pair<express::Base, TopoDS_Shape>>* product_shapes) {
void set_product_shape(const std::list<std::pair<express::base, TopoDS_Shape>>* product_shapes) {
product_shapes_ = product_shapes;
}
void set_classified_shapes(const std::list<std::tuple<express::Base, std::string, TopoDS_Shape>>* classified_shapes) {
void set_classified_shapes(const std::list<std::tuple<express::base, std::string, TopoDS_Shape>>* classified_shapes) {
classified_shapes_ = classified_shapes;
}
@@ -244,7 +244,7 @@ namespace {
r.push_back({ p.first, std::string(), occt_join(hlr_shapes.OutLineVCompound(p.second), hlr_shapes.VCompound(p.second)) });
}
} else {
r.push_back({ express::Base{}, std::string(), occt_join(hlr_shapes.OutLineVCompound(), hlr_shapes.VCompound()) });
r.push_back({ express::base{}, std::string(), occt_join(hlr_shapes.OutLineVCompound(), hlr_shapes.VCompound()) });
}
return r;
}
@@ -289,7 +289,7 @@ namespace {
, fclass(nullptr)
{
TopExp_Explorer exp(face, TopAbs_WIRE);
is_convex = exp.More() && IfcGeom::util::is_convex(TopoDS::Wire(exp.Current()), 1.e-5) && ([&exp]() {exp.Next(); return true; })() && !exp.More();
is_convex = exp.More() && ifcopenshell::geom::util::is_convex(TopoDS::Wire(exp.Current()), 1.e-5) && ([&exp]() {exp.Next(); return true; })() && !exp.More();
auto surf = BRep_Tool::Surface(fa);
if (surf->DynamicType() != STANDARD_TYPE(Geom_Plane)) {
@@ -376,9 +376,9 @@ namespace {
HLRAlgo_Projector projector_;
std::multimap<double, face_info> large_ortho_faces_;
std::list<std::pair<express::Base, TopoDS_Shape>> items_;
std::list<std::pair<express::base, TopoDS_Shape>> items_;
// SVG edge classification (issue #3668): see add_classified_edges().
std::list<std::tuple<express::Base, std::string, TopoDS_Shape>> classified_items_;
std::list<std::tuple<express::base, std::string, TopoDS_Shape>> classified_items_;
::logger& logger_;
@@ -406,7 +406,7 @@ namespace {
// SVG edge classification (issue #3668): register an edge-only sub-shape of `product`'s
// original (pre-HLR, real-face) geometry under a given class name. The full shape must
// still be added via add() as usual for correct occlusion.
void add_classified_edges(express::Base product, const std::string& cls, const TopoDS_Shape& edges) {
void add_classified_edges(express::base product, const std::string& cls, const TopoDS_Shape& edges) {
classified_items_.push_back({ product, cls, edges });
}
@@ -451,7 +451,7 @@ namespace {
return false;
}
void add(const TopoDS_Shape& s, express::Base product) {
void add(const TopoDS_Shape& s, express::base product) {
if (!use_prefiltering_) {
items_.insert(items_.end(), {product, s});
return;
@@ -465,7 +465,7 @@ namespace {
gp_Vec V;
gp_Dir D;
if (IfcGeom::util::is_manifold(s)) {
if (ifcopenshell::geom::util::is_manifold(s)) {
size_t n_faces_included = 0, n_total = 0;
{
TopExp_Explorer exp(s, TopAbs_FACE);
@@ -506,7 +506,7 @@ namespace {
D = V;
if (D.Dot(view_direction_.Direction()) > (1. - 1.e-3)) {
if (IfcGeom::util::face_area(face) > 2.) {
if (ifcopenshell::geom::util::face_area(face) > 2.) {
// arbitrary vertex, is ok because orthogonal to view dir
TopExp_Explorer expv(face, TopAbs_VERTEX);
if (expv.More()) {
@@ -529,7 +529,7 @@ namespace {
}
}
std::list<std::tuple<express::Base, std::string, TopoDS_Shape>> build() {
std::list<std::tuple<express::base, std::string, TopoDS_Shape>> build() {
size_t n_included = 0;
for (auto it = items_.begin(); it != items_.end(); ++it) {
if (!use_prefiltering_ || !is_obscured_(&it->second)) {
@@ -554,7 +554,7 @@ namespace {
typedef prefiltered_hlr hlr_t;
class SERIALIZERS_API SvgSerializer : public WriteOnlyGeometrySerializer {
class SERIALIZERS_API svg_serializer : public write_only_geometry_serializer {
public:
typedef std::pair<std::string, std::vector<util::string_buffer> > path_object;
typedef std::vector< boost::shared_ptr<util::string_buffer::float_item> > float_item_list;
@@ -599,10 +599,10 @@ protected:
bool svg_render_sharp_edges_;
ifcopenshell::file* file;
express::Base storey_;
express::base storey_;
std::multimap<drawing_key, path_object, storey_sorter> paths;
std::map<drawing_key, drawing_meta> drawing_metadata;
std::map<express::Base, hlr_t> storey_hlr;
std::map<express::base, hlr_t> storey_hlr;
float_item_list xcoords, ycoords, radii;
size_t xcoords_begin, ycoords_begin, radii_begin;
@@ -625,8 +625,8 @@ protected:
subtract_before_project subtraction_settings_;
public:
SvgSerializer(const stream_or_filename& out_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, ::logger* logger = nullptr)
: WriteOnlyGeometrySerializer(geometry_settings, settings, logger)
svg_serializer(const stream_or_filename& out_filename, const ifcopenshell::geom::settings& settings, ::logger* logger = nullptr)
: write_only_geometry_serializer(settings, logger)
, svg_file(out_filename)
, xmin(+std::numeric_limits<double>::infinity())
, ymin(+std::numeric_limits<double>::infinity())
@@ -675,18 +675,18 @@ public:
void writeHeader();
void doWriteHeader();
bool ready();
void write(const IfcGeom::TriangulationElement* /*o*/) {}
void write(const IfcGeom::BRepElement* o);
void write(const ifcopenshell::geom::triangulation_element* /*o*/) {}
void write(const ifcopenshell::geom::brep_element* o);
void write(path_object& p, const TopoDS_Shape& wire, std::optional<std::vector<double>> dash_array=std::nullopt, std::optional<std::string> css_class=std::nullopt);
void write(const geometry_data& data);
path_object& start_path(const gp_Pln& p, const express::Base& storey, const std::string& id);
path_object& start_path(const gp_Pln& p, const express::base& 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(ifcopenshell::file& f);
void setBoundingRectangle(double width, double height);
void setSectionHeight(double h, express::Base storey = express::Base());
void setSectionHeight(double h, express::base storey = express::base());
void setSectionHeightsFromStoreys(double offset=1.2);
void setPrintSpaceNames(bool b) { print_space_names_ = b; }
void setPrintSpaceAreas(bool b) { print_space_areas_ = b; }
@@ -782,14 +782,14 @@ public:
void setDrawingCenter(double x, double y) {
center_x_ = x; center_y_ = y;
}
std::string nameElement(express::Base storey, const IfcGeom::Element* elem);
std::string nameElement(express::Base elem);
std::string idElement(express::Base elem);
std::string object_id(express::Base storey, const IfcGeom::Element* o) {
std::string nameElement(express::base storey, const ifcopenshell::geom::element* elem);
std::string nameElement(express::base elem);
std::string idElement(express::base elem);
std::string object_id(express::base storey, const ifcopenshell::geom::element* o) {
if (storey) {
return idElement(storey) + "-" + GeometrySerializer::object_id(o);
return idElement(storey) + "-" + geometry_serializer::object_id(o);
} else {
return GeometrySerializer::object_id(o);
return geometry_serializer::object_id(o);
}
}
+20 -23
View File
@@ -233,36 +233,35 @@ namespace {
}
}
TtlWktSerializer::TtlWktSerializer(const stream_or_filename& filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, ::logger* logger)
: WriteOnlyGeometrySerializer(geometry_settings, settings, logger)
ttl_wkt_serializer::ttl_wkt_serializer(const stream_or_filename& filename, const ifcopenshell::geom::settings& settings, ::logger* logger)
: write_only_geometry_serializer(settings, logger)
, filename_(filename)
{
const auto& tri_setting = geometry_settings.get<ifcopenshell::geometry::settings::TriangulationType>().get();
if (settings_.get<ifcopenshell::geometry::settings::WktUseSection>().get()) {
const auto& it_output = geometry_settings.get<ifcopenshell::geometry::settings::IteratorOutput>().get();
if (it_output != ifcopenshell::geometry::settings::NATIVE) {
const auto& tri_setting = settings.get<ifcopenshell::geom::settings::TriangulationType>().get();
if (settings_.get<ifcopenshell::geom::settings::WktUseSection>().get()) {
const auto& it_output = settings.get<ifcopenshell::geom::settings::IteratorOutput>().get();
if (it_output != ifcopenshell::geom::settings::NATIVE) {
throw std::runtime_error("The RDF Turtle WKT serializer needs native geometry when section mode is enabled");
}
} else {
if (tri_setting != ifcopenshell::geometry::settings::POLYHEDRON_WITH_HOLES) {
if (tri_setting != ifcopenshell::geom::settings::POLYHEDRON_WITH_HOLES) {
throw std::runtime_error("The RDF Turtle WKT serializer needs POLYHEDRON_WITH_HOLES triangulation output");
}
}
filename_.stream << std::setprecision(settings.get<ifcopenshell::geometry::settings::FloatingPointDigits>().get());
filename_.stream << std::setprecision(settings.get<ifcopenshell::geom::settings::FloatingPointDigits>().get());
}
bool TtlWktSerializer::ready()
bool ttl_wkt_serializer::ready()
{
return filename_.is_ready();
}
void TtlWktSerializer::writeHeader()
void ttl_wkt_serializer::writeHeader()
{
using namespace ifcopenshell::geometry::settings;
filename_.stream << "# File generated by IfcOpenShell " << IFCOPENSHELL_VERSION << "\n";
filename_.stream << "@prefix geo: <http://www.opengis.net/ont/geosparql#> .\n";
if (settings_.get<BaseUri>().has()) {
filename_.stream << "@prefix base: <" << settings_.get<BaseUri>().get() << "> .\n";
if (settings_.get<ifcopenshell::geom::settings::BaseUri>().has()) {
filename_.stream << "@prefix base: <" << settings_.get<ifcopenshell::geom::settings::BaseUri>().get() << "> .\n";
} else {
filename_.stream << "@prefix base: <http://example.org/> .\n";
}
@@ -270,7 +269,7 @@ void TtlWktSerializer::writeHeader()
filename_.stream << "@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .\n\n\n";
}
void TtlWktSerializer::write(const IfcGeom::TriangulationElement* o)
void ttl_wkt_serializer::write(const ifcopenshell::geom::triangulation_element* o)
{
filename_.stream << ttl_object_id(o) << " a geo:Feature ;\n";
filename_.stream << " dcterms:identifier " << escape_for_turtle(
@@ -363,7 +362,7 @@ void TtlWktSerializer::write(const IfcGeom::TriangulationElement* o)
}
}
void TtlWktSerializer::write(const IfcGeom::BRepElement* brep_obj) {
void ttl_wkt_serializer::write(const ifcopenshell::geom::brep_element* brep_obj) {
#ifdef IFOPSH_WITH_OPENCASCADE
filename_.stream << ttl_object_id(brep_obj) << " a geo:Feature ;\n";
filename_.stream << " dcterms:identifier " << escape_for_turtle(
@@ -375,7 +374,7 @@ void TtlWktSerializer::write(const IfcGeom::BRepElement* brep_obj) {
// @todo unify logic with SVG serializer
auto itm = brep_obj->geometry().as_compound();
TopoDS_Shape compound_local = ((ifcopenshell::geometry::OpenCascadeShape*)itm)->shape();
TopoDS_Shape compound_local = ((ifcopenshell::geom::open_cascade_shape*)itm)->shape();
delete itm;
gp_Trsf trsf;
@@ -506,16 +505,15 @@ void TtlWktSerializer::write(const IfcGeom::BRepElement* brep_obj) {
#endif
}
std::string TtlWktSerializer::ttl_object_id(const IfcGeom::Element* o, const char* const postfix)
std::string ttl_wkt_serializer::ttl_object_id(const ifcopenshell::geom::element* o, const char* const postfix)
{
using namespace ifcopenshell::geometry::settings;
auto oid = boost::replace_all_copy(object_id(o), "-", "_");
if (oid.find('$') == std::string::npos) {
return "base:" + oid + (postfix ? postfix : (const char* const)"");
} else {
std::string base;
if (settings_.get<BaseUri>().has()) {
base = settings_.get<BaseUri>().get();
if (settings_.get<ifcopenshell::geom::settings::BaseUri>().has()) {
base = settings_.get<ifcopenshell::geom::settings::BaseUri>().get();
} else {
base = "http://example.org/";
}
@@ -523,7 +521,6 @@ std::string TtlWktSerializer::ttl_object_id(const IfcGeom::Element* o, const cha
}
}
bool TtlWktSerializer::isTesselated() const {
using namespace ifcopenshell::geometry::settings;
return !settings_.get<WktUseSection>().get();
bool ttl_wkt_serializer::isTesselated() const {
return !settings_.get<ifcopenshell::geom::settings::WktUseSection>().get();
}
+6 -6
View File
@@ -28,21 +28,21 @@
#include "../ifcgeom/GeometrySerializer.h"
// http://people.sc.fsu.edu/~jburkardt/txt/obj_format.txt
class SERIALIZERS_API TtlWktSerializer : public WriteOnlyGeometrySerializer {
class SERIALIZERS_API ttl_wkt_serializer : public write_only_geometry_serializer {
private:
stream_or_filename filename_;
public:
TtlWktSerializer(const stream_or_filename& filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, ::logger* logger = nullptr);
virtual ~TtlWktSerializer() {}
ttl_wkt_serializer(const stream_or_filename& filename, const ifcopenshell::geom::settings& settings, ::logger* logger = nullptr);
virtual ~ttl_wkt_serializer() {}
bool ready();
void writeHeader();
void write(const IfcGeom::TriangulationElement* o);
void write(const IfcGeom::BRepElement* /*o*/);
void write(const ifcopenshell::geom::triangulation_element* o);
void write(const ifcopenshell::geom::brep_element* /*o*/);
void finalize() {}
bool isTesselated() const;
void setUnitNameAndMagnitude(const std::string& /*name*/, float /*magnitude*/) {}
void setFile(ifcopenshell::file&) {}
std::string ttl_object_id(const IfcGeom::Element* o, const char* const postfix = nullptr);
std::string ttl_object_id(const ifcopenshell::geom::element* o, const char* const postfix = nullptr);
};
#endif
+15 -15
View File
@@ -36,8 +36,8 @@
#include <math.h>
USDSerializer::USDSerializer(const std::string& out_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, ::logger* logger):
WriteOnlyGeometrySerializer(geometry_settings, settings, logger),
usd_serializer::usd_serializer(const std::string& out_filename, const ifcopenshell::geom::settings& settings, ::logger* logger):
write_only_geometry_serializer(settings, logger),
filename_(out_filename)
{
std::size_t found = filename_.find_last_of("/\\");
@@ -47,7 +47,7 @@ USDSerializer::USDSerializer(const std::string& out_filename, const ifcopenshell
if(!stage_)
throw std::runtime_error("Could not create USD stage");
if (!settings.get<ifcopenshell::geometry::settings::UseYUp>().get()) {
if (!settings.get<ifcopenshell::geom::settings::UseYUp>().get()) {
pxr::UsdGeomSetStageUpAxis(stage_, pxr::UsdGeomTokens->z);
}
@@ -60,11 +60,11 @@ USDSerializer::USDSerializer(const std::string& out_filename, const ifcopenshell
ready_ = true;
}
USDSerializer::~USDSerializer() {
usd_serializer::~usd_serializer() {
}
std::vector<pxr::UsdShadeMaterial> USDSerializer::createMaterials(const std::vector<ifcopenshell::geometry::taxonomy::style::ptr>& styles)
std::vector<pxr::UsdShadeMaterial> usd_serializer::createMaterials(const std::vector<ifcopenshell::geom::taxonomy::style::ptr>& styles)
{
if(styles.empty())
throw std::runtime_error("No styles to create materials from");
@@ -113,11 +113,11 @@ std::vector<pxr::UsdShadeMaterial> USDSerializer::createMaterials(const std::vec
return materials;
}
void USDSerializer::writeHeader() {
void usd_serializer::writeHeader() {
stage_->GetRootLayer()->SetComment("File generated by IfcOpenShell " + std::string(IFCOPENSHELL_VERSION));
}
std::string USDSerializer::object_id_unique(const IfcGeom::Element* o) {
std::string usd_serializer::object_id_unique(const ifcopenshell::geom::element* o) {
auto it = element_names_.find(o->id());
if (it != element_names_.end()) {
return it->second;
@@ -143,7 +143,7 @@ std::string USDSerializer::object_id_unique(const IfcGeom::Element* o) {
}
template <typename T>
T USDSerializer::writeNode(const IfcGeom::Element* o, const IfcGeom::Element* p) {
T usd_serializer::writeNode(const ifcopenshell::geom::element* o, const ifcopenshell::geom::element* p) {
written_.insert(o->id());
auto m = o->transformation().data()->ccomponents();
@@ -153,7 +153,7 @@ T USDSerializer::writeNode(const IfcGeom::Element* o, const IfcGeom::Element* p)
bool is_root = false;
std::string prefix = "/";
if (geometry_settings_.get<ifcopenshell::geometry::settings::UseElementHierarchy>().get() && p == nullptr && o->parents().empty()) {
if (settings_.get<ifcopenshell::geom::settings::UseElementHierarchy>().get() && p == nullptr && o->parents().empty()) {
// Emitting hierarchy
// p == nullptr means we're in the first pass serializing geometric elements
// in that case empty parents vector means it's the root
@@ -195,15 +195,15 @@ T USDSerializer::writeNode(const IfcGeom::Element* o, const IfcGeom::Element* p)
return t;
}
void USDSerializer::write(const IfcGeom::TriangulationElement* o) {
IfcGeom::Element const * previous = nullptr;
void usd_serializer::write(const ifcopenshell::geom::triangulation_element* o) {
ifcopenshell::geom::element const * previous = nullptr;
for (auto it = o->parents().begin(); it != o->parents().end(); ++it) {
parents_.push_back({ *it, previous });
previous = *it;
}
pxr::UsdGeomXform usd_mesh_container = writeNode<pxr::UsdGeomXform>(o); // writeNode<pxr::UsdGeomMesh>(o);
auto usd_mesh = pxr::UsdGeomMesh::Define(stage_, pxr::SdfPath(usd_mesh_container.GetPath().GetString() + "/" + o->context()));
const IfcGeom::Representation::Triangulation& mesh = o->geometry();
const ifcopenshell::geom::Representation::triangulation& mesh = o->geometry();
const auto verts = mesh.verts();
const auto faces = mesh.faces();
const auto material_ids = mesh.material_ids();
@@ -240,7 +240,7 @@ void USDSerializer::write(const IfcGeom::TriangulationElement* o) {
}
}
void USDSerializer::finalize() {
void usd_serializer::finalize() {
// we write the parents at the end, because some parents might actually be
// geometrical entities such as the IfcSite.
std::set<int> written;
@@ -254,7 +254,7 @@ void USDSerializer::finalize() {
stage_->Save();
}
template pxr::UsdGeomMesh USDSerializer::writeNode<pxr::UsdGeomMesh>(const IfcGeom::Element*, const IfcGeom::Element*);
template pxr::UsdGeomXform USDSerializer::writeNode<pxr::UsdGeomXform>(const IfcGeom::Element*, const IfcGeom::Element*);
template pxr::UsdGeomMesh usd_serializer::writeNode<pxr::UsdGeomMesh>(const ifcopenshell::geom::element*, const ifcopenshell::geom::element*);
template pxr::UsdGeomXform usd_serializer::writeNode<pxr::UsdGeomXform>(const ifcopenshell::geom::element*, const ifcopenshell::geom::element*);
#endif // WITH_USD
+10 -10
View File
@@ -66,7 +66,7 @@ namespace usd_utils {
}
}
class SERIALIZERS_API USDSerializer : public WriteOnlyGeometrySerializer {
class SERIALIZERS_API usd_serializer : public write_only_geometry_serializer {
private:
bool ready_ = false;
const std::string filename_;
@@ -75,28 +75,28 @@ private:
std::map<std::string, pxr::UsdShadeMaterial> materials_;
std::map<std::string, std::string> meshes_;
std::vector<pxr::UsdShadeMaterial> createMaterials(const std::vector<ifcopenshell::geometry::taxonomy::style::ptr>&);
std::vector<pxr::UsdShadeMaterial> createMaterials(const std::vector<ifcopenshell::geom::taxonomy::style::ptr>&);
template <typename T>
T writeNode(const IfcGeom::Element*, const IfcGeom::Element* = nullptr);
std::vector<std::pair<IfcGeom::Element const*, IfcGeom::Element const*>> parents_;
T writeNode(const ifcopenshell::geom::element*, const ifcopenshell::geom::element* = nullptr);
std::vector<std::pair<ifcopenshell::geom::element const*, ifcopenshell::geom::element const*>> parents_;
std::set<int> written_;
std::map<int, std::string> paths_;
std::map<int, ifcopenshell::geometry::taxonomy::matrix4::ptr> placements_;
std::map<int, ifcopenshell::geom::taxonomy::matrix4::ptr> placements_;
std::set<std::string> emitted_names_;
std::map<int, std::string> element_names_;
public:
USDSerializer(const std::string&, const ifcopenshell::geometry::Settings&, const ifcopenshell::geometry::SerializerSettings&, ::logger* logger = nullptr);
virtual ~USDSerializer();
usd_serializer(const std::string&, const ifcopenshell::geom::settings& settings, ::logger* logger = nullptr);
virtual ~usd_serializer();
bool ready() { return ready_; }
void writeHeader();
void write(const IfcGeom::TriangulationElement*);
void write(const IfcGeom::BRepElement*) {}
void write(const ifcopenshell::geom::triangulation_element*);
void write(const ifcopenshell::geom::brep_element*) {}
void finalize();
bool isTesselated() const { return true; }
void setUnitNameAndMagnitude(const std::string&, float) {}
void setFile(ifcopenshell::file&) {}
std::string object_id_unique(const IfcGeom::Element* o);
std::string object_id_unique(const ifcopenshell::geom::element* o);
};
#endif
+12 -12
View File
@@ -27,22 +27,22 @@
#include <boost/lexical_cast.hpp>
#include <iomanip>
WaveFrontOBJSerializer::WaveFrontOBJSerializer(const stream_or_filename& obj_filename, const stream_or_filename& mtl_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, ::logger* logger)
: WriteOnlyGeometrySerializer(geometry_settings, settings, logger)
wavefront_obj_serializer::wavefront_obj_serializer(const stream_or_filename& obj_filename, const stream_or_filename& mtl_filename, const ifcopenshell::geom::settings& settings, ::logger* logger)
: write_only_geometry_serializer(settings, logger)
, obj_stream(obj_filename)
, mtl_stream(mtl_filename)
, vcount_total(1)
, ncount_total(1)
{
obj_stream.stream << std::setprecision(settings.get<ifcopenshell::geometry::settings::FloatingPointDigits>().get());
mtl_stream.stream << std::setprecision(settings.get<ifcopenshell::geometry::settings::FloatingPointDigits>().get());
obj_stream.stream << std::setprecision(settings.get<ifcopenshell::geom::settings::FloatingPointDigits>().get());
mtl_stream.stream << std::setprecision(settings.get<ifcopenshell::geom::settings::FloatingPointDigits>().get());
}
bool WaveFrontOBJSerializer::ready() {
bool wavefront_obj_serializer::ready() {
return obj_stream.is_ready() && mtl_stream.is_ready();
}
void WaveFrontOBJSerializer::writeHeader() {
void wavefront_obj_serializer::writeHeader() {
obj_stream.stream << "# File generated by IfcOpenShell " << IFCOPENSHELL_VERSION << "\n";
#ifdef WIN32
const char dir_separator = '\\';
@@ -60,7 +60,7 @@ void WaveFrontOBJSerializer::writeHeader() {
mtl_stream.stream << "# File generated by IfcOpenShell " << IFCOPENSHELL_VERSION << "\n";
}
void WaveFrontOBJSerializer::writeMaterial(const ifcopenshell::geometry::taxonomy::style::ptr styleptr)
void wavefront_obj_serializer::writeMaterial(const ifcopenshell::geom::taxonomy::style::ptr styleptr)
{
auto& style = *styleptr;
std::string material_name = style.name;
@@ -86,13 +86,13 @@ void WaveFrontOBJSerializer::writeMaterial(const ifcopenshell::geometry::taxonom
}
}
void WaveFrontOBJSerializer::write(const IfcGeom::TriangulationElement* o)
void wavefront_obj_serializer::write(const ifcopenshell::geom::triangulation_element* o)
{
obj_stream.stream << "g " << object_id(o) << "\n";
obj_stream.stream << "s 1" << "\n";
const bool isyup = settings().get<ifcopenshell::geometry::settings::UseYUp>().get();
const bool isyup = settings().get<ifcopenshell::geom::settings::UseYUp>().get();
const IfcGeom::Representation::Triangulation& mesh = o->geometry();
const ifcopenshell::geom::Representation::triangulation& mesh = o->geometry();
size_t vcount = mesh.verts().size() / 3;
size_t ncount = mesh.normals().size() / 3;
@@ -131,7 +131,7 @@ void WaveFrontOBJSerializer::write(const IfcGeom::TriangulationElement* o)
const int material_id = *(material_it++);
if (material_id != previous_material_id) {
const ifcopenshell::geometry::taxonomy::style::ptr material = mesh.materials()[material_id];
const ifcopenshell::geom::taxonomy::style::ptr material = mesh.materials()[material_id];
std::string material_name = material->name;
ifcopenshell::sanitate_material_name(material_name);
obj_stream.stream << "usemtl " << material_name << "\n";
@@ -177,7 +177,7 @@ void WaveFrontOBJSerializer::write(const IfcGeom::TriangulationElement* o)
const int material_id = *(material_it++);
if (material_id != previous_material_id) {
const ifcopenshell::geometry::taxonomy::style::ptr material = mesh.materials()[material_id];
const ifcopenshell::geom::taxonomy::style::ptr material = mesh.materials()[material_id];
std::string material_name = material->name;
ifcopenshell::sanitate_material_name(material_name);
obj_stream.stream << "usemtl " << material_name << "\n";
+6 -6
View File
@@ -28,20 +28,20 @@
#include "../ifcgeom/GeometrySerializer.h"
// http://people.sc.fsu.edu/~jburkardt/txt/obj_format.txt
class SERIALIZERS_API WaveFrontOBJSerializer : public WriteOnlyGeometrySerializer {
class SERIALIZERS_API wavefront_obj_serializer : public write_only_geometry_serializer {
private:
stream_or_filename obj_stream;
stream_or_filename mtl_stream;
size_t vcount_total, ncount_total;
std::set<std::string> materials;
public:
WaveFrontOBJSerializer(const stream_or_filename& obj_filename, const stream_or_filename& mtl_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, ::logger* logger = nullptr);
virtual ~WaveFrontOBJSerializer() {}
wavefront_obj_serializer(const stream_or_filename& obj_filename, const stream_or_filename& mtl_filename, const ifcopenshell::geom::settings& settings, ::logger* logger = nullptr);
virtual ~wavefront_obj_serializer() {}
bool ready();
void writeHeader();
void writeMaterial(const ifcopenshell::geometry::taxonomy::style::ptr style);
void write(const IfcGeom::TriangulationElement* o);
void write(const IfcGeom::BRepElement* /*o*/) {}
void writeMaterial(const ifcopenshell::geom::taxonomy::style::ptr style);
void write(const ifcopenshell::geom::triangulation_element* o);
void write(const ifcopenshell::geom::brep_element* /*o*/) {}
void finalize() {}
bool isTesselated() const { return true; }
void setUnitNameAndMagnitude(const std::string& /*name*/, float /*magnitude*/) {}
+4 -4
View File
@@ -11,15 +11,15 @@
#include <boost/shared_ptr.hpp>
class XmlSerializer : public Serializer {
class xml_serializer : public serializer {
private:
boost::shared_ptr<Serializer> implementation_;
boost::shared_ptr<serializer> implementation_;
protected:
std::string xml_filename;
public:
XmlSerializer(ifcopenshell::file* file, const std::string& xml_filename, ::logger& logger = ::logger::root())
xml_serializer(ifcopenshell::file* file, const std::string& xml_filename, ::logger& logger = ::logger::root())
: xml_filename(xml_filename)
{
if (!file) {
@@ -33,7 +33,7 @@ public:
implementation_ = ifcopenshell::serializers::document_serializer_registry_instance().create("xml", context);
}
virtual ~XmlSerializer() {}
virtual ~xml_serializer() {}
bool ready() { return true; }
void writeHeader() {}
+1 -1
View File
@@ -27,7 +27,7 @@
namespace {
boost::shared_ptr<Serializer> create_serializer(const ifcopenshell::serializers::document_serializer_context& context) {
boost::shared_ptr<serializer> create_serializer(const ifcopenshell::serializers::document_serializer_context& context) {
if (context.input_filename.empty()) {
throw ifcopenshell::exception("RocksDB document serializer requires an input filename");
}
@@ -125,7 +125,7 @@ const ifcopenshell::serializers::document_serializer_info* ifcopenshell::seriali
return entry ? &entry->info_ : nullptr;
}
boost::shared_ptr<Serializer> ifcopenshell::serializers::document_serializer_registry::create(const std::string& format, const document_serializer_context& context) const {
boost::shared_ptr<serializer> ifcopenshell::serializers::document_serializer_registry::create(const std::string& format, const document_serializer_context& context) const {
const auto schema_name = !context.schema_name.empty() ? context.schema_name :
(context.file ? context.file->schema()->name() : std::string());
auto* registry = const_cast<document_serializer_registry*>(this);
+2 -2
View File
@@ -62,11 +62,11 @@ struct SERIALIZERS_API document_serializer_context {
class SERIALIZERS_API document_serializer_registry {
public:
typedef boost::function<boost::shared_ptr<Serializer>(const document_serializer_context&)> create_fn;
typedef boost::function<boost::shared_ptr<serializer>(const document_serializer_context&)> create_fn;
void bind(const document_serializer_info& info, create_fn create, const ifcopenshell::plugin::module& module = ifcopenshell::plugin::module());
const document_serializer_info* find(const std::string& format, const std::string& schema_name = std::string()) const;
boost::shared_ptr<Serializer> create(const std::string& format, const document_serializer_context& context) const;
boost::shared_ptr<serializer> create(const std::string& format, const document_serializer_context& context) const;
std::vector<document_serializer_info> serializers() const;
private:
+2 -2
View File
@@ -37,8 +37,8 @@ plugin::metadata plugin_metadata() {
return geometry_serializer_plugin_metadata("dae");
}
boost::shared_ptr<GeometrySerializer> create_serializer(const geometry_serializer_context& context) {
return boost::make_shared<ColladaSerializer>(context.output_temp_filename, context.geometry_settings, context.serializer_settings);
boost::shared_ptr<geometry_serializer> create_serializer(const geometry_serializer_context& context) {
return boost::make_shared<collada_serializer>(context.output_temp_filename, context.settings);
}
void register_plugin(geometry_serializer_registry& registry, const plugin::module& module) {
+2 -2
View File
@@ -37,8 +37,8 @@ plugin::metadata plugin_metadata() {
return geometry_serializer_plugin_metadata("glb");
}
boost::shared_ptr<GeometrySerializer> create_serializer(const geometry_serializer_context& context) {
return boost::make_shared<GltfSerializer>(context.output_temp_filename, context.geometry_settings, context.serializer_settings);
boost::shared_ptr<geometry_serializer> create_serializer(const geometry_serializer_context& context) {
return boost::make_shared<gltf_serializer>(context.output_temp_filename, context.settings);
}
void register_plugin(geometry_serializer_registry& registry, const plugin::module& module) {
+4 -4
View File
@@ -43,16 +43,16 @@ plugin::metadata plugin_metadata() {
return geometry_serializer_plugin_metadata("igs");
}
boost::shared_ptr<GeometrySerializer> create_serializer(const geometry_serializer_context& context) {
boost::shared_ptr<geometry_serializer> create_serializer(const geometry_serializer_context& context) {
#if OCC_VERSION_HEX < 0x60900
IGESControl_Controller::Init();
#endif
return boost::make_shared<IgesSerializer>(context.output_temp_filename, context.geometry_settings, context.serializer_settings);
return boost::make_shared<iges_serializer>(context.output_temp_filename, context.settings);
}
void configure_serializer(geometry_serializer_context& context) {
context.geometry_settings.get<ifcopenshell::geometry::settings::UseWorldCoords>().value = true;
context.geometry_settings.get<ifcopenshell::geometry::settings::IteratorOutput>().value = ifcopenshell::geometry::settings::NATIVE;
context.settings.get<ifcopenshell::geom::settings::UseWorldCoords>().value = true;
context.settings.get<ifcopenshell::geom::settings::IteratorOutput>().value = ifcopenshell::geom::settings::NATIVE;
}
void register_plugin(geometry_serializer_registry& registry, const plugin::module& module) {
+5 -5
View File
@@ -49,7 +49,7 @@ plugin::metadata plugin_metadata() {
return geometry_serializer_plugin_metadata("obj");
}
boost::shared_ptr<GeometrySerializer> create_serializer(const geometry_serializer_context& context) {
boost::shared_ptr<geometry_serializer> create_serializer(const geometry_serializer_context& context) {
if (context.output_temp_stream || context.output_stream) {
stream_or_filename obj_filename = context.output_temp_stream
? *context.output_temp_stream
@@ -57,14 +57,14 @@ boost::shared_ptr<GeometrySerializer> create_serializer(const geometry_serialize
stream_or_filename mtl_filename = context.output_stream
? *context.output_stream
: stream_or_filename(obj_mtl_filename(context.output_filename));
return boost::make_shared<WaveFrontOBJSerializer>(
obj_filename, mtl_filename, context.geometry_settings, context.serializer_settings);
return boost::make_shared<wavefront_obj_serializer>(
obj_filename, mtl_filename, context.settings);
}
return boost::make_shared<WaveFrontOBJSerializer>(context.output_temp_filename, obj_mtl_filename(context.output_filename), context.geometry_settings, context.serializer_settings);
return boost::make_shared<wavefront_obj_serializer>(context.output_temp_filename, obj_mtl_filename(context.output_filename), context.settings);
}
void configure_serializer(geometry_serializer_context& context) {
context.geometry_settings.get<ifcopenshell::geometry::settings::UseWorldCoords>().value = true;
context.settings.get<ifcopenshell::geom::settings::UseWorldCoords>().value = true;
}
void register_plugin(geometry_serializer_registry& registry, const plugin::module& module) {
@@ -130,7 +130,7 @@ void ifcopenshell::serializers::geometry_serializer_registry::configure(const st
}
}
boost::shared_ptr<GeometrySerializer> ifcopenshell::serializers::geometry_serializer_registry::create(const std::string& extension, const geometry_serializer_context& context) const {
boost::shared_ptr<geometry_serializer> ifcopenshell::serializers::geometry_serializer_registry::create(const std::string& extension, const geometry_serializer_context& context) const {
const auto key = geometry_serializer_key(extension);
if (entries_.find(key) == entries_.end()) {
load_geometry_serializer_plugin(const_cast<geometry_serializer_registry&>(*this), extension);
+3 -4
View File
@@ -52,22 +52,21 @@ struct SERIALIZERS_API geometry_serializer_info {
struct SERIALIZERS_API geometry_serializer_context {
std::string output_filename;
std::string output_temp_filename;
ifcopenshell::geometry::Settings& geometry_settings;
const ifcopenshell::geometry::SerializerSettings& serializer_settings;
ifcopenshell::geom::settings& settings;
const stream_or_filename* output_stream = nullptr;
const stream_or_filename* output_temp_stream = nullptr;
};
class SERIALIZERS_API geometry_serializer_registry {
public:
typedef boost::function<boost::shared_ptr<GeometrySerializer>(const geometry_serializer_context&)> create_fn;
typedef boost::function<boost::shared_ptr<geometry_serializer>(const geometry_serializer_context&)> create_fn;
typedef boost::function<void(geometry_serializer_context&)> configure_fn;
void bind(const geometry_serializer_info& info, create_fn create, configure_fn configure = configure_fn(), const ifcopenshell::plugin::module& module = ifcopenshell::plugin::module());
bool has(const std::string& extension) const;
const geometry_serializer_info* find(const std::string& extension) const;
void configure(const std::string& extension, geometry_serializer_context& context) const;
boost::shared_ptr<GeometrySerializer> create(const std::string& extension, const geometry_serializer_context& context) const;
boost::shared_ptr<geometry_serializer> create(const std::string& extension, const geometry_serializer_context& context) const;
std::vector<geometry_serializer_info> serializers() const;
private:
+4 -4
View File
@@ -37,13 +37,13 @@ plugin::metadata plugin_metadata() {
return geometry_serializer_plugin_metadata("stp");
}
boost::shared_ptr<GeometrySerializer> create_serializer(const geometry_serializer_context& context) {
return boost::make_shared<StepSerializer>(context.output_temp_filename, context.geometry_settings, context.serializer_settings);
boost::shared_ptr<geometry_serializer> create_serializer(const geometry_serializer_context& context) {
return boost::make_shared<step_serializer>(context.output_temp_filename, context.settings);
}
void configure_serializer(geometry_serializer_context& context) {
context.geometry_settings.get<ifcopenshell::geometry::settings::UseWorldCoords>().value = true;
context.geometry_settings.get<ifcopenshell::geometry::settings::IteratorOutput>().value = ifcopenshell::geometry::settings::NATIVE;
context.settings.get<ifcopenshell::geom::settings::UseWorldCoords>().value = true;
context.settings.get<ifcopenshell::geom::settings::IteratorOutput>().value = ifcopenshell::geom::settings::NATIVE;
}
void register_plugin(geometry_serializer_registry& registry, const plugin::module& module) {
+6 -6
View File
@@ -37,17 +37,17 @@ plugin::metadata plugin_metadata() {
return geometry_serializer_plugin_metadata("svg");
}
boost::shared_ptr<GeometrySerializer> create_serializer(const geometry_serializer_context& context) {
boost::shared_ptr<geometry_serializer> create_serializer(const geometry_serializer_context& context) {
if (context.output_temp_stream) {
return boost::make_shared<SvgSerializer>(
*context.output_temp_stream, context.geometry_settings, context.serializer_settings);
return boost::make_shared<svg_serializer>(
*context.output_temp_stream, context.settings);
}
return boost::make_shared<SvgSerializer>(context.output_temp_filename, context.geometry_settings, context.serializer_settings);
return boost::make_shared<svg_serializer>(context.output_temp_filename, context.settings);
}
void configure_serializer(geometry_serializer_context& context) {
context.geometry_settings.get<ifcopenshell::geometry::settings::UseElementHierarchy>().value = true;
context.geometry_settings.get<ifcopenshell::geometry::settings::IteratorOutput>().value = ifcopenshell::geometry::settings::NATIVE;
context.settings.get<ifcopenshell::geom::settings::UseElementHierarchy>().value = true;
context.settings.get<ifcopenshell::geom::settings::IteratorOutput>().value = ifcopenshell::geom::settings::NATIVE;
}
void register_plugin(geometry_serializer_registry& registry, const plugin::module& module) {
+7 -7
View File
@@ -35,18 +35,18 @@ plugin::metadata plugin_metadata() {
return geometry_serializer_plugin_metadata("ttl");
}
boost::shared_ptr<GeometrySerializer> create_serializer(const geometry_serializer_context& context) {
boost::shared_ptr<geometry_serializer> create_serializer(const geometry_serializer_context& context) {
if (context.output_temp_stream) {
return boost::make_shared<TtlWktSerializer>(
*context.output_temp_stream, context.geometry_settings, context.serializer_settings);
return boost::make_shared<ttl_wkt_serializer>(
*context.output_temp_stream, context.settings);
}
return boost::make_shared<TtlWktSerializer>(context.output_temp_filename, context.geometry_settings, context.serializer_settings);
return boost::make_shared<ttl_wkt_serializer>(context.output_temp_filename, context.settings);
}
void configure_serializer(geometry_serializer_context& context) {
context.geometry_settings.get<ifcopenshell::geometry::settings::TriangulationType>().value = ifcopenshell::geometry::settings::POLYHEDRON_WITH_HOLES;
if (context.serializer_settings.get<ifcopenshell::geometry::settings::WktUseSection>().get()) {
context.geometry_settings.get<ifcopenshell::geometry::settings::IteratorOutput>().value = ifcopenshell::geometry::settings::NATIVE;
context.settings.get<ifcopenshell::geom::settings::TriangulationType>().value = ifcopenshell::geom::settings::POLYHEDRON_WITH_HOLES;
if (context.settings.get<ifcopenshell::geom::settings::WktUseSection>().get()) {
context.settings.get<ifcopenshell::geom::settings::IteratorOutput>().value = ifcopenshell::geom::settings::NATIVE;
}
}
+2 -2
View File
@@ -37,8 +37,8 @@ plugin::metadata plugin_metadata() {
return geometry_serializer_plugin_metadata("usd");
}
boost::shared_ptr<GeometrySerializer> create_serializer(const geometry_serializer_context& context) {
return boost::make_shared<USDSerializer>(context.output_filename, context.geometry_settings, context.serializer_settings);
boost::shared_ptr<geometry_serializer> create_serializer(const geometry_serializer_context& context) {
return boost::make_shared<usd_serializer>(context.output_filename, context.settings);
}
void register_plugin(geometry_serializer_registry& registry, const plugin::module& module) {
@@ -40,7 +40,7 @@ class format_value_visitor : public boost::static_visitor<std::string> {
template <typename T>
json operator()(const T& t) const {
if constexpr (std::is_same_v<std::decay_t<T>, derived> || std::is_same_v<std::decay_t<T>, boost::dynamic_bitset<>> || std::is_same_v<std::decay_t<T>, express::Base> || std::is_same_v<std::decay_t<T>, std::vector<int>> || std::is_same_v<std::decay_t<T>, std::vector<double>> || std::is_same_v<std::decay_t<T>, std::vector<std::string>> || std::is_same_v<std::decay_t<T>, std::vector<boost::dynamic_bitset<>>> || std::is_same_v<std::decay_t<T>, std::vector<express::Base>> || std::is_same_v<std::decay_t<T>, std::vector<std::vector<express::Base>>> || std::is_same_v<std::decay_t<T>, std::vector<std::vector<int>>> || std::is_same_v<std::decay_t<T>, std::vector<std::vector<double>>> || std::is_same_v<std::decay_t<T>, empty_aggregate_t> || std::is_same_v<std::decay_t<T>, empty_aggregate_of_aggregate_t> || std::is_same_v<std::decay_t<T>, blank>) {
if constexpr (std::is_same_v<std::decay_t<T>, derived> || std::is_same_v<std::decay_t<T>, boost::dynamic_bitset<>> || std::is_same_v<std::decay_t<T>, express::base> || std::is_same_v<std::decay_t<T>, std::vector<int>> || std::is_same_v<std::decay_t<T>, std::vector<double>> || std::is_same_v<std::decay_t<T>, std::vector<std::string>> || std::is_same_v<std::decay_t<T>, std::vector<boost::dynamic_bitset<>>> || std::is_same_v<std::decay_t<T>, std::vector<express::base>> || std::is_same_v<std::decay_t<T>, std::vector<std::vector<express::base>>> || std::is_same_v<std::decay_t<T>, std::vector<std::vector<int>>> || std::is_same_v<std::decay_t<T>, std::vector<std::vector<double>>> || std::is_same_v<std::decay_t<T>, empty_aggregate_t> || std::is_same_v<std::decay_t<T>, empty_aggregate_of_aggregate_t> || std::is_same_v<std::decay_t<T>, blank>) {
return "";
} else if constexpr (std::is_same_v<std::decay_t<T>, boost::logic::tribool>) {
// @todo handle indeterminate
@@ -75,11 +75,11 @@ auto get_related(::logger& log, T t, F f, G g) {
for (auto& u : li) {
try {
auto vs = (u.template as<U>().*g)();
if constexpr (std::is_base_of_v<express::Base, decltype(vs)>) {
if constexpr (std::is_base_of_v<express::base, decltype(vs)>) {
if (auto vv = vs.template as<V>()) {
acc.push_back(vv);
}
} else if constexpr (std::is_base_of_v<express::Select, decltype(vs)>) {
} else if constexpr (std::is_base_of_v<express::select, decltype(vs)>) {
if (auto vv = vs.concrete().template as<V>()) {
acc.push_back(vv);
}
@@ -97,7 +97,7 @@ auto get_related(::logger& log, T t, F f, G g) {
return acc;
}
void format_entity_instance(::logger& log, express::Base instance, json& tree, express::Base parent = express::Base()) {
void format_entity_instance(::logger& log, express::base instance, json& tree, express::base parent = express::base()) {
/*
{
"id" : string, // Element GUID (IFC GloballyUniqueId)
@@ -121,7 +121,7 @@ void format_entity_instance(::logger& log, express::Base instance, json& tree, e
auto write_to_json = [&](const std::string& keyJson, const std::string& keyIfc) {
attribute_value val;
try {
val = instance.as<express::Entity>().get(keyIfc);
val = instance.as<express::entity>().get(keyIfc);
} catch (const ifcopenshell::exception&) {
// simply laziness like no attribute Tag on IfcProject
return;
@@ -168,7 +168,7 @@ void format_entity_instance(::logger& log, express::Base instance, json& tree, e
// A function to be called recursively. Template specialization is used
// to descend into decomposition, containment and property relationships.
template <typename A>
void descend(::logger& log, A instance, json& tree, express::Base parent = express::Base()) {
void descend(::logger& log, A instance, json& tree, express::base parent = express::base()) {
if (instance.declaration().is(IfcSchema::IfcObjectDefinition::Class())) {
descend(log, instance.template as<IfcSchema::IfcObjectDefinition>(), tree, parent);
} else {
@@ -181,7 +181,7 @@ void descend(::logger& log, A instance, json& tree, express::Base parent = expre
// Descends into the tree by recursing into IfcRelContainedInSpatialStructure,
// IfcRelDecomposes, IfcRelDefinesByType, IfcRelDefinesByProperties relations.
template <>
void descend(::logger& log, IfcSchema::IfcObjectDefinition product, json& tree, express::Base parent) {
void descend(::logger& log, IfcSchema::IfcObjectDefinition product, json& tree, express::base parent) {
if (product.declaration().is(IfcSchema::IfcElement::Class())) {
auto voids = product.as<IfcSchema::IfcElement>().FillsVoids();
if (voids.size() == 1 && voids.front().RelatingOpeningElement() != parent) {
@@ -262,7 +262,7 @@ IfcSchema::IfcUnit get_unit_from_prop(IfcSchema::IfcProperty& prop) {
} // namespace
void POSTFIX_SCHEMA(JsonSerializer)::finalize() {
void POSTFIX_SCHEMA(json_serializer)::finalize() {
json output;
auto projects = file->instances_by_type<IfcSchema::IfcProject>();
@@ -296,7 +296,7 @@ void POSTFIX_SCHEMA(JsonSerializer)::finalize() {
output["groups"] = json::array();
// Maps for deduplication of properties and quantities
std::map<express::Entity, size_t> property_to_index;
std::map<express::entity, size_t> property_to_index;
std::unordered_map<json, std::size_t> json_to_index;
// Obtain sequence of units because properties, quantities reference them by index.
@@ -322,7 +322,7 @@ void POSTFIX_SCHEMA(JsonSerializer)::finalize() {
}
}
auto format_property = [&](const express::Entity& prop_) {
auto format_property = [&](const express::entity& prop_) {
json jprop;
/*
{
@@ -349,7 +349,7 @@ void POSTFIX_SCHEMA(JsonSerializer)::finalize() {
return jprop;
};
auto format_quantity = [&](const express::Entity& qto_) {
auto format_quantity = [&](const express::entity& qto_) {
json jprop;
/*
{
@@ -376,7 +376,7 @@ void POSTFIX_SCHEMA(JsonSerializer)::finalize() {
};
auto deduplicate = [&](auto base_formatter) {
return [&, base_formatter](const express::Entity& prop) mutable -> std::size_t {
return [&, base_formatter](const express::entity& prop) mutable -> std::size_t {
if (auto it = property_to_index.find(prop); it != property_to_index.end()) {
return it->second;
}
@@ -32,17 +32,17 @@
#define INCLUDE_PARENT_PARENT_DIR(x) STRINGIFY(../../ifcparse/schemas/x-definitions.h)
#include INCLUDE_PARENT_PARENT_DIR(IfcSchema)
class POSTFIX_SCHEMA(JsonSerializer) : public JsonSerializer {
class POSTFIX_SCHEMA(json_serializer) : public json_serializer {
private:
ifcopenshell::file* file;
// @todo
ifcopenshell::geometry::Settings settings_;
ifcopenshell::geometry::abstract_mapping* mapping_;
ifcopenshell::geom::settings settings_;
ifcopenshell::geom::abstract_mapping* mapping_;
public:
POSTFIX_SCHEMA(JsonSerializer)(ifcopenshell::file* file, const std::string& json_filename, JsonSerializer::Dialect dialect, ::logger& logger = ::logger::root())
: JsonSerializer(0, "", dialect), mapping_(ifcopenshell::geometry::impl::mapping_implementations().construct(file, settings_, logger))
POSTFIX_SCHEMA(json_serializer)(ifcopenshell::file* file, const std::string& json_filename, json_serializer::Dialect dialect, ::logger& logger = ::logger::root())
: json_serializer(0, "", dialect), mapping_(ifcopenshell::geom::impl::mapping_implementations().construct(file, settings_, logger))
{
this->file = file;
this->json_filename = json_filename;
@@ -34,12 +34,12 @@ using boost::property_tree::ptree;
namespace {
// TODO: Make this a member of XmlSerializer?
// TODO: Make this a member of xml_serializer?
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.
std::optional<std::string> format_attribute(ifcopenshell::geometry::abstract_mapping* mapping, attribute_value argument, ifcopenshell::argument_type argument_type, const std::string& argument_name) {
std::optional<std::string> format_attribute(ifcopenshell::geom::abstract_mapping* mapping, attribute_value argument, ifcopenshell::argument_type argument_type, const std::string& argument_name) {
std::optional<std::string> value;
// Hard-code lat-lon as it represents an array
@@ -86,9 +86,9 @@ std::optional<std::string> format_attribute(ifcopenshell::geometry::abstract_map
value = stream.str();
break; }
case ifcopenshell::Argument_ENTITY_INSTANCE: {
express::Base e = argument;
express::base e = argument;
if (e.declaration().as_entity() == nullptr) {
auto f = e.as<express::DeclaredType>();
auto f = e.as<express::declared_type>();
value = format_attribute(mapping, f.get_attribute_value(0), f.get_attribute_value(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.
@@ -108,7 +108,7 @@ std::optional<std::string> format_attribute(ifcopenshell::geometry::abstract_map
value = unit_name;
} else if (auto placement = e.as<IfcSchema::IfcLocalPlacement>()) {
auto item = mapping->map(e);
auto matrix = ifcopenshell::geometry::taxonomy::cast< ifcopenshell::geometry::taxonomy::matrix4>(item);
auto matrix = ifcopenshell::geom::taxonomy::cast< ifcopenshell::geom::taxonomy::matrix4>(item);
std::stringstream stream;
for (int i = 0; i < 4; ++i) {
@@ -131,7 +131,7 @@ std::optional<std::string> format_attribute(ifcopenshell::geometry::abstract_map
}
// Appends to a node with possibly existing attributes
ptree* format_entity_instance(::logger& log, ifcopenshell::geometry::abstract_mapping* mapping, const express::Base& instance, ptree& child, ptree& tree, bool as_link = false) {
ptree* format_entity_instance(::logger& log, ifcopenshell::geom::abstract_mapping* mapping, const express::base& instance, ptree& child, ptree& tree, bool as_link = false) {
const unsigned n = instance.declaration().as_entity()->attribute_count();
for (unsigned i = 0; i < n; ++i) {
try {
@@ -176,19 +176,19 @@ ptree* format_entity_instance(::logger& log, ifcopenshell::geometry::abstract_ma
// 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(::logger& log, ifcopenshell::geometry::abstract_mapping* mapping, const express::Base& instance, ptree& tree, bool as_link = false) {
ptree* format_entity_instance(::logger& log, ifcopenshell::geom::abstract_mapping* mapping, const express::base& instance, ptree& tree, bool as_link = false) {
ptree child;
return format_entity_instance(log, mapping, instance, child, tree, as_link);
}
std::string qualify_unrooted_instance(const express::Base& inst) {
std::string qualify_unrooted_instance(const express::base& inst) {
return inst.declaration().name() + "_" + std::to_string(inst.id());
}
// A function to be called recursively. Template specialization is used
// to descend into decomposition, containment and property relationships.
template <typename A>
ptree* descend(::logger& log, ifcopenshell::geometry::abstract_mapping* mapping, A instance, ptree& tree, express::Base parent = express::Base()) {
ptree* descend(::logger& log, ifcopenshell::geom::abstract_mapping* mapping, A instance, ptree& tree, express::base parent = express::base()) {
if (instance.declaration().is(IfcSchema::IfcObjectDefinition::Class())) {
return descend(log, mapping, instance.template as<IfcSchema::IfcObjectDefinition>(), tree, parent);
} else {
@@ -205,11 +205,11 @@ auto get_related(::logger& log, T t, F f, G g) {
for (auto& u : li) {
try {
auto vs = (u.template as<U>().*g)();
if constexpr (std::is_base_of_v<express::Base, decltype(vs)>) {
if constexpr (std::is_base_of_v<express::base, decltype(vs)>) {
if (auto vv = vs.template as<V>()) {
acc.push_back(vv);
}
} else if constexpr (std::is_base_of_v<express::Select, decltype(vs)>) {
} else if constexpr (std::is_base_of_v<express::select, decltype(vs)>) {
if (auto vv = vs.concrete().template as<V>()) {
acc.push_back(vv);
}
@@ -230,7 +230,7 @@ auto get_related(::logger& log, T t, F f, G g) {
// Descends into the tree by recursing into IfcRelContainedInSpatialStructure,
// IfcRelDecomposes, IfcRelDefinesByType, IfcRelDefinesByProperties relations.
template <>
ptree* descend(::logger& log, ifcopenshell::geometry::abstract_mapping* mapping, IfcSchema::IfcObjectDefinition product, ptree& tree, express::Base parent) {
ptree* descend(::logger& log, ifcopenshell::geom::abstract_mapping* mapping, IfcSchema::IfcObjectDefinition product, ptree& tree, express::base parent) {
if (product.declaration().is(IfcSchema::IfcElement::Class())) {
auto voids = product.as<IfcSchema::IfcElement>().FillsVoids();
if (voids.size() == 1 && voids.front().RelatingOpeningElement() != parent) {
@@ -365,7 +365,7 @@ ptree* descend(::logger& log, ifcopenshell::geometry::abstract_mapping* mapping,
}
// Format IfcProperty instances and insert into the DOM. IfcComplexProperties are flattened out.
void format_properties(::logger& log, ifcopenshell::geometry::abstract_mapping* mapping, const std::vector<IfcSchema::IfcProperty>& properties, ptree& node) {
void format_properties(::logger& log, ifcopenshell::geom::abstract_mapping* mapping, const std::vector<IfcSchema::IfcProperty>& properties, ptree& node) {
for (auto& p : properties) {
if (auto complex = p.as<IfcSchema::IfcComplexProperty>()) {
format_properties(log, mapping, complex.HasProperties(), node);
@@ -375,7 +375,7 @@ void format_properties(::logger& log, ifcopenshell::geometry::abstract_mapping*
}
}
void writeGroupToNode(::logger& log, ifcopenshell::geometry::abstract_mapping* mapping, IfcSchema::IfcGroup group, ptree& node, std::set<std::string> notRootGroups) {
void writeGroupToNode(::logger& log, ifcopenshell::geom::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.
@@ -407,7 +407,7 @@ void writeGroupToNode(::logger& log, ifcopenshell::geometry::abstract_mapping* m
}
// Format IfcElementQuantity instances and insert into the DOM.
void format_quantities(::logger& log, ifcopenshell::geometry::abstract_mapping* mapping, const std::vector<IfcSchema::IfcPhysicalQuantity>& quantities, ptree& node) {
void format_quantities(::logger& log, ifcopenshell::geom::abstract_mapping* mapping, const std::vector<IfcSchema::IfcPhysicalQuantity>& quantities, ptree& node) {
for (auto& p : quantities) {
ptree* node2 = format_entity_instance(log, mapping, p, node);
if (node2 && p.declaration().is(IfcSchema::IfcPhysicalComplexQuantity::Class())) {
@@ -417,7 +417,7 @@ void format_quantities(::logger& log, ifcopenshell::geometry::abstract_mapping*
}
// Format IfcTask instances and insert into the DOM.
void format_tasks(::logger& log, ifcopenshell::geometry::abstract_mapping* mapping, IfcSchema::IfcTask task, ptree& node) {
void format_tasks(::logger& log, ifcopenshell::geom::abstract_mapping* mapping, IfcSchema::IfcTask task, ptree& node) {
ptree* ntask = format_entity_instance(log, mapping, task, node);
if (ntask) {
@@ -526,7 +526,7 @@ void format_tasks(::logger& log, ifcopenshell::geometry::abstract_mapping* mappi
} // ~unnamed namespace
void POSTFIX_SCHEMA(XmlSerializer)::finalize() {
void POSTFIX_SCHEMA(xml_serializer)::finalize() {
POSTFIX_SCHEMA(argument_name_map).insert(std::make_pair("GlobalId", "id"));
auto& log = logger();
@@ -766,7 +766,7 @@ void POSTFIX_SCHEMA(XmlSerializer)::finalize() {
}
auto materal_associations = file->instances_by_type<IfcSchema::IfcRelAssociatesMaterial>();
std::set<express::Base> emitted_materials;
std::set<express::base> emitted_materials;
for (auto& rel : materal_associations) {
IfcSchema::IfcMaterialSelect mat = rel.RelatingMaterial();
if (emitted_materials.find(mat) == emitted_materials.end()) {
@@ -30,18 +30,18 @@
#define INCLUDE_PARENT_PARENT_DIR(x) STRINGIFY(../../ifcparse/schemas/x-definitions.h)
#include INCLUDE_PARENT_PARENT_DIR(IfcSchema)
class POSTFIX_SCHEMA(XmlSerializer) : public XmlSerializer {
class POSTFIX_SCHEMA(xml_serializer) : public xml_serializer {
private:
ifcopenshell::file* file;
// @todo
ifcopenshell::geometry::Settings settings_;
ifcopenshell::geometry::abstract_mapping* mapping_;
ifcopenshell::geom::settings settings_;
ifcopenshell::geom::abstract_mapping* mapping_;
public:
POSTFIX_SCHEMA(XmlSerializer)(ifcopenshell::file* file, const std::string& xml_filename, ::logger& logger = ::logger::root())
: XmlSerializer(0, "")
, mapping_(ifcopenshell::geometry::impl::mapping_implementations().construct(file, settings_, logger))
POSTFIX_SCHEMA(xml_serializer)(ifcopenshell::file* file, const std::string& xml_filename, ::logger& logger = ::logger::root())
: xml_serializer(0, "")
, mapping_(ifcopenshell::geom::impl::mapping_implementations().construct(file, settings_, logger))
{
this->file = file;
this->xml_filename = xml_filename;
@@ -29,11 +29,11 @@
namespace {
boost::shared_ptr<Serializer> create_serializer(const ifcopenshell::serializers::document_serializer_context& context) {
return boost::make_shared<POSTFIX_SCHEMA(JsonSerializer)>(
boost::shared_ptr<serializer> create_serializer(const ifcopenshell::serializers::document_serializer_context& context) {
return boost::make_shared<POSTFIX_SCHEMA(json_serializer)>(
context.file,
context.output_filename,
static_cast<JsonSerializer::Dialect>(context.dialect));
static_cast<json_serializer::Dialect>(context.dialect));
}
}
@@ -27,8 +27,8 @@
namespace {
boost::shared_ptr<Serializer> create_serializer(const ifcopenshell::serializers::document_serializer_context& context) {
return boost::make_shared<POSTFIX_SCHEMA(XmlSerializer)>(context.file, context.output_filename);
boost::shared_ptr<serializer> create_serializer(const ifcopenshell::serializers::document_serializer_context& context) {
return boost::make_shared<POSTFIX_SCHEMA(xml_serializer)>(context.file, context.output_filename);
}
}