Merge remote-tracking branch 'origin/v0.8.0' into ifcviewer-wgpu

This commit is contained in:
Thomas Krijnen
2026-07-09 13:21:39 +02:00
373 changed files with 22411 additions and 4242 deletions
+1
View File
@@ -99,6 +99,7 @@ install(FILES ${SERIALIZERS_H_FILES}
install(FILES ${SERIALIZERS_S_H_FILES}
DESTINATION ${INCLUDEDIR}/serializers/schema_dependent
)
install(TARGETS Serializers EXPORT ${IFCOPENSHELL_EXPORT_TARGETS})
set(document_serializer_libraries ${document_serializer_libraries} PARENT_SCOPE)
set(geometry_serializer_libraries ${geometry_serializer_libraries} PARENT_SCOPE)
+2 -2
View File
@@ -219,8 +219,8 @@ private:
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)
: WriteOnlyGeometrySerializer(geometry_settings, settings)
ColladaSerializer(const std::string& dae_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, Logger& logger = Logger::Root())
: WriteOnlyGeometrySerializer(geometry_settings, settings, logger)
, exporter("IfcOpenShell", dae_filename, this, settings.get<ifcopenshell::geometry::settings::FloatingPointDigits>().get() >= 15)
{
exporter.serializer = this;
+18 -11
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)
: WriteOnlyGeometrySerializer(geometry_settings, settings)
GltfSerializer::GltfSerializer(const std::string& filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, Logger& logger)
: WriteOnlyGeometrySerializer(geometry_settings, settings, logger)
, filename_(filename)
, tmp_filename1_(filename + ".indices.tmp")
, tmp_filename2_(filename + ".vertices.tmp")
@@ -108,9 +108,13 @@ int GltfSerializer::writeMaterial(const ifcopenshell::geometry::taxonomy::style:
base[3] = 1. - style->transparency;
}
if (style->has_specularity())
json_["materials"].push_back({ {"name", style->name}, {"doubleSided", true}, {"pbrMetallicRoughness", {{"baseColorFactor", base}, {"metallicFactor", 0}, {"roughnessFactor", 1.0 / style->specularity}}}});
else
if (style->has_specularity()) {
// glTF requires roughnessFactor in [0, 1]. A specular exponent of 0
// previously produced 1/0 = inf, which nlohmann::json serialises as
// null and makes the file invalid; exponents below 1 exceeded 1. #8073
const double roughness = style->specularity > 1.0 ? 1.0 / style->specularity : 1.0;
json_["materials"].push_back({ {"name", style->name}, {"doubleSided", true}, {"pbrMetallicRoughness", {{"baseColorFactor", base}, {"metallicFactor", 0}, {"roughnessFactor", roughness}}}});
} else
json_["materials"].push_back({ {"name", style->name}, {"doubleSided", true}, {"pbrMetallicRoughness", {{"baseColorFactor", base}, {"metallicFactor", 0}}}});
if (style->transparency == style->transparency && style->transparency > 1.e-9) {
@@ -518,8 +522,11 @@ namespace {
result[2] = v1[0] * v2[1] - v1[1] * v2[0];
}
void proj_log(void *, int, const char* c) {
logger::error("PROJ: " + std::string(c));
void proj_log(void* data, int, const char* c) {
auto logger = static_cast<Logger*>(data);
if (logger) {
logger->Error("SER", 1, "PROJ: " + std::string(c));
}
}
}
@@ -626,7 +633,7 @@ void GltfSerializer::setFile(ifcopenshell::file* f) {
PJ_COORD wgs84_point;
auto C = proj_context_create();
proj_log_func(C, nullptr, proj_log);
proj_log_func(C, &logger_, proj_log);
// @todo a bit ugly we assume a proj.db in current working directory.
// a very simplistic but at least portable solution.
@@ -648,7 +655,7 @@ void GltfSerializer::setFile(ifcopenshell::file* f) {
NULL);
if (!P) {
logger::error("Failed to create PROJ transformation object");
logger_.Error("SER", 2, "Failed to create PROJ transformation object");
return;
}
@@ -660,7 +667,7 @@ void GltfSerializer::setFile(ifcopenshell::file* f) {
wgs84_point = proj_trans(P, PJ_FWD, a);
logger::notice("Calculated latitude: " + std::to_string(wgs84_point.lp.lam) + " longitude: " + std::to_string(wgs84_point.lp.phi));
logger_.Notice("SER", 3, "Calculated latitude: " + std::to_string(wgs84_point.lp.lam) + " longitude: " + std::to_string(wgs84_point.lp.phi));
}
std::swap(wgs84_point.lp.phi, wgs84_point.lp.lam);
@@ -685,7 +692,7 @@ void GltfSerializer::setFile(ifcopenshell::file* f) {
PJ *ellipsoid_crs = proj_create(C, ellipsoid_def);
if (!ellipsoid_crs) {
logger::error("Failed to create ellipsoid CRS");
logger_.Error("SER", 4, "Failed to create ellipsoid CRS");
return;
}
+1 -1
View File
@@ -43,7 +43,7 @@ private:
int writeMaterial(const ifcopenshell::geometry::taxonomy::style::ptr style);
public:
GltfSerializer(const std::string& filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings);
GltfSerializer(const std::string& filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, Logger& logger = Logger::Root());
virtual ~GltfSerializer();
bool ready();
void writeHeader();
+3 -3
View File
@@ -40,8 +40,8 @@ private:
public:
/// @note IGESControl_Controller::Init() must be called prior to instantiating IgesSerializer.
/// 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)
: OpenCascadeBasedSerializer(out_filename, geometry_settings, settings)
IgesSerializer(const std::string& out_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, Logger& logger = Logger::Root())
: OpenCascadeBasedSerializer(out_filename, geometry_settings, settings, logger)
{}
virtual ~IgesSerializer() {}
void writeShape(const std::string&, const TopoDS_Shape& shape) {
@@ -54,7 +54,7 @@ public:
const char* symbol = getSymbolForUnitMagnitude(magnitude);
if (symbol) {
#ifdef HAVE_CONFIG_H
logger::warning("Setting IGES units not supported on OCE");
logger_.Warning("SER", 5, "Setting IGES units not supported on OCE");
#else
Interface_Static::SetCVal("xstep.cascade.unit", symbol);
Interface_Static::SetCVal("write.iges.unit", symbol);
+1 -1
View File
@@ -24,7 +24,7 @@ class JsonSerializer : public Serializer {
Dialect dialect_;
public:
JsonSerializer(ifcopenshell::file* file, const std::string& json_filename, Dialect dialect = Dialect::JSON_DIALECT_CREOOX)
JsonSerializer(ifcopenshell::file* file, const std::string& json_filename, Dialect dialect = Dialect::JSON_DIALECT_CREOOX, Logger& logger = Logger::Root())
: json_filename(json_filename)
, dialect_(dialect)
{
+2 -2
View File
@@ -36,8 +36,8 @@ 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)
: WriteOnlyGeometrySerializer(geometry_settings, settings)
explicit OpenCascadeBasedSerializer(const std::string& out_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, Logger& logger = Logger::Root())
: WriteOnlyGeometrySerializer(geometry_settings, settings, logger)
, out_filename(out_filename)
{}
virtual ~OpenCascadeBasedSerializer() {}
+1 -1
View File
@@ -9,7 +9,7 @@
#include "../ifcparse/logger.h"
RocksDbSerializer::RocksDbSerializer(const std::string& input_filename, const std::string& rocksdb_filename, const std::vector<std::string>& skip_supertypes)
RocksDbSerializer::RocksDbSerializer(const std::string& input_filename, const std::string& rocksdb_filename, const std::vector<std::string>& skip_supertypes, Logger& logger)
: input_filename_(input_filename)
, rocksdb_filename_(rocksdb_filename)
, skip_supertypes_(skip_supertypes)
+1 -1
View File
@@ -16,7 +16,7 @@ private:
void write_streaming_();
public:
RocksDbSerializer(const std::string& input_filename, const std::string& rocksdb_filename, const std::vector<std::string>& skip_supertypes = {});
RocksDbSerializer(const std::string& input_filename, const std::string& rocksdb_filename, const std::vector<std::string>& skip_supertypes = {}, Logger& logger = Logger::Root());
virtual ~RocksDbSerializer() {}
+2 -2
View File
@@ -34,8 +34,8 @@ class StepSerializer : public OpenCascadeBasedSerializer
private:
STEPControl_Writer writer;
public:
explicit StepSerializer(const std::string& out_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& serializer_settings)
: OpenCascadeBasedSerializer(out_filename, geometry_settings, serializer_settings)
explicit StepSerializer(const std::string& out_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& serializer_settings, Logger& logger = Logger::Root())
: OpenCascadeBasedSerializer(out_filename, geometry_settings, serializer_settings, logger)
{}
virtual ~StepSerializer() {}
void writeShape(const std::string& name, const TopoDS_Shape& shape) {
+36 -23
View File
@@ -41,7 +41,16 @@
#include <BRepTools.hxx>
#include <BRepAlgoAPI_Section.hxx>
#include <ShapeAnalysis_FreeBounds.hxx>
#include <Standard_Version.hxx>
#if OCC_VERSION_HEX >= 0x80000
#include <Standard_Macro.hxx>
#include <TopoDS_Shape.hxx>
#include <NCollection_HSequence.hxx>
#else
#include <TopTools_HSequenceOfShape.hxx>
#endif
#include <TopExp.hxx>
#include <BRepAdaptor_Curve.hxx>
@@ -53,7 +62,6 @@
#include <Geom_Circle.hxx>
#include <Geom_Ellipse.hxx>
#include <gp_Ax22d.hxx>
#include <Standard_Version.hxx>
#include <GeomAPI.hxx>
#include <TopoDS_Wire.hxx>
@@ -275,18 +283,18 @@ void SvgSerializer::write(path_object& p, const TopoDS_Shape& comp_or_wire, std:
Handle(Geom2d_Curve) curve2d;
if (curve.IsNull()) {
TopLoc_Location loc;
Handle_Geom_Surface surf;
opencascade::handle<Geom_Surface> surf;
BRep_Tool::CurveOnSurface(edge, curve2d, surf, loc, u1, u2);
if (curve2d.IsNull()) {
logger::error("Failed to obtain 2d and 3d curve from edge");
logger_.Error("SER", 20, "Failed to obtain 2d and 3d curve from edge");
continue;
}
Handle(Standard_Type) sty = surf->DynamicType();
if (sty != STANDARD_TYPE(Geom_Plane)) {
logger::error("Non-planar p-curves are not supported by this serializer");
logger_.Error("SER", 21, "Non-planar p-curves are not supported by this serializer");
continue;
}
@@ -363,7 +371,7 @@ void SvgSerializer::write(path_object& p, const TopoDS_Shape& comp_or_wire, std:
std::stringstream ss;
ss << "Skipping full circle/ellipse inside aggregated <path> (id "
<< p.first << ")";
logger::warning(ss.str());
logger_.Warning("SER", 22, ss.str());
}
}
@@ -790,7 +798,7 @@ void SvgSerializer::write(const IfcGeom::BRepElement* brep_obj) {
BRepBndLib::AddOBB(compound_unmirrored, *view_box_3d_, false, false, false);
#endif
} else {
logger::error("Failed to box or edge from drawing annotation");
logger_.Error("SER", 23, "Failed to box or edge from drawing annotation");
}
std::vector<string_property> props;
@@ -937,7 +945,7 @@ void SvgSerializer::write(const geometry_data& data) {
if (data.storey) {
section_heights_storage.push_back(horizontal_plan{ data.storey, data.storey_elevation, +1. });
} else {
logger::warning("No global section height and unable to determine building storey for:", data.product);
logger_.Warning("SER", 24, "No global section height and unable to determine building storey for:", data.product);
return;
}
}
@@ -952,7 +960,7 @@ void SvgSerializer::write(const geometry_data& data) {
Bnd_OBB obb;
BRepBndLib::AddOBB(compound_unmirrored, obb, false, false, false);
if (view_box_3d_->IsOut(obb)) {
logger::notice("Not including element due to viewBox", data.product);
logger_.Notice("SER", 25, "Not including element due to viewBox", data.product);
return;
}
}
@@ -999,7 +1007,7 @@ void SvgSerializer::write(const geometry_data& data) {
}
}
} catch (std::exception& e) {
logger::error(e);
logger_.Error("SER", 26, e);
}
if (operation_type && ((*operation_type == "SINGLE_SWING_LEFT") || (*operation_type == "SINGLE_SWING_RIGHT"))) {
@@ -1252,14 +1260,14 @@ void SvgSerializer::write(const geometry_data& data) {
compound_to_hlr = &subtracted_shape;
} catch (...) {
logger::error("Failed to cut element for HLR", data.product);
logger_.Error("SER", 27, "Failed to cut element for HLR", data.product);
}
}
}
TopoDS_Compound profile_edges;
if (profile_threshold_ != -1 && !(data.product.declaration().is("IfcWall") || data.product.declaration().is("IfcSlab"))) {
TopTools_IndexedDataMapOfShapeListOfShape map;
NCollection_IndexedDataMap<TopoDS_Shape, NCollection_List<TopoDS_Shape>, TopTools_ShapeMapHasher> map;
TopExp::MapShapesAndAncestors(*compound_to_hlr, TopAbs_EDGE, TopAbs_FACE, map);
if (map.Extent() > profile_threshold_) {
BRep_Builder BB;
@@ -1344,11 +1352,11 @@ void SvgSerializer::write(const geometry_data& data) {
if (storey) {
auto it = storey_hlr.find(storey);
if (it == storey_hlr.end()) {
it = storey_hlr.insert({ storey, hlr_t(use_prefiltering_, use_hlr_poly_, segment_projection_, projection_plane) }).first;
it = storey_hlr.insert({ storey, hlr_t(logger_, use_prefiltering_, use_hlr_poly_, segment_projection_, projection_plane) }).first;
}
it->second.add(*compound_to_hlr, data.product);
} else {
logger::warning("Unable to invoke HLR due to absence of storey containment", data.product);
logger_.Warning("SER", 28, "Unable to invoke HLR due to absence of storey containment", data.product);
}
} else if (hlr) {
hlr->add(*compound_to_hlr, data.product);
@@ -1574,8 +1582,13 @@ void SvgSerializer::write(const geometry_data& data) {
result = make_transform_mirror_.Shape();
}
#if OCC_VERSION_HEX >= 0x80000
opencascade::handle<NCollection_HSequence<TopoDS_Shape>> edges = new NCollection_HSequence<TopoDS_Shape>();
opencascade::handle<NCollection_HSequence<TopoDS_Shape>> wires = new NCollection_HSequence<TopoDS_Shape>();
#else
Handle(TopTools_HSequenceOfShape) edges = new TopTools_HSequenceOfShape();
Handle(TopTools_HSequenceOfShape) wires = new TopTools_HSequenceOfShape();
#endif
{
TopExp_Explorer exp(result, TopAbs_EDGE);
for (; exp.More(); exp.Next()) {
@@ -1821,7 +1834,7 @@ void SvgSerializer::write(const geometry_data& data) {
}
if (!emitted) {
logger::warning("Element not written to SVG due to section heights", data.product);
logger_.Warning("SER", 29, "Element not written to SVG due to section heights", data.product);
}
}
@@ -2001,7 +2014,7 @@ 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_);
auto mapping = ifcopenshell::geometry::impl::mapping_implementations().construct(file, geometry_settings_, logger_);
auto item = mapping->map(pl);
auto matrix = ifcopenshell::geometry::taxonomy::cast<ifcopenshell::geometry::taxonomy::matrix4>(item);
delete mapping;
@@ -2204,7 +2217,7 @@ void SvgSerializer::finalize() {
// @todo do we have always have pln here?
if (use_hlr && pln) {
hlr = new hlr_t(use_prefiltering_, use_hlr_poly_, segment_projection_, *pln);
hlr = new hlr_t(logger_, use_prefiltering_, use_hlr_poly_, segment_projection_, *pln);
}
section_data_ = std::vector<section_data>{ sd };
@@ -2466,7 +2479,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_);
auto mapping = ifcopenshell::geometry::impl::mapping_implementations().construct(file, geometry_settings_, logger_);
std::vector<const ifcopenshell::declaration*> to_derive_from;
to_derive_from.push_back(f->schema()->declaration_by_name("IfcBuilding"));
@@ -2485,9 +2498,9 @@ void SvgSerializer::setFile(ifcopenshell::file* f) {
#ifdef TAXONOMY_USE_NAKED_PTR
delete matrix;
#endif
logger::warning("No building storeys encountered, used for reference:", product);
apply_section_heights_from_storeys();
return;
logger_.Warning("SER", 30, "No building storeys encountered, used for reference:", product);
return;
}
}
}
}
@@ -2495,7 +2508,7 @@ void SvgSerializer::setFile(ifcopenshell::file* f) {
delete mapping;
logger::warning("No building storeys encountered, output might be invalid or missing");
logger_.Warning("SER", 31, "No building storeys encountered, output might be invalid or missing");
}
apply_section_heights_from_storeys();
@@ -2508,7 +2521,7 @@ void SvgSerializer::setSectionHeight(double h, express::Base storey) {
void SvgSerializer::setSectionHeightsFromStoreys(double offset) {
if (!file) {
logger::error("No file specified");
logger_.Error("SER", 32, "No file specified");
return;
}
with_section_heights_from_storey_ = true;
@@ -2523,7 +2536,7 @@ void SvgSerializer::setSectionHeightsFromStoreys(double offset) {
try {
elev = attr_value;
} catch (std::exception& e) {
logger::error(e);
logger_.Error("SER", 33, e);
continue;
}
if (!section_data_->empty()) {
+9 -6
View File
@@ -368,10 +368,13 @@ namespace {
std::multimap<double, face_info> large_ortho_faces_;
std::list<std::pair<express::Base, TopoDS_Shape>> items_;
Logger& logger_;
public:
prefiltered_hlr(bool use_prefiltering, bool use_hlr_poly, bool segment_projection, const gp_Pln& view_direction)
: use_prefiltering_(use_prefiltering)
prefiltered_hlr(Logger& logger, bool use_prefiltering, bool use_hlr_poly, bool segment_projection, const gp_Pln& view_direction)
: logger_(logger)
, use_prefiltering_(use_prefiltering)
, use_hlr_poly_(use_hlr_poly)
, segment_projection_(segment_projection)
// @nb negative z in accordance with occt projector convention (and opengl)
@@ -468,7 +471,7 @@ namespace {
}
}
logger::notice("Included " + std::to_string(n_faces_included) + " faces out of " + std::to_string(n_total) + " after prefiltering");
logger_.Notice("SER", 34, "Included " + std::to_string(n_faces_included) + " faces out of " + std::to_string(n_total) + " after prefiltering");
auto it = items_.insert(items_.end(), { product, C });
@@ -517,7 +520,7 @@ namespace {
}
}
if (use_prefiltering_) {
logger::notice("Included " + std::to_string(n_included) + " elements out of " + std::to_string(items_.size()) + " after prefiltering");
logger_.Notice("SER", 35, "Included " + std::to_string(n_included) + " elements out of " + std::to_string(items_.size()) + " after prefiltering");
}
hlr_calc vis(projector_);
@@ -594,8 +597,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)
: WriteOnlyGeometrySerializer(geometry_settings, settings)
SvgSerializer(const stream_or_filename& out_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, Logger& logger = Logger::Root())
: WriteOnlyGeometrySerializer(geometry_settings, settings, logger)
, svg_file(out_filename)
, xmin(+std::numeric_limits<double>::infinity())
, ymin(+std::numeric_limits<double>::infinity())
+20 -5
View File
@@ -22,7 +22,15 @@
#ifdef IFOPSH_WITH_OPENCASCADE
#include "../ifcgeom/kernels/opencascade/OpenCascadeConversionResult.h"
#include <Standard_Version.hxx>
#if OCC_VERSION_HEX >= 0x80000
#include <Standard_Macro.hxx>
#include <TopoDS_Shape.hxx>
#include <NCollection_HSequence.hxx>
#else
#include <TopTools_HSequenceOfShape.hxx>
#endif
#include <BRepBuilderAPI_Transform.hxx>
#include <BRepBndLib.hxx>
#include <BRepAlgoAPI_Section.hxx>
@@ -225,8 +233,8 @@ namespace {
}
}
TtlWktSerializer::TtlWktSerializer(const stream_or_filename& filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings)
: WriteOnlyGeometrySerializer(geometry_settings, settings)
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)
, filename_(filename)
{
const auto& tri_setting = geometry_settings.get<ifcopenshell::geometry::settings::TriangulationType>().get();
@@ -408,14 +416,21 @@ void TtlWktSerializer::write(const IfcGeom::BRepElement* brep_obj) {
for (int iter = 0; iter < 10; ++iter) {
gp_Pln pln(gp_Pnt(0, 0, zmin + section_height + iter * (height - 1.) / 10.), gp::DZ());
#if OCC_VERSION_HEX >= 0x80000
opencascade::handle<NCollection_HSequence<TopoDS_Shape>> wires = new NCollection_HSequence<TopoDS_Shape>();
#else
Handle(TopTools_HSequenceOfShape) wires = new TopTools_HSequenceOfShape();
#endif
size_t N = 0;
TopoDS_Iterator it(compound);
// Iterate over components of compound to have better chance of matching section edges to closed wires
for (; it.More(); it.Next()) {
#if OCC_VERSION_HEX >= 0x80000
opencascade::handle<NCollection_HSequence<TopoDS_Shape>> edges = new NCollection_HSequence<TopoDS_Shape>();
#else
Handle(TopTools_HSequenceOfShape) edges = new TopTools_HSequenceOfShape();
#endif
TopoDS_Shape result = BRepAlgoAPI_Section(it.Value(), pln);
{
@@ -473,11 +488,11 @@ void TtlWktSerializer::write(const IfcGeom::BRepElement* brep_obj) {
if ((polygons_by_area.rbegin()->first > (0.6 * rectangle_area)) || (height < (1. + 1.e-5))) {
// Found sufficiently large polygon
if (emitted_warning) {
logger::warning("Found larger polygon area (" + std::to_string(polygons_by_area.rbegin()->first) + ").");
logger_.Warning("SER", 36, "Found larger polygon area (" + std::to_string(polygons_by_area.rbegin()->first) + ").");
}
break;
} else if (!emitted_warning) {
logger::warning("Section polygon area is small compared to bounding box area (" + std::to_string(polygons_by_area.rbegin()->first) + " < " + std::to_string(0.6 * rectangle_area) + "). Trying again with different section height.");
logger_.Warning("SER", 37, "Section polygon area is small compared to bounding box area (" + std::to_string(polygons_by_area.rbegin()->first) + " < " + std::to_string(0.6 * rectangle_area) + "). Trying again with different section height.");
emitted_warning = true;
}
}
+1 -1
View File
@@ -32,7 +32,7 @@ class SERIALIZERS_API TtlWktSerializer : public WriteOnlyGeometrySerializer {
private:
stream_or_filename filename_;
public:
TtlWktSerializer(const stream_or_filename& filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings);
TtlWktSerializer(const stream_or_filename& filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, Logger& logger = Logger::Root());
virtual ~TtlWktSerializer() {}
bool ready();
void writeHeader();
+2 -2
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):
WriteOnlyGeometrySerializer(geometry_settings, settings),
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),
filename_(out_filename)
{
std::size_t found = filename_.find_last_of("/\\");
+2 -2
View File
@@ -86,7 +86,7 @@ private:
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&);
USDSerializer(const std::string&, const ifcopenshell::geometry::Settings&, const ifcopenshell::geometry::SerializerSettings&, Logger& logger = Logger::Root());
virtual ~USDSerializer();
bool ready() { return ready_; }
void writeHeader();
@@ -101,4 +101,4 @@ public:
#endif
#endif
#endif
+2 -2
View File
@@ -27,8 +27,8 @@
#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)
: WriteOnlyGeometrySerializer(geometry_settings, settings)
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)
, obj_stream(obj_filename)
, mtl_stream(mtl_filename)
, vcount_total(1)
+1 -1
View File
@@ -35,7 +35,7 @@ private:
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);
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 = Logger::Root());
virtual ~WaveFrontOBJSerializer() {}
bool ready();
void writeHeader();
+1 -1
View File
@@ -19,7 +19,7 @@ protected:
std::string xml_filename;
public:
XmlSerializer(ifcopenshell::file* file, const std::string& xml_filename)
XmlSerializer(ifcopenshell::file* file, const std::string& xml_filename, Logger& logger = Logger::Root())
: xml_filename(xml_filename)
{
if (!file) {
@@ -18,6 +18,7 @@ foreach(schema ${SCHEMA_VERSIONS})
target_link_options(document_serializer_json_ifc${schema} PRIVATE "SHELL:-s ERROR_ON_UNDEFINED_SYMBOLS=0")
endif()
endif()
install(TARGETS Serializers_ifc${schema} EXPORT ${IFCOPENSHELL_EXPORT_TARGETS})
endforeach()
set(document_serializer_libraries ${document_serializer_libraries} PARENT_SCOPE)
@@ -171,7 +171,7 @@ void descend(A instance, json& tree, express::Base parent = express::Base()) {
if (instance.declaration().is(IfcSchema::IfcObjectDefinition::Class())) {
descend(instance.template as<IfcSchema::IfcObjectDefinition>(), tree, parent);
} else {
format_entity_instance(instance, tree);
format_entity_instance(instance, tree, logger);
}
}
@@ -189,7 +189,7 @@ void descend(IfcSchema::IfcObjectDefinition product, json& tree, express::Base p
}
}
format_entity_instance(product, tree, parent);
format_entity_instance(product, tree, logger, parent);
if (auto opening = product.as<IfcSchema::IfcOpeningElement>()) {
auto fills = get_related<IfcSchema::IfcOpeningElement, IfcSchema::IfcRelFillsElement, IfcSchema::IfcElement>(
@@ -262,7 +262,7 @@ void POSTFIX_SCHEMA(JsonSerializer)::finalize() {
auto projects = file->instances_by_type<IfcSchema::IfcProject>();
if (projects.size() != 1) {
logger::message(logger::LOG_ERROR, "Expected a single IfcProject");
logger_.Message(Logger::LOG_ERROR, "SER", 7, "Expected a single IfcProject");
return;
}
IfcSchema::IfcProject project = projects.front();
@@ -271,7 +271,7 @@ void POSTFIX_SCHEMA(JsonSerializer)::finalize() {
try {
return fn();
} catch (const std::exception& e) {
logger::error(e);
logger_.Error("SER", 8, e);
static std::invoke_result_t<decltype(fn)> v;
return v;
}
@@ -576,7 +576,7 @@ void POSTFIX_SCHEMA(JsonSerializer)::finalize() {
}
*/
descend(project, output["metaObjects"]);
descend(project, output["metaObjects"], logger_);
std::ofstream f(ifcopenshell::path::from_utf8(json_filename).c_str());
f << output.dump(4);
@@ -41,8 +41,8 @@ class POSTFIX_SCHEMA(JsonSerializer) : public JsonSerializer {
ifcopenshell::geometry::abstract_mapping* mapping_;
public:
POSTFIX_SCHEMA(JsonSerializer)(ifcopenshell::file* file, const std::string& json_filename, JsonSerializer::Dialect dialect)
: JsonSerializer(0, "", dialect), mapping_(ifcopenshell::geometry::impl::mapping_implementations().construct(file, settings_))
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))
{
this->file = file;
this->json_filename = json_filename;
@@ -131,13 +131,13 @@ std::optional<std::string> format_attribute(ifcopenshell::geometry::abstract_map
}
// Appends to a node with possibly existing attributes
ptree* format_entity_instance(ifcopenshell::geometry::abstract_mapping* mapping, const express::Base& instance, ptree& child, ptree& tree, bool as_link = false) {
ptree* format_entity_instance(Logger& logger, ifcopenshell::geometry::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 {
instance.get_attribute_value(i);
} catch (const std::exception&) {
logger::error("Expected " + boost::lexical_cast<std::string>(n) + " attributes for:", instance);
logger.Error("SER", 9, "Expected " + boost::lexical_cast<std::string>(n) + " attributes for:", instance);
break;
}
auto argument = instance.get_attribute_value(i);
@@ -156,7 +156,7 @@ ptree* format_entity_instance(ifcopenshell::geometry::abstract_mapping* mapping,
try {
value = format_attribute(mapping, argument, argument_type, qualified_name);
} catch (const std::exception& e) {
logger::error(e);
logger.Error("SER", 10, e);
}
if (value) {
@@ -176,9 +176,9 @@ ptree* format_entity_instance(ifcopenshell::geometry::abstract_mapping* mapping,
// 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(ifcopenshell::geometry::abstract_mapping* mapping, const express::Base& instance, ptree& tree, bool as_link = false) {
ptree* format_entity_instance(Logger& logger, ifcopenshell::geometry::abstract_mapping* mapping, const express::Base& instance, ptree& tree, bool as_link = false) {
ptree child;
return format_entity_instance(mapping, instance, child, tree, as_link);
return format_entity_instance(logger, mapping, instance, child, tree, as_link);
}
std::string qualify_unrooted_instance(const express::Base& inst) {
@@ -192,7 +192,7 @@ ptree* descend(ifcopenshell::geometry::abstract_mapping* mapping, A instance, pt
if (instance.declaration().is(IfcSchema::IfcObjectDefinition::Class())) {
return descend(mapping, instance.template as<IfcSchema::IfcObjectDefinition>(), tree, parent);
} else {
return format_entity_instance(mapping, instance, tree);
return format_entity_instance(logger, mapping, instance, tree);
}
}
@@ -239,7 +239,7 @@ ptree* descend(ifcopenshell::geometry::abstract_mapping* mapping, IfcSchema::Ifc
}
}
ptree& child = *format_entity_instance(mapping, product, tree);
ptree& child = *format_entity_instance(logger, mapping, product, tree);
if (auto opening = product.as<IfcSchema::IfcOpeningElement>()) {
auto fills = get_related<IfcSchema::IfcOpeningElement, IfcSchema::IfcRelFillsElement, IfcSchema::IfcElement>(
@@ -253,7 +253,7 @@ ptree* descend(ifcopenshell::geometry::abstract_mapping* mapping, IfcSchema::Ifc
if (auto structure = product.as<IfcSchema::IfcSpatialStructureElement>()) {
auto elements = get_related
<IfcSchema::IfcSpatialStructureElement, IfcSchema::IfcRelContainedInSpatialStructure, IfcSchema::IfcObjectDefinition>
(structure, &IfcSchema::IfcSpatialStructureElement::ContainsElements, &IfcSchema::IfcRelContainedInSpatialStructure::RelatedElements);
(logger, structure, &IfcSchema::IfcSpatialStructureElement::ContainsElements, &IfcSchema::IfcRelContainedInSpatialStructure::RelatedElements);
for (auto& el : elements) {
descend(mapping, el, child, product);
@@ -272,11 +272,11 @@ ptree* descend(ifcopenshell::geometry::abstract_mapping* mapping, IfcSchema::Ifc
#ifdef SCHEMA_IfcRelDecomposes_HAS_RelatedObjects
auto structures = get_related
<IfcSchema::IfcObjectDefinition, IfcSchema::IfcRelDecomposes, IfcSchema::IfcObjectDefinition>
(product, &IfcSchema::IfcObjectDefinition::IsDecomposedBy, &IfcSchema::IfcRelDecomposes::RelatedObjects);
(logger, product, &IfcSchema::IfcObjectDefinition::IsDecomposedBy, &IfcSchema::IfcRelDecomposes::RelatedObjects);
#else
auto structures = get_related
<IfcSchema::IfcObjectDefinition, IfcSchema::IfcRelAggregates, IfcSchema::IfcObjectDefinition>
(product, &IfcSchema::IfcObjectDefinition::IsDecomposedBy, &IfcSchema::IfcRelAggregates::RelatedObjects);
(logger, product, &IfcSchema::IfcObjectDefinition::IsDecomposedBy, &IfcSchema::IfcRelAggregates::RelatedObjects);
auto nested = get_related
<IfcSchema::IfcObjectDefinition, IfcSchema::IfcRelNests, IfcSchema::IfcObjectDefinition>
@@ -292,12 +292,12 @@ ptree* descend(ifcopenshell::geometry::abstract_mapping* mapping, IfcSchema::Ifc
if (auto object = product.as<IfcSchema::IfcObject>()) {
auto property_sets = get_related
<IfcSchema::IfcObject, IfcSchema::IfcRelDefinesByProperties, IfcSchema::IfcPropertySetDefinition>
(object, &IfcSchema::IfcObject::IsDefinedBy, &IfcSchema::IfcRelDefinesByProperties::RelatingPropertyDefinition);
(logger, object, &IfcSchema::IfcObject::IsDefinedBy, &IfcSchema::IfcRelDefinesByProperties::RelatingPropertyDefinition);
#ifdef SCHEMAS_HAS_IfcPropertySetDefinitionSet
auto property_set_sets = get_related
<IfcSchema::IfcObject, IfcSchema::IfcRelDefinesByProperties, IfcSchema::IfcPropertySetDefinitionSet>
(object, &IfcSchema::IfcObject::IsDefinedBy, &IfcSchema::IfcRelDefinesByProperties::RelatingPropertyDefinition);
(logger, object, &IfcSchema::IfcObject::IsDefinedBy, &IfcSchema::IfcRelDefinesByProperties::RelatingPropertyDefinition);
for (auto& s : property_set_sets) {
auto set_sets_value = (decltype(property_sets))s;
@@ -316,11 +316,11 @@ ptree* descend(ifcopenshell::geometry::abstract_mapping* mapping, IfcSchema::Ifc
#ifdef SCHEMA_IfcObject_HAS_IsTypedBy
auto types = get_related
<IfcSchema::IfcObject, IfcSchema::IfcRelDefinesByType, IfcSchema::IfcTypeObject>
(object, &IfcSchema::IfcObject::IsTypedBy, &IfcSchema::IfcRelDefinesByType::RelatingType);
(logger, object, &IfcSchema::IfcObject::IsTypedBy, &IfcSchema::IfcRelDefinesByType::RelatingType);
#else
auto types = get_related
<IfcSchema::IfcObject, IfcSchema::IfcRelDefinesByType, IfcSchema::IfcTypeObject>
(object, &IfcSchema::IfcObject::IsDefinedBy, &IfcSchema::IfcRelDefinesByType::RelatingType);
(logger, object, &IfcSchema::IfcObject::IsDefinedBy, &IfcSchema::IfcRelDefinesByType::RelatingType);
#endif
for (auto& type : types) {
@@ -366,7 +366,7 @@ void format_properties(ifcopenshell::geometry::abstract_mapping* mapping, const
if (auto complex = p.as<IfcSchema::IfcComplexProperty>()) {
format_properties(mapping, complex.HasProperties(), node);
} else {
format_entity_instance(mapping, p, node);
format_entity_instance(logger, mapping, p, node);
}
}
}
@@ -396,7 +396,7 @@ void writeGroupToNode(ifcopenshell::geometry::abstract_mapping* mapping, IfcSche
}
else {
// Write child to father group
descend(mapping, entity, *node2);
descend(logger, mapping, entity, *node2);
}
}
}
@@ -421,7 +421,7 @@ void format_tasks(ifcopenshell::geometry::abstract_mapping* mapping, IfcSchema::
IfcSchema::IfcTaskTime task_time = task.TaskTime();
if (task_time)
{
format_entity_instance(mapping, task_time, *ntask);
format_entity_instance(logger, mapping, task_time, *ntask);
}
#endif
@@ -449,7 +449,7 @@ void format_tasks(ifcopenshell::geometry::abstract_mapping* mapping, IfcSchema::
auto property_sets = get_related
<IfcSchema::IfcObject, IfcSchema::IfcRelDefinesByProperties, IfcSchema::IfcPropertySetDefinition>
(task, &IfcSchema::IfcObject::IsDefinedBy, &IfcSchema::IfcRelDefinesByProperties::RelatingPropertyDefinition);
(logger, task, &IfcSchema::IfcObject::IsDefinedBy, &IfcSchema::IfcRelDefinesByProperties::RelatingPropertyDefinition);
for (auto& pset : property_sets) {
if (pset.declaration().is(IfcSchema::IfcPropertySet::Class())) {
@@ -538,7 +538,7 @@ void POSTFIX_SCHEMA(XmlSerializer)::finalize() {
try {
return fn();
} catch(const std::exception& e) {
logger::error(e);
logger_.Error("SER", 13, e);
static std::invoke_result_t<decltype(fn)> v;
return v;
}
@@ -563,7 +563,7 @@ void POSTFIX_SCHEMA(XmlSerializer)::finalize() {
catch (const ifcopenshell::exception& ex) {
std::stringstream ss;
ss << "Failed to get ifc file header file_description implementation_level, error: '" << ex.what() << "'";
logger::message(logger::LOG_ERROR, ss.str());
logger_.Message(Logger::LOG_ERROR, "SER", 14, ss.str());
}
try {
header.put("file_name.name", file->header().file_name().name());
@@ -571,7 +571,7 @@ void POSTFIX_SCHEMA(XmlSerializer)::finalize() {
catch (const ifcopenshell::exception& ex) {
std::stringstream ss;
ss << "Failed to get ifc file header file_name name, error: '" << ex.what() << "'";
logger::message(logger::LOG_ERROR, ss.str());
logger_.Message(Logger::LOG_ERROR, "SER", 15, ss.str());
}
try {
header.put("file_name.time_stamp", file->header().file_name().time_stamp());
@@ -579,7 +579,7 @@ void POSTFIX_SCHEMA(XmlSerializer)::finalize() {
catch (const ifcopenshell::exception& ex) {
std::stringstream ss;
ss << "Failed to get ifc file header file_name time_stamp, error: '" << ex.what() << "'";
logger::message(logger::LOG_ERROR, ss.str());
logger_.Message(Logger::LOG_ERROR, "SER", 16, ss.str());
}
try {
header.put("file_name.preprocessor_version", file->header().file_name().preprocessor_version());
@@ -587,7 +587,7 @@ void POSTFIX_SCHEMA(XmlSerializer)::finalize() {
catch (const ifcopenshell::exception& ex) {
std::stringstream ss;
ss << "Failed to get ifc file header file_name preprocessor_version, error: '" << ex.what() << "'";
logger::message(logger::LOG_ERROR, ss.str());
logger_.Message(Logger::LOG_ERROR, "SER", 17, ss.str());
}
try {
header.put("file_name.originating_system", file->header().file_name().originating_system());
@@ -595,7 +595,7 @@ void POSTFIX_SCHEMA(XmlSerializer)::finalize() {
catch (const ifcopenshell::exception& ex) {
std::stringstream ss;
ss << "Failed to get ifc file header file_name originating_system, error: '" << ex.what() << "'";
logger::message(logger::LOG_ERROR, ss.str());
logger_.Message(Logger::LOG_ERROR, "SER", 18, ss.str());
}
try {
// @nb inconsistent spelling
@@ -604,11 +604,11 @@ void POSTFIX_SCHEMA(XmlSerializer)::finalize() {
catch (const ifcopenshell::exception& ex) {
std::stringstream ss;
ss << "Failed to get ifc file header file_name authorization, error: '" << ex.what() << "'";
logger::message(logger::LOG_ERROR, ss.str());
}
logger_.Message(Logger::LOG_ERROR, "SER", 19, ss.str());
}
// Descend into the decomposition structure of the IFC file.
descend(mapping_, project, decomposition);
descend(logger_, mapping_, project, decomposition);
// Write all property sets and values as XML nodes.
auto psets = file->instances_by_type<IfcSchema::IfcPropertySet>();
@@ -39,9 +39,9 @@ private:
ifcopenshell::geometry::abstract_mapping* mapping_;
public:
POSTFIX_SCHEMA(XmlSerializer)(ifcopenshell::file* file, const std::string& xml_filename)
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_))
, mapping_(ifcopenshell::geometry::impl::mapping_implementations().construct(file, settings_, logger))
{
this->file = file;
this->xml_filename = xml_filename;
@@ -51,4 +51,4 @@ public:
void setFile(ifcopenshell::file*) {}
};
#endif
#endif