#include <GeomAPI_Vertex.h>
#include <GeomAPI_ShapeExplorer.h>
+#include <BRep_Builder.hxx>
#include <BRep_Tool.hxx>
#include <BRepBuilderAPI_MakeWire.hxx>
+#include <BRepTools_ReShape.hxx>
#include <Geom_Curve.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Wire.hxx>
+#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
static GeomShapePtr fromTopoDS(const TopoDS_Shape& theShape)
return aResultShape;
}
-GeomAlgoAPI_WireBuilder::GeomAlgoAPI_WireBuilder(const ListOfShape& theShapes)
+GeomAlgoAPI_WireBuilder::GeomAlgoAPI_WireBuilder(const ListOfShape& theShapes,
+ const bool theForceOpenWire)
{
TopTools_ListOfShape aListOfEdges;
}
}
+ bool isSplitWire = false;
+ gp_Pnt aSplitPoint;
+ if (theForceOpenWire) {
+ // find a vertex to split the wire
+ TopoDS_Vertex V1[2];
+ TopExp::Vertices(TopoDS::Edge(aListOfEdges.First()), V1[0], V1[1]);
+ TopoDS_Vertex V2[2];
+ TopExp::Vertices(TopoDS::Edge(aListOfEdges.Last()), V2[0], V2[1]);
+ gp_Pnt P1[2] = { BRep_Tool::Pnt(V1[0]), BRep_Tool::Pnt(V1[1]) };
+ gp_Pnt P2[2] = { BRep_Tool::Pnt(V2[0]), BRep_Tool::Pnt(V2[1]) };
+ double Tol1[2] = { BRep_Tool::Tolerance(V1[0]), BRep_Tool::Tolerance(V1[1]) };
+ double Tol2[2] = { BRep_Tool::Tolerance(V2[0]), BRep_Tool::Tolerance(V2[1]) };
+ for (int i = 0; i < 2 && !isSplitWire; ++i)
+ for (int j = 0; j < 2 && !isSplitWire; ++j)
+ if (P1[i].Distance(P2[i]) < Max(Tol1[i], Tol2[j])) {
+ aSplitPoint = P1[i];
+ isSplitWire = true;
+ }
+ }
+
BRepBuilderAPI_MakeWire* aWireBuilder = new BRepBuilderAPI_MakeWire;
aWireBuilder->Add(aListOfEdges);
if (aWireBuilder->Error() == BRepBuilderAPI_WireDone) {
setImpl(aWireBuilder);
setBuilderType(OCCT_BRepBuilderAPI_MakeShape);
- // store generated/modified shapes
+ // split the result wire
TopoDS_Wire aWire = aWireBuilder->Wire();
+ if (isSplitWire && BRep_Tool::IsClosed(aWire)) {
+ TopoDS_Wire aNewWire;
+ BRep_Builder aBuilder;
+ aBuilder.MakeWire(aNewWire);
+ for (TopExp_Explorer anExp(aWire, TopAbs_EDGE); anExp.More(); anExp.Next()) {
+ TopoDS_Edge aNewCurrent = TopoDS::Edge(anExp.Current());
+ if (isSplitWire) {
+ bool isToReshape = false;
+ BRepTools_ReShape aReshape;
+ TopoDS_Vertex aVF, aVL;
+ TopExp::Vertices(aNewCurrent, aVF, aVL);
+ gp_Pnt aPF = BRep_Tool::Pnt(aVF);
+ double aTolF = BRep_Tool::Tolerance(aVF);
+ gp_Pnt aPL = BRep_Tool::Pnt(aVL);
+ double aTolL = BRep_Tool::Tolerance(aVL);
+ if (aSplitPoint.SquareDistance(aPF) < aTolF * aTolF) {
+ aReshape.Replace(aVF, aReshape.CopyVertex(aVF));
+ isToReshape = true;
+ }
+ else if (aSplitPoint.SquareDistance(aPL) < aTolL * aTolL) {
+ aReshape.Replace(aVL, aReshape.CopyVertex(aVL));
+ isToReshape = true;
+ }
+ if (isToReshape) {
+ aNewCurrent = TopoDS::Edge(aReshape.Apply(aNewCurrent));
+ isSplitWire = false; // no need to continue splitting
+ }
+ }
+ aBuilder.Add(aNewWire, aNewCurrent);
+ }
+ aWire = aNewWire;
+ }
+
+ // store generated/modified shapes
for (TopTools_ListOfShape::Iterator aBaseIt(aListOfEdges); aBaseIt.More(); aBaseIt.Next()) {
TopoDS_Edge aBaseCurrent = TopoDS::Edge(aBaseIt.Value());
Standard_Real aFirst, aLast;