X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FGeomAlgoAPI%2FGeomAlgoAPI_SketchBuilder.cpp;h=880273df25fe4665fa09d37cd3649dfca5df5be9;hb=f0cec241aae9ca16d86e166f45cb5c4987d2c792;hp=9713fda503f839eb42b77fa19d9725fcdd31d295;hpb=6755cb75f722eab87766a25f66d0ab6ea6847193;p=modules%2Fshaper.git diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_SketchBuilder.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_SketchBuilder.cpp index 9713fda50..880273df2 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_SketchBuilder.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_SketchBuilder.cpp @@ -12,11 +12,39 @@ #include #include #include +#include #include #include #include #include +#include +#include + + +static TopoDS_Vertex findStartVertex(const TopoDS_Shape& theShape) +{ + static const double aTol = Precision::PConfusion(); + + TopExp_Explorer anExp(theShape, TopAbs_VERTEX); + TopoDS_Vertex aStart = TopoDS::Vertex(anExp.Current()); + gp_Pnt aStartPnt(BRep_Tool::Pnt(aStart)); + TopoDS_Vertex aCurrent; + gp_Pnt aCurrentPnt; + + for (anExp.Next(); anExp.More(); anExp.Next()) { + aCurrent = TopoDS::Vertex(anExp.Current()); + aCurrentPnt = BRep_Tool::Pnt(aCurrent); + if ((aCurrentPnt.X() > aStartPnt.X() + aTol) || + (aCurrentPnt.X() > aStartPnt.X() - aTol && aCurrentPnt.Y() > aStartPnt.Y() + aTol) || + (aCurrentPnt.X() > aStartPnt.X() - aTol && aCurrentPnt.Y() > aStartPnt.Y() - aTol && + aCurrentPnt.Z() > aStartPnt.Z() + aTol)) { + aStart = aCurrent; + aStartPnt = aCurrentPnt; + } + } + return aStart; +} void GeomAlgoAPI_SketchBuilder::createFaces( const std::shared_ptr& theOrigin, @@ -61,24 +89,54 @@ void GeomAlgoAPI_SketchBuilder::createFaces( if (aFClass.PerformInfinitePoint() == TopAbs_IN) continue; - // remove internal edges from faces - TopExp_Explorer anExp(aFace, TopAbs_EDGE); - for (; anExp.More(); anExp.Next()) - if (anExp.Current().Orientation() == TopAbs_INTERNAL) - break; - if (anExp.More()) { - TopoDS_Face aNewFace; - aBuilder.MakeFace(aNewFace, aPlane, Precision::Confusion()); - TopoDS_Wire aWire; - aBuilder.MakeWire(aWire); - for (anExp.ReInit(); anExp.More(); anExp.Next()) - if (anExp.Current().Orientation() != TopAbs_INTERNAL) - aBuilder.Add(aWire, anExp.Current()); - aBuilder.Add(aNewFace, aWire); - aFace = aNewFace; + // rebuild face + TopoDS_Face aNewFace; + aBuilder.MakeFace(aNewFace, aPlane, Precision::Confusion()); + + // iterate on wires + TopExp_Explorer aWireExp(aFace, TopAbs_WIRE); + for (; aWireExp.More(); aWireExp.Next()) { + TopoDS_Wire aWire = TopoDS::Wire(aWireExp.Current()); + + // to make faces equal on different platforms, we will find + // a vertex with greater coordinates and start wire from it + TopoDS_Vertex aStartVertex = findStartVertex(aWire); + + TopoDS_Wire aNewWire; + aBuilder.MakeWire(aNewWire); + std::list aSkippedEdges; + bool aStartFound = false; + + // remove internal edges from faces and make wire start from found vertex + TopExp_Explorer anExp(aWire, TopAbs_EDGE); + for (; anExp.More(); anExp.Next()) { + if (anExp.Current().Orientation() == TopAbs_INTERNAL) + continue; + if (!aStartFound) { + const TopoDS_Edge& anEdge = TopoDS::Edge(anExp.Current()); + TopoDS_Vertex aV1, aV2; + TopExp::Vertices(anEdge, aV1, aV2, Standard_True); + if (aV1.IsSame(aStartVertex) == Standard_True) + aStartFound = true; + else + aSkippedEdges.push_back(anEdge); + } + if (aStartFound) + aBuilder.Add(aNewWire, anExp.Current()); + } + // add skipped edges to the end of wire + std::list::const_iterator aSkIt = aSkippedEdges.begin(); + for (; aSkIt != aSkippedEdges.end(); ++aSkIt) + aBuilder.Add(aNewWire, *aSkIt); + + // check the wire is empty + anExp.Init(aNewWire, TopAbs_EDGE); + if (anExp.More()) + aBuilder.Add(aNewFace, aNewWire); } - // Store face + // store face + aFace = aNewFace; std::shared_ptr aResFace(new GeomAPI_Shape); aResFace->setImpl(new TopoDS_Face(aFace)); theResultFaces.push_back(aResFace);