Some fixes to make sure that non-planar faces get explicitly triangulated

This commit is contained in:
Thomas Krijnen
2019-04-09 17:03:24 +02:00
parent f0fa9ca736
commit 013b7a763d
3 changed files with 17 additions and 6 deletions
+1 -1
View File
@@ -317,7 +317,7 @@ public:
void remove_collinear_points_from_loop(TColgp_SequenceOfPnt& polygon, bool closed, double tol=-1.); void remove_collinear_points_from_loop(TColgp_SequenceOfPnt& polygon, bool closed, double tol=-1.);
bool wire_to_sequence_of_point(const TopoDS_Wire&, TColgp_SequenceOfPnt&); bool wire_to_sequence_of_point(const TopoDS_Wire&, TColgp_SequenceOfPnt&);
void sequence_of_point_to_wire(const TColgp_SequenceOfPnt&, TopoDS_Wire&, bool closed); void sequence_of_point_to_wire(const TColgp_SequenceOfPnt&, TopoDS_Wire&, bool closed);
bool approximate_plane_through_wire(const TopoDS_Wire&, gp_Pln&); bool approximate_plane_through_wire(const TopoDS_Wire&, gp_Pln&, double eps=-1.);
bool flatten_wire(TopoDS_Wire&); bool flatten_wire(TopoDS_Wire&);
bool triangulate_wire(const TopoDS_Wire&, TopTools_ListOfShape&); bool triangulate_wire(const TopoDS_Wire&, TopTools_ListOfShape&);
bool wire_intersections(const TopoDS_Wire & wire, TopTools_ListOfShape & wires); bool wire_intersections(const TopoDS_Wire & wire, TopTools_ListOfShape & wires);
-2
View File
@@ -199,8 +199,6 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcFace* l, TopoDS_Shape& face) {
for (; exp.More(); exp.Next(), count++) { for (; exp.More(); exp.Next(), count++) {
if (count < 2) { if (count < 2) {
edges[count] = TopoDS::Edge(exp.Current()); edges[count] = TopoDS::Edge(exp.Current());
} else {
break;
} }
} }
+16 -3
View File
@@ -3077,12 +3077,15 @@ bool IfcGeom::Kernel::is_identity_transform(IfcUtil::IfcBaseClass* l) {
} }
} }
bool IfcGeom::Kernel::approximate_plane_through_wire(const TopoDS_Wire& wire, gp_Pln& plane) { bool IfcGeom::Kernel::approximate_plane_through_wire(const TopoDS_Wire& wire, gp_Pln& plane, double eps) {
// Newell's Method is used for the normal calculation // Newell's Method is used for the normal calculation
// as a simple edge cross product can give opposite results // as a simple edge cross product can give opposite results
// for a concave face boundary. // for a concave face boundary.
// Reference: Graphics Gems III p. 231 // Reference: Graphics Gems III p. 231
const double eps_ = eps < 1. ? getValue(GV_PRECISION) : eps;
const double eps2 = eps_ * eps_;
double x = 0, y = 0, z = 0; double x = 0, y = 0, z = 0;
gp_Pnt current, previous, first; gp_Pnt current, previous, first;
gp_XYZ center; gp_XYZ center;
@@ -3122,8 +3125,18 @@ bool IfcGeom::Kernel::approximate_plane_through_wire(const TopoDS_Wire& wire, gp
if (n < 3) { if (n < 3) {
return false; return false;
} }
plane = gp_Pln(center / n, gp_Dir(x, y, z)); plane = gp_Pln(center / n, gp_Dir(x, y, z));
exp.Init(wire);
for (; exp.More(); exp.Next()) {
const TopoDS_Vertex& v = exp.CurrentVertex();
current = BRep_Tool::Pnt(v);
if (plane.SquareDistance(current) > eps2) {
return false;
}
}
return true; return true;
} }
@@ -3161,7 +3174,7 @@ bool IfcGeom::Kernel::triangulate_wire(const TopoDS_Wire& wire, TopTools_ListOfS
typedef std::pair<double, double> uv_node; typedef std::pair<double, double> uv_node;
gp_Pln pln; gp_Pln pln;
if (!approximate_plane_through_wire(wire, pln)) { if (!approximate_plane_through_wire(wire, pln, std::numeric_limits<double>::infinity())) {
return false; return false;
} }