diff --git a/src/Mod/Part/App/TopoShapePy.xml b/src/Mod/Part/App/TopoShapePy.xml
index b205e3e76..1a953e2c6 100644
--- a/src/Mod/Part/App/TopoShapePy.xml
+++ b/src/Mod/Part/App/TopoShapePy.xml
@@ -283,7 +283,7 @@ The parameter is a list of shapes.
Checks whether a point is inside or outside a given shape
-
+
Removes redundant edges from the B-REP model
diff --git a/src/Mod/Part/App/modelRefine.cpp b/src/Mod/Part/App/modelRefine.cpp
index a42e11def..0fa258ef7 100644
--- a/src/Mod/Part/App/modelRefine.cpp
+++ b/src/Mod/Part/App/modelRefine.cpp
@@ -32,8 +32,8 @@
#include
#include
#include
+#include
#include
-#include
#include
#include
#include
@@ -42,91 +42,17 @@
#include
#include
#include
-#include
#include
#include
#include
#include
#include
+#include
+#include
#include "modelRefine.h"
using namespace ModelRefine;
-
-
-//this following struct and function was stole from freecad AppPartPy.cpp
-namespace ModelRefine {
-struct EdgePoints {
- gp_Pnt v1, v2;
- TopoDS_Edge edge;
-};
-static std::list sort_Edges(double tol3d, const std::vector& edges)
-{
- tol3d = tol3d * tol3d;
- std::list edge_points;
- TopExp_Explorer xp;
- for (std::vector::const_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.edge = *it;
- edge_points.push_back(ep);
- }
-
- if (edge_points.empty())
- return std::list();
-
- std::list sorted;
- gp_Pnt first, last;
- first = edge_points.front().v1;
- last = edge_points.front().v2;
-
- sorted.push_back(edge_points.front().edge);
- edge_points.erase(edge_points.begin());
-
- while (!edge_points.empty()) {
- // search for adjacent edge
- std::list::iterator pEI;
- for (pEI = edge_points.begin(); pEI != edge_points.end(); ++pEI) {
- if (pEI->v1.SquareDistance(last) <= tol3d) {
- last = pEI->v2;
- sorted.push_back(pEI->edge);
- edge_points.erase(pEI);
- break;
- }
- else if (pEI->v2.SquareDistance(first) <= tol3d) {
- first = pEI->v1;
- sorted.push_front(pEI->edge);
- edge_points.erase(pEI);
- break;
- }
- else if (pEI->v2.SquareDistance(last) <= tol3d) {
- last = pEI->v1;
- sorted.push_back(pEI->edge);
- edge_points.erase(pEI);
- break;
- }
- else if (pEI->v1.SquareDistance(first) <= tol3d) {
- first = pEI->v2;
- sorted.push_front(pEI->edge);
- edge_points.erase(pEI);
- break;
- }
- }
-
- if ((pEI == edge_points.end()) || (last.SquareDistance(first) <= tol3d)) {
- // no adjacent edge found or polyline is closed
- return sorted;
- }
- }
- return sorted;
-}
-}
-//end stolen freecad.
-
-
void ModelRefine::getFaceEdges(const TopoDS_Face &face, EdgeVectorType &edges)
{
TopExp_Explorer it;
@@ -175,79 +101,64 @@ TopoDS_Shell ModelRefine::removeFaces(const TopoDS_Shell &shell, const FaceVecto
return TopoDS::Shell(rebuilder.Apply(shell));
}
+namespace ModelRefine
+{
+ class WireSort
+ {
+ public:
+ bool operator() (const TopoDS_Wire& wire1, const TopoDS_Wire& wire2)
+ {
+ Bnd_Box box1, box2;
+ BRepBndLib::Add(wire1, box1);
+ BRepBndLib::Add(wire2, box2);
+ return box2.SquareExtent() < box1.SquareExtent();
+ }
+ };
+}
+
void BoundaryEdgeSplitter::split(const EdgeVectorType &edgesIn)
{
- buildMap(edgesIn);
- EdgeVectorType::const_iterator workIt;
- for (workIt = edgesIn.begin(); workIt != edgesIn.end(); ++workIt)
+ std::list edges;
+ std::copy(edgesIn.begin(), edgesIn.end(), back_inserter(edges));
+ while(!edges.empty())
{
- TopoDS_Edge current = *workIt;
-
- if (processed.Contains(*workIt))
+ TopoDS_Vertex destination = TopExp::FirstVertex(edges.front(), Standard_True);
+ TopoDS_Vertex lastVertex = TopExp::LastVertex(edges.front(), Standard_True);
+ EdgeVectorType boundary;
+ boundary.push_back(edges.front());
+ edges.pop_front();
+ //single edge closed check.
+ if (destination.IsSame(lastVertex))
+ {
+ groupedEdges.push_back(boundary);
continue;
+ }
- EdgeVectorType temp;
- temp.reserve(edgesIn.size() + 1);
- temp.push_back(current);
- //recursive call
- splitRecursive(temp, edgesIn);
- groupedEdges.push_back(temp);
- }
-}
-
-void BoundaryEdgeSplitter::splitRecursive(EdgeVectorType &tempEdges, const EdgeVectorType &workEdges)
-{
- EdgeVectorType::iterator tempIt;
- EdgeVectorType::const_iterator workIt;
- for (tempIt = tempEdges.begin(); tempIt != tempEdges.end(); ++tempIt)
- {
- for (workIt = workEdges.begin(); workIt != workEdges.end(); ++workIt)
+ bool closedSignal(false);
+ std::list::iterator it;
+ for (it = edges.begin(); it != edges.end();)
{
- if ((*tempIt).IsSame(*workIt))
- continue;
- if (processed.Contains(*workIt))
- continue;
- if (edgeTest(*tempIt, *workIt))
+ TopoDS_Vertex currentVertex = TopExp::FirstVertex(*it, Standard_True);
+ if (lastVertex.IsSame(currentVertex))
{
- tempEdges.push_back(*workIt);
- processed.Add(*workIt);
- splitRecursive(tempEdges, workEdges);
+ boundary.push_back(*it);
+ lastVertex = TopExp::LastVertex(*it, Standard_True);
+ edges.erase(it);
+ it = edges.begin();
+ if (lastVertex.IsSame(destination))
+ {
+ closedSignal = true;
+ break;
+ }
+ continue;
}
+ ++it;
}
+ if (closedSignal)
+ groupedEdges.push_back(boundary);
}
}
-void BoundaryEdgeSplitter::buildMap(const EdgeVectorType &edgesIn)
-{
- EdgeVectorType::const_iterator vit;
- for (vit = edgesIn.begin(); vit != edgesIn.end(); ++vit)
- {
- TopTools_ListOfShape shapeList;
- TopExp_Explorer it;
- for (it.Init(*vit, TopAbs_VERTEX); it.More(); it.Next())
- shapeList.Append(it.Current());
- edgeVertexMap.Bind((*vit), shapeList);
- }
-}
-
-bool BoundaryEdgeSplitter::edgeTest(const TopoDS_Edge &edgeOne, const TopoDS_Edge &edgeTwo)
-{
- const TopTools_ListOfShape &verticesOne = edgeVertexMap.Find(edgeOne);
- const TopTools_ListOfShape &verticesTwo = edgeVertexMap.Find(edgeTwo);
- TopTools_ListIteratorOfListOfShape itOne;
- TopTools_ListIteratorOfListOfShape itTwo;
-
- for (itOne.Initialize(verticesOne); itOne.More(); itOne.Next())
- {
- for (itTwo.Initialize(verticesTwo); itTwo.More(); itTwo.Next())
- {
- if (itOne.Value().IsSame(itTwo.Value()))
- return true;
- }
- }
- return false;
-}
-
////////////////////////////////////////////////////////////////////////////////////////////
void FaceTypeSplitter::addShell(const TopoDS_Shell &shellIn)
@@ -460,65 +371,43 @@ TopoDS_Face FaceTypedPlane::buildFace(const FaceVectorType &faces) const
BoundaryEdgeSplitter bSplitter;
bSplitter.split(bEdges);
-
- //parallel vectors. Topo* doesn't have less than. map wouldn't work.
- FaceVectorType facesParallel;
- std::vector wiresParallel;
+ std::vector wires;
std::vector splitEdges = bSplitter.getGroupedEdges();
+ if (splitEdges.empty())
+ return TopoDS_Face();
std::vector::iterator splitIt;
for (splitIt = splitEdges.begin(); splitIt != splitEdges.end(); ++splitIt)
{
- std::list sortedEdges;
- sortedEdges = sort_Edges(Precision::Confusion(), *splitIt);
-
BRepLib_MakeWire wireMaker;
- std::list::iterator sortedIt;
- for (sortedIt = sortedEdges.begin(); sortedIt != sortedEdges.end(); ++sortedIt)
- wireMaker.Add(*sortedIt);
+ EdgeVectorType::iterator it;
+ for (it = (*splitIt).begin(); it != (*splitIt).end(); ++it)
+ wireMaker.Add(*it);
TopoDS_Wire currentWire = wireMaker.Wire();
-
- TopoDS_Face currentFace = BRepBuilderAPI_MakeFace(currentWire, Standard_True);
-
- facesParallel.push_back(currentFace);
- wiresParallel.push_back(currentWire);
+ wires.push_back(currentWire);
}
- if (facesParallel.size() < 1)//shouldn't be here.
- return BRepBuilderAPI_MakeFace();//will cause exception.
- if (facesParallel.size() == 1)
- return (facesParallel.front());
- TopoDS_Face current;
- current = facesParallel.at(0);
- //now we have more than one wire.
- //there has to be a better way to determin which face is inside other
- //without have to build all the faces.
- for(size_t index(1); index 1)
{
- //this algorithm assumes that the boundaries don't intersect.
- gp_Pnt point;
- Handle(Geom_Surface) surface = BRep_Tool::Surface(facesParallel.at(index));
- surface->D0(0.5, 0.5, point);
- BRepClass_FaceClassifier faceTest(current, point, Precision::Confusion());
- if (faceTest.State() == TopAbs_EXTERNAL)
- current = facesParallel.at(index);
+ ShapeFix_Face faceFix(current);
+ faceFix.SetContext(new ShapeBuild_ReShape());
+ for (size_t index(1); index ShapeExtend_DONE)
+ return TopoDS_Face();
+ faceFix.FixOrientation();
+ signal = faceFix.Perform();
+ if (signal > ShapeExtend_DONE)
+ return TopoDS_Face();
+ current = faceFix.Face();
}
- ShapeFix_Face faceFix(current);
- faceFix.SetContext(new ShapeBuild_ReShape());
- for (size_t index(0); index ShapeExtend_DONE)
- return TopoDS_Face();
- else
- return faceFix.Face();
+ BRepLib_FuseEdges edgeFuse(current, Standard_True);
+ return TopoDS::Face(edgeFuse.Shape());
}
FaceTypedPlane& ModelRefine::getPlaneObject()
@@ -655,9 +544,6 @@ bool FaceUniter::process()
for(sewIt = facesToSew.begin(); sewIt != facesToSew.end(); ++sewIt)
builder.Add(workShell, *sewIt);
}
-
- BRepLib_FuseEdges edgeFuse(workShell, true);
- workShell = TopoDS::Shell(edgeFuse.Shape());
}
return true;
}
diff --git a/src/Mod/Part/App/modelRefine.h b/src/Mod/Part/App/modelRefine.h
index 576f4e054..08a146294 100644
--- a/src/Mod/Part/App/modelRefine.h
+++ b/src/Mod/Part/App/modelRefine.h
@@ -141,12 +141,7 @@ namespace ModelRefine
const std::vector& getGroupedEdges(){return groupedEdges;}
private:
- void splitRecursive(EdgeVectorType &tempEdges, const EdgeVectorType &workEdges);
- void buildMap(const EdgeVectorType &edgesIn);
- bool edgeTest(const TopoDS_Edge &edgeOne, const TopoDS_Edge &edgeTwo);
- TopTools_MapOfShape processed;
std::vector groupedEdges;
- TopTools_DataMapOfShapeListOfShape edgeVertexMap;
};
class FaceUniter
diff --git a/src/Mod/Part/Gui/CommandSimple.cpp b/src/Mod/Part/Gui/CommandSimple.cpp
index 00d22cf81..578b5fc9c 100644
--- a/src/Mod/Part/Gui/CommandSimple.cpp
+++ b/src/Mod/Part/Gui/CommandSimple.cpp
@@ -222,16 +222,21 @@ void CmdPartRefineShape::activated(int iMsg)
std::vector objs = Gui::Selection().getObjectsOfType(partid);
openCommand("Refine shape");
for (std::vector::iterator it = objs.begin(); it != objs.end(); ++it) {
- doCommand(Doc,"App.ActiveDocument.addObject('Part::Feature','%s').Shape="
- "App.ActiveDocument.%s.Shape.removeSplitter()\n"
- "App.ActiveDocument.ActiveObject.Label="
- "App.ActiveDocument.%s.Label\n",
- (*it)->getNameInDocument(),
- (*it)->getNameInDocument(),
- (*it)->getNameInDocument());
- copyVisual("ActiveObject", "ShapeColor", (*it)->getNameInDocument());
- copyVisual("ActiveObject", "LineColor", (*it)->getNameInDocument());
- copyVisual("ActiveObject", "PointColor", (*it)->getNameInDocument());
+ try {
+ doCommand(Doc,"App.ActiveDocument.addObject('Part::Feature','%s').Shape="
+ "App.ActiveDocument.%s.Shape.removeSplitter()\n"
+ "App.ActiveDocument.ActiveObject.Label="
+ "App.ActiveDocument.%s.Label\n",
+ (*it)->getNameInDocument(),
+ (*it)->getNameInDocument(),
+ (*it)->getNameInDocument());
+ copyVisual("ActiveObject", "ShapeColor", (*it)->getNameInDocument());
+ copyVisual("ActiveObject", "LineColor", (*it)->getNameInDocument());
+ copyVisual("ActiveObject", "PointColor", (*it)->getNameInDocument());
+ }
+ catch (const Base::Exception& e) {
+ Base::Console().Warning("%s: %s\n", (*it)->Label.getValue(), e.what());
+ }
}
commitCommand();
updateActive();