Skip to content

Commit

Permalink
Merge pull request #413 from realthunder/sortEdges
Browse files Browse the repository at this point in the history
Add C++ implementation of Part.sortEdges
  • Loading branch information
wwmayer committed Jan 4, 2017
2 parents 109f869 + d585499 commit 6dff7f1
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 4 deletions.
4 changes: 3 additions & 1 deletion src/Mod/Draft/DraftGeomUtils.py
Expand Up @@ -870,8 +870,10 @@ def flattenWire(wire):
w = Part.makePolygon(verts)
return w


def findWires(edgeslist):
return [ Part.Wire(e) for e in Part.sortEdges(edgeslist)]

def findWiresOld2(edgeslist):
'''finds connected wires in the given list of edges'''

def touches(e1,e2):
Expand Down
51 changes: 48 additions & 3 deletions src/Mod/Part/App/AppPartPy.cpp
Expand Up @@ -143,20 +143,22 @@ extern const char* BRepBuilderAPI_FaceErrorText(BRepBuilderAPI_FaceError fe);
namespace Part {
struct EdgePoints {
gp_Pnt v1, v2;
std::list<TopoDS_Edge>::iterator it;
TopoDS_Edge edge;
};

static std::list<TopoDS_Edge> sort_Edges(double tol3d, const std::vector<TopoDS_Edge>& edges)
static std::list<TopoDS_Edge> sort_Edges(double tol3d, std::list<TopoDS_Edge>& edges)
{
tol3d = tol3d * tol3d;
std::list<EdgePoints> edge_points;
TopExp_Explorer xp;
for (std::vector<TopoDS_Edge>::const_iterator it = edges.begin(); it != edges.end(); ++it) {
for (std::list<TopoDS_Edge>::iterator it = edges.begin(); it != edges.end(); ++it) {
EdgePoints ep;
xp.Init(*it,TopAbs_VERTEX);
ep.v1 = BRep_Tool::Pnt(TopoDS::Vertex(xp.Current()));
xp.Next();
ep.v2 = BRep_Tool::Pnt(TopoDS::Vertex(xp.Current()));
ep.it = it;
ep.edge = *it;
edge_points.push_back(ep);
}
Expand All @@ -170,6 +172,7 @@ static std::list<TopoDS_Edge> sort_Edges(double tol3d, const std::vector<TopoDS_
last = edge_points.front().v2;

sorted.push_back(edge_points.front().edge);
edges.erase(edge_points.front().it);
edge_points.erase(edge_points.begin());

while (!edge_points.empty()) {
Expand All @@ -179,13 +182,15 @@ static std::list<TopoDS_Edge> sort_Edges(double tol3d, const std::vector<TopoDS_
if (pEI->v1.SquareDistance(last) <= tol3d) {
last = pEI->v2;
sorted.push_back(pEI->edge);
edges.erase(pEI->it);
edge_points.erase(pEI);
pEI = edge_points.begin();
break;
}
else if (pEI->v2.SquareDistance(first) <= tol3d) {
first = pEI->v1;
sorted.push_front(pEI->edge);
edges.erase(pEI->it);
edge_points.erase(pEI);
pEI = edge_points.begin();
break;
Expand All @@ -198,6 +203,7 @@ static std::list<TopoDS_Edge> sort_Edges(double tol3d, const std::vector<TopoDS_
last = curve->ReversedParameter(last);
TopoDS_Edge edgeReversed = BRepBuilderAPI_MakeEdge(curve->Reversed(), last, first);
sorted.push_back(edgeReversed);
edges.erase(pEI->it);
edge_points.erase(pEI);
pEI = edge_points.begin();
break;
Expand All @@ -210,6 +216,7 @@ static std::list<TopoDS_Edge> sort_Edges(double tol3d, const std::vector<TopoDS_
last = curve->ReversedParameter(last);
TopoDS_Edge edgeReversed = BRepBuilderAPI_MakeEdge(curve->Reversed(), last, first);
sorted.push_front(edgeReversed);
edges.erase(pEI->it);
edge_points.erase(pEI);
pEI = edge_points.begin();
break;
Expand Down Expand Up @@ -357,6 +364,9 @@ class Module : public Py::ExtensionModule<Module>
"__sortEdges__(list of edges) -- Helper method to sort an unsorted list of edges so that afterwards\n"
"two adjacent edges share a common vertex"
);
add_varargs_method("sortEdges",&Module::sortEdges2,
"sortEdges(list of edges) -- Helper method to sort a list of edges into a list of list of connected edges"
);
add_varargs_method("__toPythonOCC__",&Module::toPythonOCC,
"__toPythonOCC__(shape) -- Helper method to convert an internal shape to pythonocc shape"
);
Expand Down Expand Up @@ -1742,7 +1752,7 @@ class Module : public Py::ExtensionModule<Module>
}

Py::Sequence list(obj);
std::vector<TopoDS_Edge> edges;
std::list<TopoDS_Edge> edges;
for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
PyObject* item = (*it).ptr();
if (PyObject_TypeCheck(item, &(Part::TopoShapePy::Type))) {
Expand All @@ -1766,6 +1776,41 @@ class Module : public Py::ExtensionModule<Module>

return sorted_list;
}
Py::Object sortEdges2(const Py::Tuple& args)
{
PyObject *obj;
if (!PyArg_ParseTuple(args.ptr(), "O", &obj)) {
throw Py::Exception(PartExceptionOCCError, "list of edges expected");
}

Py::Sequence list(obj);
std::list<TopoDS_Edge> edges;
for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) {
PyObject* item = (*it).ptr();
if (PyObject_TypeCheck(item, &(Part::TopoShapePy::Type))) {
const TopoDS_Shape& sh = static_cast<Part::TopoShapePy*>(item)->getTopoShapePtr()->getShape();
if (sh.ShapeType() == TopAbs_EDGE)
edges.push_back(TopoDS::Edge(sh));
else {
throw Py::TypeError("shape is not an edge");
}
}
else {
throw Py::TypeError("item is not a shape");
}
}

Py::List root_list;
while(edges.size()) {
std::list<TopoDS_Edge> sorted = sort_Edges(Precision::Confusion(), edges);
Py::List sorted_list;
for (std::list<TopoDS_Edge>::iterator it = sorted.begin(); it != sorted.end(); ++it) {
sorted_list.append(Py::Object(new TopoShapeEdgePy(new TopoShape(*it)),true));
}
root_list.append(sorted_list);
}
return root_list;
}
Py::Object toPythonOCC(const Py::Tuple& args)
{
PyObject *pcObj;
Expand Down

0 comments on commit 6dff7f1

Please sign in to comment.