+void GeomAlgoAPI_SketchBuilder::fixIntersections(
+ std::list<std::shared_ptr<GeomAPI_Shape> >& theFaces)
+{
+ BRepClass_FaceClassifier aClassifier;
+
+ std::list<std::shared_ptr<GeomAPI_Shape> >::iterator anIter1 = theFaces.begin();
+ std::list<std::shared_ptr<GeomAPI_Shape> >::iterator anIter2;
+ for (; anIter1 != theFaces.end(); anIter1++) {
+ anIter2 = anIter1;
+ for (++anIter2; anIter2 != theFaces.end(); anIter2++) {
+ const TopoDS_Face& aF1 = (*anIter1)->impl<TopoDS_Face>();
+ assert(aF1.ShapeType() == TopAbs_FACE); // all items in result list should be faces
+ TopExp_Explorer aVert2((*anIter2)->impl<TopoDS_Shape>(), TopAbs_VERTEX);
+ for (; aVert2.More(); aVert2.Next()) {
+ const TopoDS_Vertex& aV = (const TopoDS_Vertex&)aVert2.Current();
+ aClassifier.Perform(aF1, BRep_Tool::Pnt(aV), tolerance);
+ TopAbs_State aState = aClassifier.State();
+ if (aState != TopAbs_IN && aState != TopAbs_ON)
+ break;
+ }
+ if (aVert2.More()) { // second shape is not inside first, change the shapes order and repeat comparision
+ const TopoDS_Face& aF2 = (*anIter2)->impl<TopoDS_Face>();
+ assert(aF2.ShapeType() == TopAbs_FACE); // all items in result list should be faces
+ TopExp_Explorer aVert1((*anIter1)->impl<TopoDS_Shape>(), TopAbs_VERTEX);
+ for (; aVert1.More(); aVert1.Next()) {
+ const TopoDS_Vertex& aV = (const TopoDS_Vertex&)aVert2.Current();
+ aClassifier.Perform(aF2, BRep_Tool::Pnt(aV), tolerance);
+ TopAbs_State aState = aClassifier.State();
+ if (aState != TopAbs_IN && aState != TopAbs_ON)
+ break;
+ }
+ if (!aVert1.More()) { // first shape should be cut from the second
+ BRepAlgoAPI_Cut aCut((*anIter2)->impl<TopoDS_Shape>(), (*anIter1)->impl<TopoDS_Shape>());
+ aCut.Build();
+ TopExp_Explorer anExp(aCut.Shape(), TopAbs_FACE);
+ bool isFirstFace = true;
+ for (; anExp.More(); anExp.Next()) {
+ if (anExp.Current().ShapeType() != TopAbs_FACE) continue;
+ if (isFirstFace) {
+ (*anIter2)->setImpl(new TopoDS_Shape(anExp.Current()));
+ isFirstFace = false;
+ } else {
+ std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape);
+ aShape->setImpl(new TopoDS_Shape(anExp.Current()));
+ theFaces.push_back(aShape);
+ }
+ }
+ }
+ } else { // second shape should be cut from the first
+ BRepAlgoAPI_Cut aCut((*anIter1)->impl<TopoDS_Shape>(), (*anIter2)->impl<TopoDS_Shape>());
+ aCut.Build();
+ TopExp_Explorer anExp(aCut.Shape(), TopAbs_FACE);
+ bool isFirstFace = true;
+ for (; anExp.More(); anExp.Next()) {
+ if (anExp.Current().ShapeType() != TopAbs_FACE) continue;
+ if (isFirstFace) {
+ (*anIter1)->setImpl(new TopoDS_Shape(anExp.Current()));
+ isFirstFace = false;
+ } else {
+ std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape);
+ aShape->setImpl(new TopoDS_Shape(anExp.Current()));
+ theFaces.push_back(aShape);
+ }
+ }
+ }
+ }
+ }
+}
+