Move print() to header, distinguish properly between curve_sense and edge orientation, unwrap trimmed curves as edge bases, don't mutated cached edge in oriented edge processing, etc. #4895

This commit is contained in:
Thomas Krijnen
2024-06-24 21:56:27 +02:00
parent 278524ee3e
commit 8da68f599b
9 changed files with 189 additions and 111 deletions
+4 -1
View File
@@ -650,7 +650,7 @@ bool CgalKernel::convert(const taxonomy::loop::ptr loop, cgal_wire_t& result) {
std::vector<taxonomy::point3> edge;
if (e->basis) {
convert_curve(settings_, e, edge);
if (!e->orientation_2.get_value_or(true)) {
if (!e->curve_sense.get_value_or(true)) {
std::reverse(edge.begin(), edge.end());
}
} else {
@@ -659,6 +659,9 @@ bool CgalKernel::convert(const taxonomy::loop::ptr loop, cgal_wire_t& result) {
*boost::get<taxonomy::point3::ptr>(e->end)
};
}
if (!e->orientation.get_value_or(true)) {
std::reverse(edge.begin(), edge.end());
}
extend_wire(points, edge);
}
+7
View File
@@ -49,6 +49,13 @@ using namespace IfcGeom;
using namespace IfcGeom::util;
bool OpenCascadeKernel::convert(const taxonomy::face::ptr face, TopoDS_Shape& result) {
#ifdef IFOPSH_DEBUG
std::ostringstream oss;
face->print(oss);
auto osss = oss.str();
std::wcout << osss.c_str() << std::endl;
#endif
face_definition fd;
const bool is_face_surface = false; /* todo */
@@ -155,7 +155,6 @@ IfcGeom::OpenCascadeKernel::faceset_helper::faceset_helper(
if (edge_sets.find(segment_set) != edge_sets.end()) {
duplicate_faces++;
// @todo does this work with tesselated face sets, will they have an associated instance? Guess not.
duplicates_.insert(loop->identity());
continue;
}
@@ -203,6 +202,9 @@ void IfcGeom::OpenCascadeKernel::faceset_helper::loop_(const ifcopenshell::geome
auto B = boost::get<ifcopenshell::geometry::taxonomy::point3::ptr>(b->start)->identity();
auto C = vertex_mapping_[A], D = vertex_mapping_[B];
bool fwd = C < D;
if (!b->orientation) {
fwd = !fwd;
}
if (!fwd) {
std::swap(C, D);
}
+27 -13
View File
@@ -110,8 +110,14 @@ namespace {
}
TopoDS_Edge E;
if (e->basis) {
auto crv_or_wire = convert_curve(kernel, e->basis);
auto e_basis = e->basis;
if (e_basis) {
while (e_basis->kind() == taxonomy::EDGE && e_basis->instance && e_basis->instance->declaration().name() == "IfcTrimmedCurve") {
// @todo we still might have something to wrt orientation on periodic curves
// to make sure we select the correct arc later on.
e_basis = taxonomy::cast<taxonomy::edge>(e_basis)->basis;
}
auto crv_or_wire = convert_curve(kernel, e_basis);
Handle(Geom_Curve) curve;
if (crv_or_wire.which() == 0) {
curve = boost::get<Handle(Geom_Curve)>(crv_or_wire);
@@ -131,27 +137,23 @@ namespace {
curve = approx.Curve();
}
const bool reversed = !taxonomy::cast<taxonomy::geom_item>(e->basis)->orientation.get_value_or(true);
const bool is_conic = e->basis->kind() == taxonomy::ELLIPSE || e->basis->kind() == taxonomy::CIRCLE;
const bool reversed = !e->orientation.get_value_or(true);
const bool is_conic = e_basis->kind() == taxonomy::ELLIPSE || e_basis->kind() == taxonomy::CIRCLE;
if (!e->curve_sense) {
curve->Reverse();
}
// @todo, copy over logic from previous IfcTrimmedCurve handling
if (e->start.which() == 0) {
auto p1 = OpenCascadeKernel::convert_xyz<gp_Pnt>(*boost::get<taxonomy::point3::ptr>(e->start));
auto p2 = OpenCascadeKernel::convert_xyz<gp_Pnt>(*boost::get<taxonomy::point3::ptr>(e->end));
if (reversed) {
std::swap(p1, p2);
}
E = BRepBuilderAPI_MakeEdge(curve, p1, p2).Edge();
} else {
auto v1 = boost::get<double>(e->start);
auto v2 = boost::get<double>(e->end);
if (reversed) {
std::swap(v1, v2);
}
if (is_conic && ALMOST_THE_SAME(fmod(v2 - v1, M_PI*2.), 0.)) {
E = BRepBuilderAPI_MakeEdge(curve).Edge();
} else {
@@ -171,6 +173,18 @@ namespace {
E = BRepBuilderAPI_MakeEdge(p1, p2).Edge();
}
#ifdef IFOPSH_DEBUG
std::ostringstream oss;
e->print(oss);
TopoDS_Vertex v0, v1;
TopExp::Vertices(E, v0, v1, true);
BRep_Tool::Pnt(v0).DumpJson(oss);
BRep_Tool::Pnt(v1).DumpJson(oss);
auto osss = oss.str();
std::wcout << osss.c_str() << std::endl;
#endif
BRep_Builder B;
TopoDS_Wire W;
B.MakeWire(W);
@@ -221,7 +235,7 @@ bool OpenCascadeKernel::convert(const taxonomy::loop::ptr loop, TopoDS_Wire& wir
std::wcout << o_str.c_str() << std::endl;
#endif
if (!segment->orientation_2.get_value_or(true)) {
if (!segment->curve_sense.get_value_or(true)) {
segment_wire.Reverse();
}