Path.Area: fix self intersect wire issue
Self intersected wire may cause a loop, and BRepBuilderAPI_MakeWire may mistakenly consider the wire to be closed. And this makes BrepTools_WireExplorer unhappy and cause it to skip edges. We now use ShapeAnalysis_FreeBounds to connect edges to wires.
This commit is contained in:
committed by
Yorik van Havre
parent
6720be82bf
commit
ff21f64385
@@ -81,6 +81,7 @@
|
||||
#include <ShapeFix_ShapeTolerance.hxx>
|
||||
#include <ShapeExtend_WireData.hxx>
|
||||
#include <ShapeFix_Wire.hxx>
|
||||
#include <ShapeAnalysis_FreeBounds.hxx>
|
||||
|
||||
#include <Base/Exception.h>
|
||||
#include <Base/Tools.h>
|
||||
@@ -1610,7 +1611,7 @@ void Area::build() {
|
||||
WireJoiner joiner;
|
||||
gp_Trsf trsf(myTrsf.Inverted());
|
||||
for(const auto &c : myArea->m_curves) {
|
||||
TopoDS_Wire wire = toShape(c,&trsf);
|
||||
auto wire = toShape(c,&trsf);
|
||||
if(!wire.IsNull())
|
||||
joiner.add(wire);
|
||||
}
|
||||
@@ -2045,8 +2046,9 @@ static inline bool IsLeft(const gp_Pnt &a, const gp_Pnt &b, const gp_Pnt &c) {
|
||||
return ((b.X() - a.X())*(c.Y() - a.Y()) - (b.Y() - a.Y())*(c.X() - a.X())) > 0;
|
||||
}
|
||||
|
||||
TopoDS_Wire Area::toShape(const CCurve &_c, const gp_Trsf *trsf, int reorient) {
|
||||
BRepBuilderAPI_MakeWire mkWire;
|
||||
TopoDS_Shape Area::toShape(const CCurve &_c, const gp_Trsf *trsf, int reorient) {
|
||||
Handle(TopTools_HSequenceOfShape) hEdges = new TopTools_HSequenceOfShape();
|
||||
Handle(TopTools_HSequenceOfShape) hWires = new TopTools_HSequenceOfShape();
|
||||
|
||||
CCurve cReversed;
|
||||
if(reorient) {
|
||||
@@ -2061,6 +2063,7 @@ TopoDS_Wire Area::toShape(const CCurve &_c, const gp_Trsf *trsf, int reorient) {
|
||||
}
|
||||
const CCurve &c = reorient?cReversed:_c;
|
||||
|
||||
TopoDS_Shape shape;
|
||||
gp_Pnt pstart,pt;
|
||||
bool first = true;
|
||||
for(const CVertex &v : c.m_vertices){
|
||||
@@ -2074,7 +2077,7 @@ TopoDS_Wire Area::toShape(const CCurve &_c, const gp_Trsf *trsf, int reorient) {
|
||||
continue;
|
||||
if(v.m_type == 0) {
|
||||
auto edge = BRepBuilderAPI_MakeEdge(pt,pnext).Edge();
|
||||
mkWire.Add(edge);
|
||||
hEdges->Append(edge);
|
||||
} else {
|
||||
gp_Pnt center(v.m_c.x,v.m_c.y,0);
|
||||
double r = center.Distance(pt);
|
||||
@@ -2102,7 +2105,7 @@ TopoDS_Wire Area::toShape(const CCurve &_c, const gp_Trsf *trsf, int reorient) {
|
||||
gp_Ax2 axis(center, gp_Dir(0,0,v.m_type));
|
||||
try {
|
||||
auto edge = BRepBuilderAPI_MakeEdge(gp_Circ(axis,r),pt,pnext).Edge();
|
||||
mkWire.Add(edge);
|
||||
hEdges->Append(edge);
|
||||
break;
|
||||
} catch(Standard_Failure &e) {
|
||||
if(!fix_arc) {
|
||||
@@ -2117,11 +2120,8 @@ TopoDS_Wire Area::toShape(const CCurve &_c, const gp_Trsf *trsf, int reorient) {
|
||||
}
|
||||
pt = pnext;
|
||||
}
|
||||
if(!mkWire.IsDone()) {
|
||||
AREA_WARN("failed to make wire " << mkWire.Error());
|
||||
return TopoDS_Wire();
|
||||
}
|
||||
|
||||
#if 0
|
||||
if(c.IsClosed() && !BRep_Tool::IsClosed(mkWire.Wire())){
|
||||
// This should never happen after changing libarea's
|
||||
// Point::tolerance to be the same as Precision::Confusion().
|
||||
@@ -2134,10 +2134,26 @@ TopoDS_Wire Area::toShape(const CCurve &_c, const gp_Trsf *trsf, int reorient) {
|
||||
AREA_XYZ(p2)<<endl<<AREA_XYZ(pt)<<endl<<AREA_XYZ(pstart));
|
||||
mkWire.Add(BRepBuilderAPI_MakeEdge(pt,pstart).Edge());
|
||||
}
|
||||
#endif
|
||||
|
||||
ShapeAnalysis_FreeBounds::ConnectEdgesToWires(
|
||||
hEdges, Precision::Confusion(), Standard_False, hWires);
|
||||
if(!hWires->Length())
|
||||
return shape;
|
||||
if(hWires->Length()==1)
|
||||
shape = hWires->Value(1);
|
||||
else {
|
||||
BRep_Builder builder;
|
||||
TopoDS_Compound compound;
|
||||
builder.MakeCompound(compound);
|
||||
for(int i=1;i<=hWires->Length();++i)
|
||||
builder.Add(compound,hWires->Value(i));
|
||||
shape = compound;
|
||||
}
|
||||
|
||||
if(trsf)
|
||||
return TopoDS::Wire(mkWire.Wire().Moved(TopLoc_Location(*trsf)));
|
||||
else
|
||||
return mkWire.Wire();
|
||||
shape.Move(TopLoc_Location(*trsf));
|
||||
return shape;
|
||||
}
|
||||
|
||||
TopoDS_Shape Area::toShape(const CArea &area, bool fill, const gp_Trsf *trsf, int reorient) {
|
||||
@@ -2146,7 +2162,7 @@ TopoDS_Shape Area::toShape(const CArea &area, bool fill, const gp_Trsf *trsf, in
|
||||
builder.MakeCompound(compound);
|
||||
|
||||
for(const CCurve &c : area.m_curves) {
|
||||
const TopoDS_Wire &wire = toShape(c,trsf,reorient);
|
||||
const auto &wire = toShape(c,trsf,reorient);
|
||||
if(!wire.IsNull())
|
||||
builder.Add(compound,wire);
|
||||
}
|
||||
|
||||
@@ -329,7 +329,7 @@ public:
|
||||
* \arg \c trsf: optional transform matrix to transform the shape back into
|
||||
* its original position.
|
||||
* */
|
||||
static TopoDS_Wire toShape(const CCurve &curve, const gp_Trsf *trsf=NULL, int reorient=0);
|
||||
static TopoDS_Shape toShape(const CCurve &curve, const gp_Trsf *trsf=NULL, int reorient=0);
|
||||
|
||||
/** Check if two OCC shape is coplanar */
|
||||
static bool isCoplanar(const TopoDS_Shape &s1, const TopoDS_Shape &s2);
|
||||
|
||||
Reference in New Issue
Block a user