mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-10-02 21:12:07 +00:00
WKT footprint massaging
This commit is contained in:
@@ -31,6 +31,10 @@
|
|||||||
#include <TopoDS.hxx>
|
#include <TopoDS.hxx>
|
||||||
#include <Bnd_Box.hxx>
|
#include <Bnd_Box.hxx>
|
||||||
#include <gp_Pln.hxx>
|
#include <gp_Pln.hxx>
|
||||||
|
#include <TopoDS_Wire.hxx>
|
||||||
|
#include <BRepBuilderAPI_MakeFace.hxx>
|
||||||
|
#include <GProp_GProps.hxx>
|
||||||
|
#include <BRepGProp.hxx>
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -396,7 +400,14 @@ void TtlWktSerializer::write(const IfcGeom::BRepElement* brep_obj) {
|
|||||||
|
|
||||||
filename_.stream << ttl_object_id(brep_obj) << " geo:hasMetricLength " << height << " .\n\n";
|
filename_.stream << ttl_object_id(brep_obj) << " geo:hasMetricLength " << height << " .\n\n";
|
||||||
|
|
||||||
gp_Pln pln(gp_Pnt(0, 0, zmin + section_height), gp::DZ());
|
std::map<double, std::string> polygons_by_area;
|
||||||
|
|
||||||
|
double rectangle_area = (x2 - x1) * (y2 - y1);
|
||||||
|
bool emitted_warning = false;
|
||||||
|
|
||||||
|
for (int iter = 0; iter < 10; ++iter) {
|
||||||
|
|
||||||
|
gp_Pln pln(gp_Pnt(0, 0, zmin + section_height + iter * (height - 1.) / 10.), gp::DZ());
|
||||||
|
|
||||||
Handle(TopTools_HSequenceOfShape) wires = new TopTools_HSequenceOfShape();
|
Handle(TopTools_HSequenceOfShape) wires = new TopTools_HSequenceOfShape();
|
||||||
|
|
||||||
@@ -417,6 +428,21 @@ void TtlWktSerializer::write(const IfcGeom::BRepElement* brep_obj) {
|
|||||||
ShapeAnalysis_FreeBounds::ConnectEdgesToWires(edges, 1e-4, false, wires);
|
ShapeAnalysis_FreeBounds::ConnectEdgesToWires(edges, 1e-4, false, wires);
|
||||||
for (int i = 1; i <= wires->Length(); ++i) {
|
for (int i = 1; i <= wires->Length(); ++i) {
|
||||||
const TopoDS_Wire& wire = TopoDS::Wire(wires->Value(i));
|
const TopoDS_Wire& wire = TopoDS::Wire(wires->Value(i));
|
||||||
|
if (!wire.Closed()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
BRepBuilderAPI_MakeFace mf(wire);
|
||||||
|
if (!mf.IsDone()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto face = mf.Face();
|
||||||
|
// calculate face area
|
||||||
|
GProp_GProps props;
|
||||||
|
BRepGProp::SurfaceProperties(face, props);
|
||||||
|
auto area = props.Mass();
|
||||||
|
|
||||||
BRepTools_WireExplorer it(wire);
|
BRepTools_WireExplorer it(wire);
|
||||||
std::vector<double> loop_coords;
|
std::vector<double> loop_coords;
|
||||||
for (; it.More(); it.Next()) {
|
for (; it.More(); it.Next()) {
|
||||||
@@ -433,19 +459,35 @@ void TtlWktSerializer::write(const IfcGeom::BRepElement* brep_obj) {
|
|||||||
|
|
||||||
std::string postfix = "_section_geometry_" + std::to_string(N++);
|
std::string postfix = "_section_geometry_" + std::to_string(N++);
|
||||||
|
|
||||||
filename_.stream << ttl_object_id(brep_obj) << " geo:hasGeometry " << ttl_object_id(brep_obj, postfix.c_str()) << " .\n\n";
|
std::ostringstream oss;
|
||||||
filename_.stream << ttl_object_id(brep_obj, postfix.c_str()) << " a geo:Geometry ;\n";
|
|
||||||
filename_.stream << " geo:asWKT " << escape_for_turtle(
|
oss << ttl_object_id(brep_obj) << " geo:hasGeometry " << ttl_object_id(brep_obj, postfix.c_str()) << " .\n\n";
|
||||||
IfcUtil::convert_utf8(
|
oss << ttl_object_id(brep_obj, postfix.c_str()) << " a geo:Geometry ;\n";
|
||||||
capture_output(
|
oss << " geo:asWKT " << escape_for_turtle(IfcUtil::convert_utf8(capture_output(emit_line_component, loop_coords, loop_idxs, true, POLYGON))) << "^^geo:wktLiteral .\n\n";
|
||||||
emit_line_component,
|
|
||||||
loop_coords,
|
polygons_by_area[area] = oss.str();
|
||||||
loop_idxs,
|
|
||||||
true,
|
|
||||||
POLYGON))
|
|
||||||
) << "^^geo:wktLiteral .\n\n";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (polygons_by_area.size() > 0) {
|
||||||
|
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) + ").");
|
||||||
|
}
|
||||||
|
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.");
|
||||||
|
emitted_warning = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (polygons_by_area.size() > 0) {
|
||||||
|
// Emit polygon with largest area
|
||||||
|
auto it = polygons_by_area.rbegin();
|
||||||
|
filename_.stream << it->second;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user