mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-26 18:21:59 +00:00
Some fixes to make sure that non-planar faces get explicitly triangulated
This commit is contained in:
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user