Merge remote-tracking branch 'origin/v0.8.0' into tfk-rocksdb-storage

This commit is contained in:
Thomas Krijnen
2025-08-26 10:17:57 +02:00
1179 changed files with 47255 additions and 16166 deletions
+4 -1
View File
@@ -106,7 +106,10 @@ int GltfSerializer::writeMaterial(const ifcopenshell::geometry::taxonomy::style:
base[3] = 1. - style->transparency;
}
json_["materials"].push_back({ {"name", style->name}, {"doubleSided", true}, {"pbrMetallicRoughness", {{"baseColorFactor", base}, {"metallicFactor", 0}}}});
if (style->has_specularity())
json_["materials"].push_back({ {"name", style->name}, {"doubleSided", true}, {"pbrMetallicRoughness", {{"baseColorFactor", base}, {"metallicFactor", 0}, {"roughnessFactor", 1.0 / style->specularity}}}});
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) {
json_["materials"].back()["alphaMode"] = "BLEND";
+28 -9
View File
@@ -33,6 +33,7 @@
#include <iomanip>
#include <numeric>
#include <functional>
#include <cmath>
#ifdef USE_BINARY
#define write_shape write_binary
@@ -233,21 +234,25 @@ namespace {
}
}
void HdfSerializer::read_surface_style(surface_style_serialization& s, const ifcopenshell::geometry::taxonomy::style::ptr& gss_) {
auto& gss = *gss_;
void HdfSerializer::read_surface_style(const surface_style_serialization& s,
ifcopenshell::geometry::taxonomy::style& gss,
IfcParse::IfcFile& f) {
if (strlen(s.name) || s.id) {
if (s.diffuse[0] == s.diffuse[0]) {
if (!std::isnan(s.diffuse[0])) {
gss.diffuse = ifcopenshell::geometry::taxonomy::colour(s.diffuse[0], s.diffuse[1], s.diffuse[2]);
}
if (s.specular[0] == s.specular[0]) {
if (!std::isnan(s.specular[0])) {
gss.specular = ifcopenshell::geometry::taxonomy::colour(s.specular[0], s.specular[1], s.specular[2]);
}
if (s.transparency == s.transparency) {
if (!std::isnan(s.transparency)) {
gss.transparency = s.transparency;
}
if (s.specularity == s.specularity) {
if (!std::isnan(s.specularity)) {
gss.specularity = s.specularity;
}
if (s.id != 0) {
gss.instance = f.instance_by_id(s.id)->as<IfcUtil::IfcBaseEntity>();
}
}
}
@@ -356,7 +361,7 @@ IfcGeom::Element* HdfSerializer::read(IfcParse::IfcFile& f, const std::string& g
matrix->components() << Eigen::Map<Eigen::Matrix4d>(&part.matrix[0][0]);
auto style_ptr = ifcopenshell::geometry::taxonomy::make<ifcopenshell::geometry::taxonomy::style>();
read_surface_style(part.surface_style, style_ptr);
read_surface_style(part.surface_style, *style_ptr, f);
shapes.push_back(IfcGeom::ConversionResult(part.id, matrix, new ifcopenshell::geometry::OpenCascadeShape(shp), style_ptr));
}
@@ -421,7 +426,8 @@ IfcGeom::Element* HdfSerializer::read(IfcParse::IfcFile& f, const std::string& g
std::vector<ifcopenshell::geometry::taxonomy::style::ptr> surface_style_ptrs(surface_styles.size());
for (size_t i = 0; i < surface_styles.size(); ++i) {
read_surface_style(surface_styles[i], surface_style_ptrs[i]);
surface_style_ptrs[i] = ifcopenshell::geometry::taxonomy::make<ifcopenshell::geometry::taxonomy::style>();
read_surface_style(surface_styles[i], *surface_style_ptrs[i], f);
}
triangulation_geometry = boost::shared_ptr<IfcGeom::Representation::Triangulation>(new IfcGeom::Representation::Triangulation(
@@ -544,7 +550,8 @@ void HdfSerializer::write_style(surface_style_serialization& data, const ifcopen
data.name = s.name.c_str();
// @todo
data.original_name = s.name.c_str();
data.id = s.instance->as<IfcUtil::IfcBaseClass>()->id();
auto instance = s.instance->as<IfcUtil::IfcBaseClass>();
data.id = instance ? instance->id() : 0;
if (s.diffuse) {
data.diffuse[0] = s.diffuse.ccomponents()(0);
data.diffuse[1] = s.diffuse.ccomponents()(1);
@@ -565,6 +572,16 @@ void HdfSerializer::write_style(surface_style_serialization& data, const ifcopen
void HdfSerializer::write(const IfcGeom::BRepElement* o) {
// Currenly we only support OpenCascade shapes.
for (auto it = o->geometry().begin(); it != o->geometry().end(); ++it) {
auto shape_ptr = std::dynamic_pointer_cast<ifcopenshell::geometry::OpenCascadeShape>(it->Shape());
if (shape_ptr == nullptr) {
std::cerr << "WARNING. Only OpenCascade shapes support caching. "
<< "Skipping caching for item #" << it->ItemId() << "." << std::endl;
return;
}
}
static auto nan = std::numeric_limits<double>::quiet_NaN();
auto element_group = write((const IfcGeom::Element*)o);
@@ -609,6 +626,7 @@ void HdfSerializer::write(const IfcGeom::BRepElement* o) {
}
brep_strings.emplace_back();
// OpenCascadeShape type ensured by the check at the method start.
write_shape(std::static_pointer_cast<ifcopenshell::geometry::OpenCascadeShape>(it->Shape())->shape(), brep_strings.back());
parts[i].surface_style = { "", "", 0, {nan,nan,nan}, {nan,nan,nan}, nan, nan };
@@ -671,6 +689,7 @@ void HdfSerializer::write(const IfcGeom::TriangulationElement* o) {
write_dataset(meshGroup, DATASET_NAME_UVCOORDS, mesh.uvs(), 2);
write_dataset(meshGroup, DATASET_NAME_MATERIAL_IDS, mesh.material_ids(), 1);
write_dataset(meshGroup, DATASET_NAME_ITEM_IDS, mesh.item_ids(), 1);
write_dataset(meshGroup, DATASET_NAME_EDGES_ITEM_IDS, mesh.edges_item_ids(), 1);
{
auto& ts = mesh.materials();
+3 -1
View File
@@ -90,7 +90,9 @@ private:
std::map<std::string, std::string> group_cache_;
H5::Group createRepresentationGroup(const H5::Group& element_group, const std::string& gid);
void read_surface_style(surface_style_serialization& sss, const ifcopenshell::geometry::taxonomy::style::ptr& style_ptr);
void read_surface_style(const surface_style_serialization& s,
ifcopenshell::geometry::taxonomy::style& gss,
IfcParse::IfcFile& f);
void write_style(surface_style_serialization& data, const ifcopenshell::geometry::taxonomy::style::ptr& s);
public:
+1 -1
View File
@@ -54,7 +54,7 @@ public:
void setUnitNameAndMagnitude(const std::string& /*name*/, float magnitude) {
const char* symbol = getSymbolForUnitMagnitude(magnitude);
if (symbol) {
Interface_Static::SetCVal("xstep.cascade.unit", symbol);
// Interface_Static::SetCVal("xstep.cascade.unit", symbol);
Interface_Static::SetCVal("write.step.unit", symbol);
}
}
+11 -7
View File
@@ -646,6 +646,8 @@ void SvgSerializer::write(const IfcGeom::BRepElement* brep_obj) {
view_box_3d_.emplace();
BRepBndLib::AddOBB(compound_unmirrored, *view_box_3d_, false, false, false);
#endif
} else {
Logger::Error("Failed to box or edge from drawing annotation");
}
std::vector<string_property> props;
@@ -2401,13 +2403,15 @@ namespace {
std::string SvgSerializer::writeMetadata(const drawing_meta& m) {
gp_Trsf trsf;
trsf.SetTransformation(m.pln_3d.Position(), gp::XOY());
// @todo
std::array<std::array<double, 4>, 4> m4 = {{
{{ 1, 0, 0, 0 }},
{{ 0, 1, 0, 0 }},
{{ 0, 0, 1, 0 }},
{{ 0, 0, 0, 1 }}
}};
NCollection_Mat4<double> mat4;
trsf.GetMat4(mat4);
const auto* d = mat4.GetData();
std::array<std::array<double, 4>, 4> m4 = { {
{{ d[0], d[4], d[8], d[12] }},
{{ d[1], d[5], d[9], d[13] }},
{{ d[2], d[6], d[10], d[14] }},
{{ d[3], d[7], d[11], d[15] }}
} };
return namespace_prefix_ + "plane=\""+ array_to_string(m4) +"\" " +
namespace_prefix_ + "matrix3=\"" + array_to_string(m.matrix_3) + "\"";
}
+17 -12
View File
@@ -177,7 +177,7 @@ namespace {
}
std::string escape_for_turtle(const std::u32string& input) {
std::wostringstream escaped;
std::ostringstream escaped;
escaped << "\"";
for (auto& c : input) {
@@ -200,7 +200,7 @@ namespace {
default:
if (c < 0x20 || c > 0x7E) {
escaped << "\\u"
<< std::hex << std::setw(4) << std::setfill(L'0')
<< std::hex << std::setw(4) << std::setfill('0')
<< (c & 0xFFFF);
} else {
escaped.put(c);
@@ -209,7 +209,7 @@ namespace {
}
}
escaped << "\"";
return IfcUtil::convert_utf8(escaped.str());
return escaped.str();
}
template <typename Fn, typename... Ts>
@@ -262,16 +262,16 @@ void TtlWktSerializer::write(const IfcGeom::TriangulationElement* o)
{
filename_.stream << ttl_object_id(o) << " a geo:Feature ;\n";
filename_.stream << " dcterms:identifier " << escape_for_turtle(
IfcUtil::convert_utf8_to_utf32(o->guid())) << " ;\n";
IfcUtil::convert_utf8(o->guid())) << " ;\n";
filename_.stream << " rdfs:label " << escape_for_turtle(
IfcUtil::convert_utf8_to_utf32(o->name())
IfcUtil::convert_utf8(o->name())
) << " ;\n";
filename_.stream << " geo:hasGeometry " << ttl_object_id(o, "_geometry") << " .\n\n";
if (!o->geometry().polyhedral_faces_with_holes().empty()) {
filename_.stream << ttl_object_id(o, "_geometry") << " a geo:Geometry ;\n";
filename_.stream << " geo:asWKT " << escape_for_turtle(
IfcUtil::convert_utf8_to_utf32(
IfcUtil::convert_utf8(
capture_output(
emit_polyhedral_surface,
o->geometry().verts(),
@@ -314,7 +314,7 @@ void TtlWktSerializer::write(const IfcGeom::TriangulationElement* o)
filename_.stream << ttl_object_id(o) << " geo:hasGeometry " << ttl_object_id(o, "_footprint_geometry") << " .\n\n";
filename_.stream << ttl_object_id(o, "_footprint_geometry") << " a geo:Geometry ;\n";
filename_.stream << " geo:asWKT " << escape_for_turtle(
IfcUtil::convert_utf8_to_utf32(
IfcUtil::convert_utf8(
capture_output(
// @nb this is line_component, because this is the linestring
// from a faceboundary, not the edges as pairs of indices.
@@ -341,7 +341,7 @@ void TtlWktSerializer::write(const IfcGeom::TriangulationElement* o)
}
}
filename_.stream << " geo:asWKT " << escape_for_turtle(
IfcUtil::convert_utf8_to_utf32(
IfcUtil::convert_utf8(
capture_output(
emit_line_strings,
o->geometry().verts(),
@@ -355,9 +355,9 @@ void TtlWktSerializer::write(const IfcGeom::BRepElement* brep_obj) {
#ifdef IFOPSH_WITH_OPENCASCADE
filename_.stream << ttl_object_id(brep_obj) << " a geo:Feature ;\n";
filename_.stream << " dcterms:identifier " << escape_for_turtle(
IfcUtil::convert_utf8_to_utf32(brep_obj->guid())) << " ;\n";
IfcUtil::convert_utf8(brep_obj->guid())) << " ;\n";
filename_.stream << " rdfs:label " << escape_for_turtle(
IfcUtil::convert_utf8_to_utf32(brep_obj->name())
IfcUtil::convert_utf8(brep_obj->name())
) << " .\n";
// @todo unify logic with SVG serializer
@@ -391,7 +391,12 @@ void TtlWktSerializer::write(const IfcGeom::BRepElement* brep_obj) {
double x1, y1, zmin, x2, y2, zmax;
bb.Get(x1, y1, zmin, x2, y2, zmax);
gp_Pln pln(gp_Pnt(0, 0, zmin + 1.), gp::DZ());
auto height = zmax - zmin;
auto section_height = (height < (1. + 1.e-5)) ? (height / 2.0) : 1.0;
filename_.stream << ttl_object_id(brep_obj) << " geo:hasMetricLength " << height << " .\n\n";
gp_Pln pln(gp_Pnt(0, 0, zmin + section_height), gp::DZ());
Handle(TopTools_HSequenceOfShape) wires = new TopTools_HSequenceOfShape();
@@ -431,7 +436,7 @@ void TtlWktSerializer::write(const IfcGeom::BRepElement* brep_obj) {
filename_.stream << ttl_object_id(brep_obj) << " geo:hasGeometry " << ttl_object_id(brep_obj, postfix.c_str()) << " .\n\n";
filename_.stream << ttl_object_id(brep_obj, postfix.c_str()) << " a geo:Geometry ;\n";
filename_.stream << " geo:asWKT " << escape_for_turtle(
IfcUtil::convert_utf8_to_utf32(
IfcUtil::convert_utf8(
capture_output(
emit_line_component,
loop_coords,
@@ -219,9 +219,9 @@ ptree* descend(ifcopenshell::geometry::abstract_mapping* mapping, A* instance, p
// Returns related entity instances using IFC's objectified relationship
// model. The second and third argument require a member function pointer.
template <typename T, typename U, typename V, typename F, typename G>
typename V::list::ptr get_related(T* t, F f, G g) {
auto get_related(T* t, F f, G g) {
typename U::list::ptr li = (*t.*f)()->template as<U>();
typename V::list::ptr acc(new typename V::list);
typename aggregate_of<V>::ptr acc(new aggregate_of<V>);
for (typename U::list::it it = li->begin(); it != li->end(); ++it) {
U* u = *it;
try {
@@ -305,6 +305,16 @@ ptree* descend(ifcopenshell::geometry::abstract_mapping* mapping, IfcSchema::Ifc
<IfcSchema::IfcObject, IfcSchema::IfcRelDefinesByProperties, IfcSchema::IfcPropertySetDefinition>
(object, &IfcSchema::IfcObject::IsDefinedBy, &IfcSchema::IfcRelDefinesByProperties::RelatingPropertyDefinition);
#ifdef SCHEMAS_HAS_IfcPropertySetDefinitionSet
aggregate_of<IfcSchema::IfcPropertySetDefinitionSet>::ptr property_set_sets = get_related
<IfcSchema::IfcObject, IfcSchema::IfcRelDefinesByProperties, IfcSchema::IfcPropertySetDefinitionSet>
(object, &IfcSchema::IfcObject::IsDefinedBy, &IfcSchema::IfcRelDefinesByProperties::RelatingPropertyDefinition);
for (auto& s : *property_set_sets) {
property_sets->push((decltype(property_sets))*s);
}
#endif
for (IfcSchema::IfcPropertySetDefinition::list::it it = property_sets->begin(); it != property_sets->end(); ++it) {
IfcSchema::IfcPropertySetDefinition* pset = *it;
if (pset->declaration().is(IfcSchema::IfcPropertySet::Class())) {
@@ -352,7 +362,7 @@ ptree* descend(ifcopenshell::geometry::abstract_mapping* mapping, IfcSchema::Ifc
}
}
#ifdef SCHEMA_HAS_IfcAlignmentSegment
#if defined(SCHEMA_HAS_IfcAlignmentSegment) && defined(SCHEMA_IfcAlignmentSegment_HAS_DesignParameters)
if (auto* als = product->as<IfcSchema::IfcAlignmentSegment>()) {
ptree node;
format_entity_instance(mapping, als->DesignParameters(), node, child, false);
+3 -1
View File
@@ -22,6 +22,8 @@
#include <sstream>
#include <vector>
#include <iomanip>
#include <limits>
#include <boost/shared_ptr.hpp>
@@ -50,7 +52,7 @@ namespace util {
void assign(const double& d) { this->d = d; }
const double& value() const { return d; }
double& value() { return d; }
std::string str() const { std::stringstream ss; ss << d; return ss.str(); }
std::string str() const { std::stringstream ss; ss << std::setprecision(std::numeric_limits<double>::max_digits10) << d; return ss.str(); }
virtual ~float_item() {};
};
private: