Skip to content

Commit

Permalink
Part.Area: fixed sortWires3D
Browse files Browse the repository at this point in the history
  • Loading branch information
realthunder committed Jan 31, 2017
1 parent a6380f6 commit 6f862fe
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 25 deletions.
90 changes: 68 additions & 22 deletions src/Mod/Path/App/Area.cpp
Expand Up @@ -729,7 +729,10 @@ void Area::build() {
return;
}

#ifdef AREA_TRACE_ENABLE
TIME_INIT(t);
#endif

getPlane();

try {
Expand Down Expand Up @@ -806,7 +809,7 @@ void Area::build() {
myArea = std::move(area.myArea);
}

TIME_PRINT(t,"prepare");
TIME_TRACE(t,"prepare");

}catch(...) {
clean();
Expand Down Expand Up @@ -1283,7 +1286,7 @@ TopoDS_Shape Area::toShape(const CArea &area, bool fill, const gp_Trsf *trsf) {
}

struct WireInfo {
TopoDS_Shape wire;
TopoDS_Wire wire;
gp_Pnt pend;
gp_Pnt pstart;
};
Expand All @@ -1296,15 +1299,14 @@ struct GetWires {
void operator()(const TopoDS_Shape &shape, int type) {
WireInfo info;
if(type == TopAbs_WIRE)
info.wire = shape;
info.wire = TopoDS::Wire(shape);
else
info.wire = BRepBuilderAPI_MakeWire(TopoDS::Edge(shape)).Wire();

BRepTools_WireExplorer xp(TopoDS::Wire(shape));
BRepTools_WireExplorer xp(info.wire);
info.pstart = BRep_Tool::Pnt(xp.CurrentVertex());
for(;xp.More();xp.Next());
info.pend = BRep_Tool::Pnt(xp.CurrentVertex());
info.wire = shape;
wires.push_back(info);
}
};
Expand Down Expand Up @@ -1349,18 +1351,16 @@ struct ShapeInfo{
BRepExtrema_DistShapeShape extss(v,wire);
if(extss.IsDone() && extss.NbSolution()) {
d = extss.Value();
p = extss.PointOnShape2(0);
support = extss.SupportOnShape2(0);
support_edge = extss.SupportTypeShape2(0)==BRepExtrema_IsOnEdge;
p = extss.PointOnShape2(1);
support = extss.SupportOnShape2(1);
support_edge = extss.SupportTypeShape2(1)==BRepExtrema_IsOnEdge;
done = true;
}else
AREA_WARN("BRepExtrema_DistShapeShape failed");
}
if(!done){
double d1 = p.Distance(it->pstart);
double d2 = p.Distance(it->pend);
AREA_TRACE("start "<<AREA_PT(it->pstart)<<", " << d1 <<
AREA_PT(it->pend)<<", " <<d2);
double d1 = pt.Distance(it->pstart);
double d2 = pt.Distance(it->pend);
if(d1<d2) {
d = d1;
p = it->pstart;
Expand Down Expand Up @@ -1388,24 +1388,31 @@ struct ShapeInfo{

//Assumes nearest() has been called. Rebased the best wire
//to begin with the best point. Currently only works with closed wire
TopoDS_Shape rebaseWire(gp_Pnt &pend) {
TopoDS_Shape rebaseWire(gp_Pnt &pend, double min_dist) {
AREA_TRACE("rebase wire");
BRepBuilderAPI_MakeWire mkWire;
TopoDS_Shape estart;
TopoDS_Edge eend;

if(min_dist < Precision::Confusion())
min_dist = Precision::Confusion();

for(int state=0;state<3;++state) {
BRepTools_WireExplorer xp(TopoDS::Wire(myBestWire->wire));
pend = BRep_Tool::Pnt(xp.CurrentVertex());

//checking the case of bestpoint == wire start
if(state==0 && !mySupportEdge && pend.Distance(myBestPt)<Precision::Confusion()) {
AREA_TRACE("keep start");
pend = myBestWire->pend;
return myBestWire->wire;
}

gp_Pnt pt;
for(;xp.More();xp.Next(),pend=pt) {
//state==2 means we are in second pass. estart marks the new start of the wire
if(state==2 && estart.IsSame(xp.Current()))
//state==2 means we are in second pass. estart marks the new start of the wire.
//so seeing estart means we're done
if(state==2 && estart.IsEqual(xp.Current()))
break;

BRepAdaptor_Curve curve(xp.Current());
Expand All @@ -1421,12 +1428,50 @@ struct ShapeInfo{
if(mySupportEdge) {
//if best point is on some edge, break the edge in half
if(xp.Current().IsEqual(mySupport)) {
estart = mySupport;
state = 1;
eend = BRepBuilderAPI_MakeEdge(curve.Curve().Curve(), pend, myBestPt);
mkWire.Add(BRepBuilderAPI_MakeEdge(curve.Curve().Curve(), myBestPt, pt));
double d1 = pend.Distance(myBestPt);
double d2 = pt.Distance(myBestPt);

if(d1>min_dist && d2>min_dist) {
BRepBuilderAPI_MakeEdge mkEdge1,mkEdge2;
if(reversed) {
mkEdge1.Init(curve.Curve().Curve(), myBestPt, myBestPt);
mkEdge2.Init(curve.Curve().Curve(), pt, myBestPt);
}else{
mkEdge1.Init(curve.Curve().Curve(), pend, myBestPt);
mkEdge2.Init(curve.Curve().Curve(), myBestPt, pt);
}
if(mkEdge1.IsDone() && mkEdge2.IsDone()) {
if(reversed) {
eend = TopoDS::Edge(mkEdge1.Edge().Reversed());
mkWire.Add(TopoDS::Edge(mkEdge2.Edge().Reversed()));
}else{
eend = mkEdge1.Edge();
mkWire.Add(mkEdge2.Edge());
}
estart = mySupport;
state = 1;
AREA_TRACE("edge broken "<<AREA_PT(pend)<<", " << AREA_PT(myBestPt)
<< ", " << AREA_PT(pt) << ", " << d1 << ", " << d2);
continue;
}
AREA_WARN("edge break failed "<<AREA_PT(pend)<<", " << AREA_PT(myBestPt)
<< ", " << AREA_PT(pt) << ", " << d1 << ", " << d2);
}

if(d1<d2) {
AREA_TRACE("break edge->start");
estart = xp.Current();
state = 1;
mkWire.Add(xp.Current());
}else{
AREA_TRACE("break edge->end");
mySupportEdge = false;
myBestPt = pt;
continue;
}
}
}else if(myBestPt.Distance(pend)<Precision::Confusion()){
AREA_TRACE("break vertex");
//if best point is on some vertex
estart = xp.Current();
state = 1;
Expand All @@ -1443,13 +1488,14 @@ struct ShapeInfo{
return myBestWire->wire;
}

std::list<TopoDS_Shape> sortWires(gp_Pnt &pend) {
std::list<TopoDS_Shape> sortWires3D(gp_Pnt &pend,double min_dist) {
std::list<TopoDS_Shape> wires;
while(true) {
AREA_TRACE("3D sort pt " << AREA_PT(myBestPt));
if(myRebase) {
AREA_TRACE("3D sort rebase");
wires.push_back(rebaseWire(pend));
pend = myBestPt;
wires.push_back(rebaseWire(pend,min_dist));
}else if(!myStart){
AREA_TRACE("3D sort reverse");
wires.push_back(myBestWire->wire.Reversed());
Expand Down Expand Up @@ -1619,7 +1665,7 @@ std::list<TopoDS_Shape> Area::sortWires(const std::list<TopoDS_Shape> &shapes,
0,-1,&pstart,&pend, PARAM_FIELDS(PARAM_FARG,AREA_PARAMS_SORT)));
AREA_TIME_2D5;
}else{
wires.splice(wires.end(),best_it->sortWires(pend));
wires.splice(wires.end(),best_it->sortWires3D(pend,min_dist));
AREA_TIME_3D;
}
pstart = pend;
Expand Down
11 changes: 8 additions & 3 deletions src/Mod/Path/App/Area.h
Expand Up @@ -51,7 +51,7 @@
#define AREA_PT(_pt) '('<<(_pt).X()<<", " << (_pt).Y()<<", " << (_pt).Z()<<')'
#define AREA_PT2(_pt) '('<<(_pt).x<<", " << (_pt).y<<')'
#ifdef AREA_TRACE_ENABLE
# define AREA_TRACE AREA_LOG
# define AREA_TRACE(_msg) AREA_LOG('('<<__LINE__<<"): " <<_msg)
#else
# define AREA_TRACE(...) do{}while(0)
#endif
Expand All @@ -69,12 +69,17 @@
#define TIME_INIT2(_t1,_t2) TIME_INIT(_t1),_t2=_t1
#define TIME_INIT3(_t1,_t2,_t3) TIME_INIT(_t1),_t2=_t1,_t3=_t1

#define DURATION_PRINT(_d,_msg) \
AREA_LOG(_msg<< " time: " << _d.count()<<'s');
#define _DURATION_PRINT(_l,_d,_msg) \
AREA_##_l(_msg<< " time: " << _d.count()<<'s');

#define DURATION_PRINT(_d,_msg) _DURATION_PRINT(LOG,_d,_msg)

#define TIME_PRINT(_t,_msg) \
DURATION_PRINT(Path::getDuration(_t),_msg);

#define TIME_TRACE(_t,_msg) \
_DURATION_PRINT(TRACE,Path::getDuration(_t),_msg);

#define DURATION_INIT(_d) \
std::chrono::TIME_UNIT _d(0)

Expand Down

0 comments on commit 6f862fe

Please sign in to comment.