X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2FGeomAlgoAPI%2FGeomAlgoAPI_MakeShape.cpp;h=fc1aaaeda76d4def6838fb6a8f4396e49b6a0131;hb=98ac3fe4aa897d878ee3ef2bf2ab3a238a8c5977;hp=14b3bcb3886369a8c31335f3ff2089ef3f25e2a5;hpb=42de443bf267cba7278df5dd4ae8a5f19612bd25;p=modules%2Fshaper.git diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.cpp index 14b3bcb38..fc1aaaeda 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_MakeShape.cpp @@ -1,14 +1,26 @@ -// Copyright (C) 2014-20xx CEA/DEN, EDF R&D - -// File: GeomAlgoAPI_MakeShape.cpp -// Created: 20 Oct 2014 -// Author: Sergey ZARITCHNY +// Copyright (C) 2014-2021 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 +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// 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 +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// Modified by Clarisse Genrault (CEA) : 17 Mar 2016 #include "GeomAlgoAPI_MakeShape.h" #include +#include #include #include #include @@ -18,129 +30,134 @@ #include #include #include +#include +#include +#include +#include + +// new shape -> old shapes -> index in the old shape +typedef NCollection_DataMap, TopTools_ShapeMapHasher> + MapNewToOld; +typedef + NCollection_DataMap > + HistoryMap; -//================================================================================================= +//================================================================================================== GeomAlgoAPI_MakeShape::GeomAlgoAPI_MakeShape() : myBuilderType(Unknown), myDone(false) { + myHist = 0; } -//================================================================================================= +//================================================================================================== +GeomAlgoAPI_MakeShape::~GeomAlgoAPI_MakeShape() +{ + if (myHist) { + delete (HistoryMap*)myHist; + } +} + +//================================================================================================== bool GeomAlgoAPI_MakeShape::isDone() const { return myDone; } -//================================================================================================= -const std::shared_ptr GeomAlgoAPI_MakeShape::shape() const +//================================================================================================== +const GeomShapePtr GeomAlgoAPI_MakeShape::shape() const { return myShape; } -//================================================================================================= +//================================================================================================== bool GeomAlgoAPI_MakeShape::isValid() const { BRepCheck_Analyzer aChecker(myShape->impl()); return (aChecker.IsValid() == Standard_True); } -//================================================================================================= -bool GeomAlgoAPI_MakeShape::hasVolume() const -{ - bool hasVolume = false; - if(isValid()) { - const TopoDS_Shape& aRShape = myShape->impl(); - GProp_GProps aGProp; - BRepGProp::VolumeProperties(aRShape, aGProp); - if(aGProp.Mass() > Precision::Confusion()) - hasVolume = true; - } - return hasVolume; -} - -//================================================================================================= +//================================================================================================== std::shared_ptr GeomAlgoAPI_MakeShape::mapOfSubShapes() const { return myMap; } -//================================================================================================= -void GeomAlgoAPI_MakeShape::generated(const std::shared_ptr theShape, - ListOfShape& theHistory) +//================================================================================================== +void GeomAlgoAPI_MakeShape::generated(const GeomShapePtr theOldShape, + ListOfShape& theNewShapes) { TopTools_ListOfShape aList; if(myBuilderType == OCCT_BRepBuilderAPI_MakeShape) { BRepBuilderAPI_MakeShape* aMakeShape = implPtr(); - aList = aMakeShape->Generated(theShape->impl()); + aList = aMakeShape->Generated(theOldShape->impl()); } else if(myBuilderType == OCCT_BOPAlgo_Builder) { BOPAlgo_Builder* aBOPBuilder = implPtr(); - aList = aBOPBuilder->Generated(theShape->impl()); + aList = aBOPBuilder->Generated(theOldShape->impl()); } for(TopTools_ListIteratorOfListOfShape anIt(aList); anIt.More(); anIt.Next()) { - if(anIt.Value().IsNull()) { - continue; - } - std::shared_ptr aShape(new GeomAPI_Shape()); + GeomShapePtr aShape(new GeomAPI_Shape()); aShape->setImpl(new TopoDS_Shape(anIt.Value())); - theHistory.push_back(aShape); + if (!isValidForHistory(aShape)) continue; + fixOrientation(aShape); + theNewShapes.push_back(aShape); } } -//================================================================================================= -void GeomAlgoAPI_MakeShape::modified(const std::shared_ptr theShape, - ListOfShape& theHistory) +//================================================================================================== +void GeomAlgoAPI_MakeShape::modified(const GeomShapePtr theOldShape, + ListOfShape& theNewShapes) { TopTools_ListOfShape aList; if(myBuilderType == OCCT_BRepBuilderAPI_MakeShape) { BRepBuilderAPI_MakeShape* aMakeShape = implPtr(); try { - aList = aMakeShape->Modified(theShape->impl()); + aList = aMakeShape->Modified(theOldShape->impl()); } catch(Standard_NoSuchObject) { } } else if(myBuilderType == OCCT_BOPAlgo_Builder) { BOPAlgo_Builder* aBOPBuilder = implPtr(); - aList = aBOPBuilder->Modified(theShape->impl()); + aList = aBOPBuilder->Modified(theOldShape->impl()); } for(TopTools_ListIteratorOfListOfShape anIt(aList); anIt.More(); anIt.Next()) { - if(anIt.Value().IsNull()) { - continue; - } - std::shared_ptr aShape(new GeomAPI_Shape()); + GeomShapePtr aShape(new GeomAPI_Shape()); aShape->setImpl(new TopoDS_Shape(anIt.Value())); - theHistory.push_back(aShape); + if (!isValidForHistory(aShape)) continue; + fixOrientation(aShape); + theNewShapes.push_back(aShape); } } -//================================================================================================= -bool GeomAlgoAPI_MakeShape::isDeleted(const std::shared_ptr theShape) +//================================================================================================== +bool GeomAlgoAPI_MakeShape::isDeleted(const GeomShapePtr theOldShape) { bool isDeleted = false; if(myBuilderType == OCCT_BRepBuilderAPI_MakeShape) { BRepBuilderAPI_MakeShape* aMakeShape = implPtr(); - isDeleted = aMakeShape->IsDeleted(theShape->impl()) == Standard_True; + isDeleted = aMakeShape->IsDeleted(theOldShape->impl()) == Standard_True; } else if(myBuilderType == OCCT_BOPAlgo_Builder) { BOPAlgo_Builder* aBOPBuilder = implPtr(); - isDeleted = aBOPBuilder->IsDeleted(theShape->impl()) == Standard_True; + isDeleted = aBOPBuilder->IsDeleted(theOldShape->impl()) == Standard_True; } return isDeleted; } -//================================================================================================= +//================================================================================================== void GeomAlgoAPI_MakeShape::setBuilderType(const BuilderType theBuilderType) { myBuilderType = theBuilderType; } -//================================================================================================= +//================================================================================================== void GeomAlgoAPI_MakeShape::setDone(const bool theFlag) { myDone = theFlag; } -//================================================================================================= -void GeomAlgoAPI_MakeShape::setShape(const std::shared_ptr theShape) +//================================================================================================== +void GeomAlgoAPI_MakeShape::setShape(const GeomShapePtr theShape) { if(myShape.get() && myShape->isEqual(theShape)) { return; @@ -158,17 +175,17 @@ void GeomAlgoAPI_MakeShape::setShape(const std::shared_ptr theSha const TopoDS_Shape& aTopoDSShape = myShape->impl(); for(TopExp_Explorer anExp(aTopoDSShape,TopAbs_VERTEX); anExp.More(); anExp.Next()) { - std::shared_ptr aCurrentShape(new GeomAPI_Shape()); + GeomShapePtr aCurrentShape(new GeomAPI_Shape()); aCurrentShape->setImpl(new TopoDS_Shape(anExp.Current())); myMap->bind(aCurrentShape, aCurrentShape); } for(TopExp_Explorer anExp(aTopoDSShape,TopAbs_EDGE); anExp.More(); anExp.Next()) { - std::shared_ptr aCurrentShape(new GeomAPI_Shape()); + GeomShapePtr aCurrentShape(new GeomAPI_Shape()); aCurrentShape->setImpl(new TopoDS_Shape(anExp.Current())); myMap->bind(aCurrentShape, aCurrentShape); } for(TopExp_Explorer anExp(aTopoDSShape,TopAbs_FACE); anExp.More(); anExp.Next()) { - std::shared_ptr aCurrentShape(new GeomAPI_Shape()); + GeomShapePtr aCurrentShape(new GeomAPI_Shape()); aCurrentShape->setImpl(new TopoDS_Shape(anExp.Current())); myMap->bind(aCurrentShape, aCurrentShape); } @@ -179,8 +196,30 @@ void GeomAlgoAPI_MakeShape::setShape(const std::shared_ptr theSha } } -//================================================================================================= -void GeomAlgoAPI_MakeShape::initialize() { +//================================================================================================== +bool GeomAlgoAPI_MakeShape::isValidForHistory(const GeomShapePtr theShape) +{ + if (!theShape.get()) return false; + + const TopoDS_Shape& aShape_ = theShape->impl(); + if (aShape_.IsNull()) return false; + + if (aShape_.ShapeType() == TopAbs_EDGE) { + TopoDS_Edge anEdge_ = TopoDS::Edge(aShape_); + if (BRep_Tool::Degenerated(anEdge_)) return false; + } + + return true; +} + +//================================================================================================== +void GeomAlgoAPI_MakeShape::fixOrientation(GeomShapePtr& theShape) { + if (myMap->isBound(theShape)) theShape = myMap->find(theShape); +} + +//================================================================================================== +void GeomAlgoAPI_MakeShape::initialize() +{ switch (myBuilderType) { case OCCT_BRepBuilderAPI_MakeShape: { myDone = implPtr()->IsDone() == Standard_True; @@ -194,6 +233,8 @@ void GeomAlgoAPI_MakeShape::initialize() { myShape->setImpl(new TopoDS_Shape(implPtr()->Shape())); break; } + default: + break; } if(myMap.get()) { @@ -204,28 +245,28 @@ void GeomAlgoAPI_MakeShape::initialize() { const TopoDS_Shape& aTopoDSShape = myShape->impl(); for(TopExp_Explorer anExp(aTopoDSShape,TopAbs_FACE); anExp.More(); anExp.Next()) { - std::shared_ptr aCurrentShape(new GeomAPI_Shape()); + GeomShapePtr aCurrentShape(new GeomAPI_Shape()); aCurrentShape->setImpl(new TopoDS_Shape(anExp.Current())); myMap->bind(aCurrentShape, aCurrentShape); } + myHist = 0; } -//================================================================================================= +//================================================================================================== void GeomAlgoAPI_MakeShape::prepareNamingFaces() { long long index = 1; - GeomAPI_ShapeExplorer anExp(shape(), GeomAPI_Shape::FACE); for(GeomAPI_ShapeExplorer anExp(shape(), GeomAPI_Shape::FACE); anExp.more(); anExp.next()) { - std::shared_ptr aFace = anExp.current(); + GeomShapePtr aFace = anExp.current(); myCreatedFaces["Face_" + std::to_string(index++)] = aFace; } } -//================================================================================================= -bool GeomAlgoAPI_MakeShape::checkValid(std::string theMessage){ - +//================================================================================================== +bool GeomAlgoAPI_MakeShape::checkValid(std::string theMessage) +{ // isValid() is called from this method if (!isValid()) { myError = theMessage + " :: resulting shape is not valid."; @@ -238,12 +279,105 @@ bool GeomAlgoAPI_MakeShape::checkValid(std::string theMessage){ for(TopExp_Explorer anExp(aTopoDSShape,TopAbs_SOLID); anExp.More(); anExp.Next()) { aNbVolumes ++; } - + if (aNbVolumes != 1) { - myError = theMessage + " :: connexity error, the resulting shape is made of several separate solids."; + myError = theMessage + + " :: connexity error, the resulting shape is made of several separate solids."; return false; } - + return true ; } - + +//================================================================================================== +bool GeomAlgoAPI_MakeShape::isNewShapesCollected(GeomShapePtr theWholeOld, + const int theShapeType) +{ + if (!myHist) + return false; + HistoryMap* aHist = (HistoryMap*)myHist; + if (!aHist->IsBound(theShapeType)) + return false; + return aHist->Find(theShapeType).IsBound(theWholeOld->impl()); +} + +void GeomAlgoAPI_MakeShape::collectNewShapes( + GeomShapePtr theWholeOld, const int theShapeType) +{ + if (!myHist) + myHist = new HistoryMap; + HistoryMap* aHist = (HistoryMap*)myHist; + if (!aHist->IsBound(theShapeType)) + aHist->Bind( + theShapeType, NCollection_DataMap()); + aHist->ChangeFind(theShapeType). // add a new in anyway + Bind(theWholeOld->impl(), MapNewToOld()); + MapNewToOld& aCurrent = + aHist->ChangeFind(theShapeType).ChangeFind(theWholeOld->impl()); + ListOfShape aNewList; + TopTools_MapOfShape aViewed; //avoid same shapes + GeomAPI_ShapeExplorer anExp(theWholeOld, GeomAPI_Shape::ShapeType(theShapeType)); + for(int anIndexInWholeOld = 0; anExp.more(); anExp.next(), anIndexInWholeOld++) { + if (!aViewed.Add(anExp.current()->impl())) + continue; + aNewList.clear(); + modified(anExp.current(), aNewList); + for(ListOfShape::iterator aNew = aNewList.begin(); aNew != aNewList.end(); aNew++) { + const TopoDS_Shape& aNewShape = (*aNew)->impl(); + if (!aCurrent.IsBound(aNewShape)) { + aCurrent.Bind( + aNewShape, NCollection_DataMap()); + } + aCurrent.ChangeFind(aNewShape).Bind(anExp.current()->impl(), anIndexInWholeOld); + } + } +} + +static void addAllSubs(const TopoDS_Shape& theNewShape, + MapNewToOld& theCurrent, std::map& theResMap) +{ + if (theCurrent.IsBound(theNewShape)) { + NCollection_DataMap::Iterator + anOldIter(theCurrent.Find(theNewShape)); + for(; anOldIter.More(); anOldIter.Next()) { + theResMap[anOldIter.Value()] = anOldIter.Key(); + } + } + + TopoDS_Iterator anIter(theNewShape); + for(; anIter.More(); anIter.Next()) { + //if (anIter.Value().ShapeType() != TopAbs_VERTEX) + addAllSubs(anIter.Value(), theCurrent, theResMap); // add recursively + } +} + +//================================================================================================== +GeomShapePtr GeomAlgoAPI_MakeShape::oldShapesForNew(GeomShapePtr theWholeOld, + GeomShapePtr theNewShape, + const int theShapeType) +{ + GeomShapePtr aResult(new GeomAPI_Shape); + TopoDS_Compound aResComp; + TopoDS_Builder aBuilder; + aBuilder.MakeCompound(aResComp); + aResult->setImpl(new TopoDS_Shape(aResComp)); + + HistoryMap* aHist = (HistoryMap*)myHist; + if (!aHist->IsBound(theShapeType)) + return aResult; // not found, empty compound + const TopoDS_Shape& aWholeOld = theWholeOld->impl(); + if (!aHist->Find(theShapeType).IsBound(aWholeOld)) + return aResult; // not found, empty compound + std::map aResMap; // map with all results, ordered by index in whole old + MapNewToOld& aCurrent = aHist->ChangeFind(theShapeType).ChangeFind(aWholeOld); + // we don't know what type of new shapes were produced by the old theShapeType, so, iterate all + addAllSubs(theNewShape->impl(), aCurrent, aResMap); + + std::map::iterator anOldIter = aResMap.begin(); + for(; anOldIter != aResMap.end(); anOldIter++) { + if (anOldIter->second.ShapeType() == (TopAbs_ShapeEnum)theShapeType) + aBuilder.Add(aResComp, anOldIter->second); + } + aResult->setImpl(new TopoDS_Shape(aResComp)); + return aResult; +}