diff --git a/src/ifcgeom/kernels/cgal/CgalKernel.cpp b/src/ifcgeom/kernels/cgal/CgalKernel.cpp index f3e5342309..f07cc0affa 100644 --- a/src/ifcgeom/kernels/cgal/CgalKernel.cpp +++ b/src/ifcgeom/kernels/cgal/CgalKernel.cpp @@ -324,6 +324,11 @@ namespace { } else { std::tie(a, b) = param; } + a = std::fmod(a, 2 * M_PI); + b = std::fmod(b, 2 * M_PI); + if (b < a) { + b += 2 * M_PI; + } int num_segments = (int)std::ceil(std::fabs(a - b) / (2 * M_PI) * FULL_CIRCLE_NUM_SEGMENTS); double du = (b - a) / num_segments; taxonomy::point3 P; @@ -352,6 +357,10 @@ namespace { boost::apply_visitor(v1, e.start); boost::apply_visitor(v2, e.end); + if (!e.orientation.get_value_or(true)) { + std::swap(v1.u, v2.u); + } + cgal_curve_creation_visitor v({ v1.u, v2.u }); dispatch_curve_creation::dispatch(e.basis, v); @@ -392,7 +401,10 @@ bool CgalKernel::convert(const taxonomy::loop* loop, cgal_wire_t& result) { for (auto& e : edges) { if (e->basis) { std::vector edge; - convert_curve(e->basis, points); + convert_curve(e, edge); + if (!e->orientation_2.get_value_or(true)) { + std::reverse(edge.begin(), edge.end()); + } extend_wire(points, edge); } else { extend_wire(points, { diff --git a/src/ifcgeom/kernels/opencascade/IfcGeomShapes.cpp b/src/ifcgeom/kernels/opencascade/IfcGeomShapes.cpp index ce6e606e2c..00505beb23 100644 --- a/src/ifcgeom/kernels/opencascade/IfcGeomShapes.cpp +++ b/src/ifcgeom/kernels/opencascade/IfcGeomShapes.cpp @@ -862,7 +862,7 @@ bool OpenCascadeKernel::convert(const taxonomy::loop* loop, TopoDS_Wire& wire) { std::wcout << o_str.c_str() << std::endl; #endif - if (!segment->orientation) { + if (!segment->orientation_2.get_value_or(true)) { segment_wire.Reverse(); } diff --git a/src/ifcgeom/schema/mapping.cpp b/src/ifcgeom/schema/mapping.cpp index 046bb399ec..a7e436a315 100644 --- a/src/ifcgeom/schema/mapping.cpp +++ b/src/ifcgeom/schema/mapping.cpp @@ -1325,7 +1325,7 @@ namespace { *c->matrix.components = Eigen::Affine3d(Eigen::Translation3d(O)).matrix(); c->radius = *p.radius; e->basis = c; - c->orientation = sign == -1.; + c->orientation.reset(sign == -1.); loop->children.insert(std::find(loop->children.begin(), loop->children.end(), p.next), e); } @@ -1612,7 +1612,7 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcCompositeCurve* inst) { auto crv = map(segment->ParentCurve()); if (crv) { if (crv->kind() == taxonomy::EDGE) { - ((taxonomy::geom_item*)crv)->orientation = segment->SameSense(); + ((taxonomy::edge*)crv)->orientation_2.reset(segment->SameSense()); loop->children.push_back(crv); } else if (crv->kind() == taxonomy::LOOP) { if (!segment->SameSense()) { @@ -1816,7 +1816,7 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcHalfSpaceSolid* inst) { } auto p = new taxonomy::plane; p->matrix = as(map(((IfcSchema::IfcPlane*)surface)->Position())); - p->orientation = !inst->AgreementFlag(); + p->orientation.reset(!inst->AgreementFlag()); auto f = new taxonomy::face; f->basis = p; return f; diff --git a/src/ifcgeom/taxonomy.h b/src/ifcgeom/taxonomy.h index 5c78592078..8ce654980b 100644 --- a/src/ifcgeom/taxonomy.h +++ b/src/ifcgeom/taxonomy.h @@ -251,9 +251,11 @@ struct trimmed_curve : public curve { // @todo somehow account for the fact that curve in IFC can be trimmed curve, polyline and composite curve as well. item* basis; - bool orientation; - trimmed_curve() : basis(nullptr), orientation(true) {} + // @todo does this make sense? this is to accomodate for the fact that orientation is defined on both TrimmedCurve as well CompCurveSegment + boost::optional orientation_2; + + trimmed_curve() : basis(nullptr), orientation_2(true) {} virtual void reverse() { // std::swap(start, end);