X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FGeomAlgoAPI%2FGeomAlgoAPI_Boolean.cpp;h=ef984332f823f9cad0e540b12a71108f0ed2d9cb;hb=47bec5ba5234d6aa1d0cd784dfb2c21dc0b1f37d;hp=2af2e8edb0841920fd95f9ad3c6312bf915a283a;hpb=dc75c390f0aa6108d6983a8618dc4b9a4cd5949e;p=modules%2Fshaper.git diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_Boolean.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_Boolean.cpp index 2af2e8edb..ef984332f 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_Boolean.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_Boolean.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 CEA/DEN, EDF R&D +// Copyright (C) 2014-2019 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -12,10 +12,9 @@ // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or -// email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // #include "GeomAlgoAPI_Boolean.h" @@ -25,6 +24,29 @@ #include #include +#include +#include + +//================================================================================================= +GeomAlgoAPI_Boolean::GeomAlgoAPI_Boolean(const GeomShapePtr theObject, + const GeomShapePtr theTool, + const OperationType theOperationType) +{ + ListOfShape aListWithObject, aListWithTool; + aListWithObject.push_back(theObject); + aListWithTool.push_back(theTool); + build(aListWithObject, aListWithTool, theOperationType); +} + +//================================================================================================= +GeomAlgoAPI_Boolean::GeomAlgoAPI_Boolean(const GeomShapePtr theObject, + const ListOfShape& theTools, + const OperationType theOperationType) +{ + ListOfShape aListWithObject; + aListWithObject.push_back(theObject); + build(aListWithObject, theTools, theOperationType); +} //================================================================================================= GeomAlgoAPI_Boolean::GeomAlgoAPI_Boolean(const ListOfShape& theObjects, @@ -84,6 +106,10 @@ void GeomAlgoAPI_Boolean::build(const ListOfShape& theObjects, aBuilder->SetArguments(anObjects); aBuilder->SetTools(aTools); + // Set parallel processing mode (default is false) + Standard_Boolean bRunParallel = Standard_True; + aBuilder->SetRunParallel(bRunParallel); + // Building and getting result. aBuilder->Perform(); if (aBuilder->HasErrors()) @@ -96,11 +122,10 @@ void GeomAlgoAPI_Boolean::build(const ListOfShape& theObjects, if(aResult.ShapeType() == TopAbs_COMPOUND) { std::shared_ptr aGeomShape(new GeomAPI_Shape); aGeomShape->setImpl(new TopoDS_Shape(aResult)); - ListOfShape aCompSolids, aFreeSolids; + ListOfShape aResults; aGeomShape = GeomAlgoAPI_ShapeTools::combineShapes(aGeomShape, GeomAPI_Shape::COMPSOLID, - aCompSolids, - aFreeSolids); + aResults); aResult = aGeomShape->impl(); } @@ -109,3 +134,87 @@ void GeomAlgoAPI_Boolean::build(const ListOfShape& theObjects, this->setShape(aShape); this->setDone(true); } + +static bool isHistoryType(TopAbs_ShapeEnum theType) { + return theType == TopAbs_VERTEX || theType == TopAbs_EDGE || + theType == TopAbs_FACE || theType == TopAbs_SOLID; +} + +/// searches the corresponding result for theOld +static void searchResult(const TopoDS_Shape& theOld, const TopoDS_Shape& theResult, + BOPAlgo_BOP* theBuilder, TopTools_MapOfShape& theNews) +{ + if (theResult.ShapeType() == theOld.ShapeType()) { // check some sub-shape produces a sub-result + if (theOld.IsSame(theResult)) { + theNews.Add(theResult); + return; + } + // searching for new result by sub-shapes of aSubType type + TopAbs_ShapeEnum aSubType = TopAbs_ShapeEnum(int(theOld.ShapeType()) + 1); + while(aSubType < TopAbs_VERTEX && !isHistoryType(aSubType)) + aSubType = TopAbs_ShapeEnum(int(aSubType) + 1); + if (aSubType == TopAbs_SHAPE) + return; + TopTools_MapOfShape aResSubs; + for(TopExp_Explorer aResExp(theResult, aSubType); aResExp.More(); aResExp.Next()) + aResSubs.Add(aResExp.Current()); + for(TopExp_Explorer anExp(theOld, aSubType); anExp.More(); anExp.Next()) { + const TopTools_ListOfShape& aNewSubs = theBuilder->Modified(anExp.Current()); + // searching for this new sub in theResult + for(TopTools_ListIteratorOfListOfShape aNewSub(aNewSubs); aNewSub.More(); aNewSub.Next()) { + if (aResSubs.Contains(aNewSub.Value())) { + theNews.Add(theResult); + return; + } + } + } + } else if (theResult.ShapeType() < theOld.ShapeType()) { // recursive search among sub-shapes + for(TopoDS_Iterator aSubResults(theResult); aSubResults.More(); aSubResults.Next()) { + searchResult(theOld, aSubResults.Value(), theBuilder, theNews); + } + } +} + +// check the shape is on the higher level of compound or compsolid +bool isInComp(const TopoDS_Shape& theComp, const TopoDS_Shape& theShape) { + if (theComp.ShapeType() == TopAbs_COMPOUND || theComp.ShapeType() == TopAbs_COMPSOLID) { + for(TopoDS_Iterator anIter(theComp); anIter.More(); anIter.Next()) { + if (isInComp(anIter.Value(), theShape)) + return true; + } + } else return theShape.IsSame(theComp); + return false; +} + +//================================================================================================= +/// make arguments of Fuse produce result shapes with "modified" evolution +void GeomAlgoAPI_Boolean::modified(const GeomShapePtr theOldShape, ListOfShape& theNewShapes) +{ + BOPAlgo_BOP* aBuilder = this->implPtr(); + if (aBuilder->Operation() == BOPAlgo_FUSE) { // only for fuse and when old is and argument + TopoDS_Shape anOld = theOldShape->impl(); + bool isOldComp = anOld.ShapeType() == TopAbs_COMPOUND || anOld.ShapeType() == TopAbs_COMPSOLID; + bool aFound = false; + TopTools_ListIteratorOfListOfShape anIter(aBuilder->Arguments()); + for(; !aFound && anIter.More(); anIter.Next()) + aFound = anOld.IsSame(anIter.Value()) || (!isOldComp && isInComp(anIter.Value(), anOld)); + for(anIter.Initialize(aBuilder->Tools()); !aFound && anIter.More(); anIter.Next()) + aFound = anOld.IsSame(anIter.Value()) || (!isOldComp && isInComp(anIter.Value(), anOld)); + if (aFound) { + TopoDS_Shape aResult = aBuilder->Shape(); + TopTools_MapOfShape aNewsMap; + searchResult(anOld, aResult, aBuilder, aNewsMap); + if (!aNewsMap.IsEmpty()) { + for(TopTools_MapIteratorOfMapOfShape aNewsIter(aNewsMap); + aNewsIter.More(); aNewsIter.Next()) + { + GeomShapePtr aShape(new GeomAPI_Shape); + aShape->setImpl(new TopoDS_Shape(aNewsIter.Value())); + theNewShapes.push_back(aShape); + } + return; + } + } + } + GeomAlgoAPI_MakeShape::modified(theOldShape, theNewShapes); // default behavior +}