diff --git a/src/ifcgeom/kernels/opencascade/IfcGeomTree.h b/src/ifcgeom/kernels/opencascade/IfcGeomTree.h index 8aed46f5bc..46e0f06731 100644 --- a/src/ifcgeom/kernels/opencascade/IfcGeomTree.h +++ b/src/ifcgeom/kernels/opencascade/IfcGeomTree.h @@ -1863,23 +1863,36 @@ namespace IfcGeom { candidates.push_back({ std::abs(Z.Dot(ref)), ref }); } - if (candidates.empty()) { - { - gp_XYZ ref(0, 0, 1); - candidates.push_back({ std::abs(Z.Dot(ref)), ref }); + gp_Ax3 ax3; + gp_Trsf trsf2; + + for (size_t attempt = 0; attempt < 2; ++attempt) { + + if (candidates.empty() || attempt == 1) { + { + gp_XYZ ref(0, 0, 1); + candidates.push_back({std::abs(Z.Dot(ref)), ref}); + } + { + gp_XYZ ref(1, 0, 0); + candidates.push_back({std::abs(Z.Dot(ref)), ref}); + } } + + auto X = std::min_element(candidates.begin(), candidates.end(), [](auto& p1, auto& p2) { return p1.first < p2.first; })->second; + { - gp_XYZ ref(1, 0, 0); - candidates.push_back({ std::abs(Z.Dot(ref)), ref }); + try { + ax3 = gp_Ax3(gp::Origin(), Z, X); + trsf2.SetTransformation(gp::XOY(), ax3); + } catch (Standard_ConstructionError&) { + // Try again, likely we have all identical normals in candidates so + // we cannot find a suitable candidate and need the two default axes + continue; + } } } - auto X = std::min_element(candidates.begin(), candidates.end(), [](auto& p1, auto& p2) { return p1.first < p2.first; })->second; - - gp_Trsf trsf2; - gp_Ax3 ax3(gp::Origin(), Z, X); - trsf2.SetTransformation(gp::XOY(), ax3); - Bnd_Box tmp; for (auto& p : vs_transformed) {