]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
feature addVolume v1.0
authorNicolas RECHATIN <nicolas.rechatin@cea.fr>
Wed, 21 Jul 2021 07:37:50 +0000 (09:37 +0200)
committerNicolas RECHATIN <nicolas.rechatin@cea.fr>
Wed, 21 Jul 2021 07:37:50 +0000 (09:37 +0200)
src/Model/Model_Document.cpp
src/Model/Model_Objects.h
src/Model/Model_ResultVolume.cpp
src/Model/Model_ResultVolume.h
src/ModelAPI/CMakeLists.txt
src/ModelAPI/ModelAPI_ResultVolume.cpp [new file with mode: 0644]
src/ModelAPI/ModelAPI_ResultVolume.h
src/ModelAPI/ModelAPI_Tools.cpp
src/ModelAPI/ModelAPI_Tools.h
src/OperaPlugin/OperaPlugin_Volume.cpp
src/PrimitivesPlugin/PrimitivesPlugin_Box.cpp

index ab44f2686107269513c0930db97f5c982b61bb03..8a1dc2f24000f55e3876507716043b30da48fd22 100644 (file)
@@ -1571,16 +1571,17 @@ std::shared_ptr<ModelAPI_ResultConstruction> Model_Document::createConstruction(
   return myObjs->createConstruction(theFeatureData, theIndex);
 }
 
-std::shared_ptr<ModelAPI_ResultBody> Model_Document::createBody(
+std::shared_ptr<ModelAPI_ResultVolume> Model_Document::createVolume(
     const std::shared_ptr<ModelAPI_Data>& theFeatureData, const int theIndex)
 {
-  return myObjs->createBody(theFeatureData, theIndex);
+  return myObjs->createVolume(theFeatureData, theIndex);
 }
 
-std::shared_ptr<ModelAPI_ResultVolume> Model_Document::createVolume(
+
+std::shared_ptr<ModelAPI_ResultBody> Model_Document::createBody(
     const std::shared_ptr<ModelAPI_Data>& theFeatureData, const int theIndex)
 {
-  return myObjs->createVolume(theFeatureData, theIndex);
+  return myObjs->createBody(theFeatureData, theIndex);
 }
 
 std::shared_ptr<ModelAPI_ResultPart> Model_Document::createPart(
index d644560606ce24faae1867734204382174311b10..d4b6a98d7a1a11236da27e9d9483f1bc97d2e0a5 100644 (file)
@@ -125,7 +125,7 @@ class Model_Objects
   std::shared_ptr<ModelAPI_ResultBody> createBody(
       const std::shared_ptr<ModelAPI_Data>& theFeatureData, const int theIndex = 0,
       const std::wstring& theNameShape = L"");
-  /// Creates a body result
+  /// Creates a volume result
   std::shared_ptr<ModelAPI_ResultVolume> createVolume(
       const std::shared_ptr<ModelAPI_Data>& theFeatureData, const int theIndex = 0,
       const std::wstring& theNameShape = L"");
index 3145ebe9bd301cdedfdf53d2eafc4c0bc3bdf92c..eda5d69844272e26a13f6ad9e2f2f0425edd49cc 100644 (file)
 #include <TDataStd_UAttribute.hxx>
 
 // if this attribute exists, the shape is connected topology
-Standard_GUID kIsConnectedTopology("e51392e0-3a4d-405d-8e36-bbfe19858ef5");
+Standard_GUID kIsConnectedTopologyVolume("e51392e0-3a4d-405d-8e36-bbfe19858ef5");
 // if this attribute exists, the connected topology flag must be recomputed
-Standard_GUID kUpdateConnectedTopology("01ef7a45-0bec-4266-b0b4-4aa570921818");
+Standard_GUID kUpdateConnectedTopologyVolume("01ef7a45-0bec-4266-b0b4-4aa570921818");
 
-Model_ResultVolume::Model_ResultVolume() : Model_ResultVolume()
+Model_ResultVolume::Model_ResultVolume() : ModelAPI_ResultVolume()
 {
   myBuilder = new Model_BodyBuilder(this);
-  // myLastConcealed = false;
-  // updateSubs(shape()); // in case of open, etc.
+  myLastConcealed = false;
+  updateSubs(shape()); // in case of open, etc.
 }
 
 Model_ResultVolume::~Model_ResultVolume()
 {
-  // updateSubs(std::shared_ptr<GeomAPI_Shape>()); // erase sub-results
+  updateSubs(std::shared_ptr<GeomAPI_Shape>()); // erase sub-results
   delete myBuilder;
 }
+
+bool Model_ResultVolume::generated(const GeomShapePtr& theNewShape,
+  const std::string& theName, const bool theCheckIsInResult)
+{
+  bool aResult = false;
+  if (mySubs.size()) { // consists of subs
+    for (std::vector<ResultVolumePtr>::const_iterator aSubIter = mySubs.cbegin();
+         aSubIter != mySubs.cend();
+         ++aSubIter)
+    {
+      const ResultVolumePtr& aSub = *aSubIter;
+      if (aSub->generated(theNewShape, theName, theCheckIsInResult))
+        aResult = true;
+    }
+  } else { // do for this directly
+    if (myBuilder->generated(theNewShape, theName, theCheckIsInResult))
+      aResult = true;
+  }
+  return aResult;
+}
+
+void Model_ResultVolume::loadGeneratedShapes(const std::shared_ptr<GeomAlgoAPI_MakeShape>& theAlgo,
+                                           const GeomShapePtr& theOldShape,
+                                           const GeomAPI_Shape::ShapeType theShapeTypeToExplore,
+                                           const std::string& theName,
+                                           const bool theSaveOldIfNotInTree)
+{
+  if (mySubs.size()) { // consists of subs
+    for (std::vector<ResultVolumePtr>::const_iterator aSubIter = mySubs.cbegin();
+         aSubIter != mySubs.cend();
+         ++aSubIter)
+    {
+      const ResultVolumePtr& aSub = *aSubIter;
+      aSub->loadGeneratedShapes(
+        theAlgo, theOldShape, theShapeTypeToExplore, theName, theSaveOldIfNotInTree);
+    }
+  } else { // do for this directly
+    myBuilder->loadGeneratedShapes(
+      theAlgo, theOldShape, theShapeTypeToExplore, theName, theSaveOldIfNotInTree);
+  }
+}
+
+void Model_ResultVolume::loadModifiedShapes(const std::shared_ptr<GeomAlgoAPI_MakeShape>& theAlgo,
+                                          const GeomShapePtr& theOldShape,
+                                          const GeomAPI_Shape::ShapeType theShapeTypeToExplore,
+                                          const std::string& theName)
+{
+  if (mySubs.size()) { // consists of subs
+    // optimization of getting of new shapes for specific sub-result
+    if (!theAlgo->isNewShapesCollected(theOldShape, theShapeTypeToExplore))
+      theAlgo->collectNewShapes(theOldShape, theShapeTypeToExplore);
+    std::vector<ResultVolumePtr>::const_iterator aSubIter = mySubs.cbegin();
+    for(; aSubIter != mySubs.cend(); aSubIter++) {
+      (*aSubIter)->loadModifiedShapes(theAlgo, theOldShape, theShapeTypeToExplore, theName);
+    }
+  } else { // do for this directly
+    myBuilder->loadModifiedShapes(theAlgo, theOldShape, theShapeTypeToExplore, theName);
+  }
+}
+
+void Model_ResultVolume::loadFirstLevel(GeomShapePtr theShape, const std::string& theName)
+{
+  if (mySubs.size()) { // consists of subs
+    for (std::vector<ResultVolumePtr>::const_iterator aSubIter = mySubs.cbegin();
+      aSubIter != mySubs.cend();
+      ++aSubIter)
+    {
+      const ResultVolumePtr& aSub = *aSubIter;
+      aSub->loadFirstLevel(theShape, theName);
+    }
+  } else { // do for this directly
+    myBuilder->loadFirstLevel(theShape, theName);
+  }
+}
+
+int Model_ResultVolume::numberOfSubs(bool /*forTree*/) const
+{
+  return int(mySubs.size());
+}
+
+ResultVolumePtr Model_ResultVolume::subResult(const int theIndex, bool /*forTree*/) const
+{
+  if (theIndex >= int(mySubs.size()))
+    return ResultVolumePtr();
+  return mySubs.at(theIndex);
+}
+
+bool Model_ResultVolume::isSub(ObjectPtr theResult, int& theIndex) const
+{
+  std::map<ObjectPtr, int>::const_iterator aFound = mySubsMap.find(theResult);
+  if (aFound != mySubsMap.end()) {
+    theIndex = aFound->second;
+    return true;
+  }
+  return false;
+}
+
+void Model_ResultVolume::colorConfigInfo(std::string& theSection, std::string& theName,
+  std::string& theDefault)
+{
+  theSection = "Visualization";
+  theName = "result_body_color";
+  theDefault = DEFAULT_COLOR();
+}
+
+bool Model_ResultVolume::setDisabled(std::shared_ptr<ModelAPI_Result> theThis, const bool theFlag)
+{
+  bool aChanged = ModelAPI_ResultVolume::setDisabled(theThis, theFlag);
+  if (aChanged) { // state is changed, so modifications are needed
+    updateSubs(shape(), false); // to set disabled/enabled
+  }
+  return aChanged;
+}
+
+bool Model_ResultVolume::isConcealed()
+{
+  return myLastConcealed;
+}
+
+void Model_ResultVolume::setIsConcealed(const bool theValue, const bool theForced)
+{
+  if (ModelAPI_ResultVolume::isConcealed() != theValue) {
+    ModelAPI_ResultVolume::setIsConcealed(theValue, theForced);
+    updateConcealment();
+  }
+}
+
+// recursively check all subs for concealment flag, returns true if everybody have "flag" state,
+// in theAll returns results with "flag" state
+static bool checkAllSubs(ResultVolumePtr theParent, bool theFlag, std::list<ResultVolumePtr>& theAll)
+{
+  if (theParent->isConcealed() != theFlag)
+    theAll.push_back(theParent);
+  bool aResult = theParent->ModelAPI_ResultVolume::isConcealed() == theFlag;
+  for(int a = 0; a < theParent->numberOfSubs(); a++) {
+    bool aSubRes = checkAllSubs(theParent->subResult(a), theFlag, theAll);
+    if (theFlag)
+      aResult = aResult || aSubRes; // concealed: one makes concealed everyone
+    else
+      aResult = aResult && aSubRes; // not concealed: all must be not concealed
+  }
+  return aResult;
+}
+
+void Model_ResultVolume::updateConcealment()
+{
+  if (myLastConcealed != ModelAPI_ResultVolume::isConcealed()) {
+    // check the whole tree of results: if one is concealed, everybody are concealed
+    ResultVolumePtr anOwner = std::dynamic_pointer_cast<ModelAPI_ResultVolume>(data()->owner());
+    if (!anOwner.get())
+      return; // "this" is invalid
+    ResultVolumePtr aParent = ModelAPI_Tools::volumeOwner(anOwner);
+    while(aParent.get()) {
+      anOwner = aParent;
+      aParent = ModelAPI_Tools::volumeOwner(anOwner);
+    }
+    // iterate all results and collect all results whose state may be updated
+    std::list<ResultVolumePtr> anUpdated;
+    bool aNewFlag = !myLastConcealed;
+    if (checkAllSubs(anOwner, aNewFlag, anUpdated)) { // state of everyone must be updated
+      std::list<ResultVolumePtr>::iterator aRes = anUpdated.begin();
+      for(; aRes != anUpdated.end(); aRes++) {
+        bool aLastConcealed = (*aRes)->isConcealed();
+        if (aNewFlag != aLastConcealed) {
+          std::dynamic_pointer_cast<Model_ResultVolume>(*aRes)->myLastConcealed = aNewFlag;
+          if (aNewFlag) { // become concealed, behaves like removed
+            ModelAPI_EventCreator::get()->sendDeleted(document(), groupName());
+          } else { // become not-concealed, behaves like created
+            static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_CREATED);
+            ModelAPI_EventCreator::get()->sendUpdated(*aRes, anEvent);
+          }
+          static Events_ID EVENT_DISP = // must be redisplayed in any case
+            Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY);
+          ModelAPI_EventCreator::get()->sendUpdated(*aRes, EVENT_DISP);
+        }
+      }
+    }
+  }
+}
+
+void Model_ResultVolume::addShapeColor( const std::wstring& theName,std::vector<int>& color) {
+
+  if (myColorsShape.find(theName) == myColorsShape.end())
+    myColorsShape[ theName ] =  color;
+}
+
+std::wstring Model_ResultVolume::addShapeName(std::shared_ptr<GeomAPI_Shape> theshape,
+                                            const std::wstring& theName ){
+
+  int indice = 1;
+  std::wstringstream aName;
+  aName << theName;
+  while(myNamesShape.find(aName.str()) != myNamesShape.end() ){
+    aName.str(L"");
+    aName << theName << L"__" << indice;
+    indice++;
+  }
+  myNamesShape[ aName.str() ] = theshape;
+
+  return aName.str();
+}
+
+std::wstring Model_ResultVolume::findShapeName(std::shared_ptr<GeomAPI_Shape> theShape){
+
+  TopoDS_Shape  aShape =  theShape->impl<TopoDS_Shape>();
+  for (std::map< std::wstring, std::shared_ptr<GeomAPI_Shape> >::iterator it =
+                                                                myNamesShape.begin();
+        it != myNamesShape.end();
+        ++it)
+  {
+    TopoDS_Shape curSelectedShape = (*it).second->impl<TopoDS_Shape>();
+    if ((aShape.IsSame(curSelectedShape)))  {
+      return (*it).first;
+    }
+  }
+  return  L"material not found" ;
+}
+
+void Model_ResultVolume::setShapeName(
+                std::map< std::wstring, std::shared_ptr<GeomAPI_Shape>>& theShapeName,
+                std::map< std::wstring, std::vector<int>>& theColorsShape)
+{
+  myNamesShape = theShapeName;
+  myColorsShape = theColorsShape;
+}
+
+void Model_ResultVolume::clearShapeNameAndColor(){
+  myNamesShape.clear();
+  myColorsShape.clear();
+}
+
+void Model_ResultVolume::updateSubs(const std::shared_ptr<GeomAPI_Shape>& theThisShape,
+                                  const bool theShapeChanged)
+{
+  static Events_Loop* aLoop = Events_Loop::loop();
+  static Events_ID EVENT_DISP = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY);
+  static Events_ID EVENT_UPD = aLoop->eventByName(EVENT_OBJECT_UPDATED);
+  static const ModelAPI_EventCreator* aECreator = ModelAPI_EventCreator::get();
+  // erase flag that topology is connected: the shape is new
+  if (theShapeChanged && data().get()) {
+    TDF_Label aDataLab = std::dynamic_pointer_cast<Model_Data>(data())->label();
+    if (!aDataLab.IsNull()) {
+      TDataStd_UAttribute::Set(aDataLab, kUpdateConnectedTopologyVolume);
+      isConnectedTopology(); // to store this flag in transaction, #2630
+    }
+  }
+  // iterate all sub-solids of compsolid to make sub-results synchronized with them
+  TopoDS_Shape aThisShape;
+  if (theThisShape.get()) aThisShape = theThisShape->impl<TopoDS_Shape>();
+  if (!aThisShape.IsNull() && (aThisShape.ShapeType() == TopAbs_COMPSOLID ||
+       aThisShape.ShapeType() == TopAbs_COMPOUND)) {
+    bool aWasEmpty = mySubs.empty();
+    Model_Objects* anObjects = std::dynamic_pointer_cast<Model_Document>(document())->objects();
+    unsigned int aSubIndex = 0;
+    TopoDS_Iterator aShapesIter(aThisShape);
+    for(; aShapesIter.More(); aShapesIter.Next(), aSubIndex++) {
+      std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape);
+      aShape->setImpl(new TopoDS_Shape(aShapesIter.Value()));
+      ResultVolumePtr aSub;
+      if (mySubs.size() <= aSubIndex) { // it is needed to create a new sub-result
+        std::wstring thenameshape = L"";
+        // find shape name read
+        for (std::map< std::wstring, std::shared_ptr<GeomAPI_Shape> >::iterator it =
+                                                                            myNamesShape.begin();
+           it != myNamesShape.end();
+           ++it)
+        {
+            TopoDS_Shape curSelectedShape = (*it).second->impl<TopoDS_Shape>();
+            if (!(aShapesIter.Value().IsSame(curSelectedShape))) continue;
+            thenameshape = (*it).first;
+            break;
+        }
+        aSub = anObjects->createVolume(this->data(), aSubIndex,thenameshape);
+        //finf color read
+        std::map< std::wstring, std::vector<int>>::iterator itColor =
+                                                          myColorsShape.find(thenameshape);
+        if (itColor != myColorsShape.end()){
+            ModelAPI_Tools::setColor(aSub,(*itColor).second);
+        }
+        aSub->setShapeName(myNamesShape,myColorsShape);
+        mySubs.push_back(aSub);
+        mySubsMap[aSub] = int(mySubs.size() - 1);
+        if (isConcealed()) { // for issue #2579 note7
+          aSub->ModelAPI_ResultVolume::setIsConcealed(true);
+          std::dynamic_pointer_cast<Model_ResultVolume>(aSub)->updateConcealment();
+        }
+
+      } else { // just update shape of this result
+        aSub = mySubs[aSubIndex];
+      }
+      GeomShapePtr anOldSubShape = aSub->shape();
+      if (!aShape->isEqual(anOldSubShape)) {
+        if (myAlgo.get()) {
+          std::list<GeomShapePtr> anOldForSub;
+          computeOldForSub(aShape, myOlds, anOldForSub);
+          myIsGenerated ? aSub->storeGenerated(anOldForSub, aShape, myAlgo) :
+            aSub->storeModified(anOldForSub, aShape, myAlgo);
+        } else {
+          aSub->store(aShape, false);
+        }
+        aECreator->sendUpdated(aSub, EVENT_DISP);
+        aECreator->sendUpdated(aSub, EVENT_UPD);
+      }
+      aSub->setDisabled(aSub, isDisabled());
+    }
+    // erase left, unused results
+    while(mySubs.size() > aSubIndex) {
+      ResultVolumePtr anErased = *(mySubs.rbegin());
+      if (anErased->ModelAPI_ResultVolume::isConcealed()) {
+        anErased->ModelAPI_ResultVolume::setIsConcealed(false);
+        std::dynamic_pointer_cast<Model_ResultVolume>(anErased)->updateConcealment();
+      }
+      anErased->setDisabled(anErased, true);
+      mySubsMap.erase(anErased);
+      mySubs.pop_back();
+    }
+    if (aWasEmpty) { // erase all subs
+      // redisplay this because result with and without subs are displayed differently
+      aECreator->sendUpdated(data()->owner(), EVENT_DISP);
+    }
+    cleanCash();
+  } else if (!mySubs.empty()) { // erase all subs
+    while(!mySubs.empty()) {
+      ResultVolumePtr anErased = *(mySubs.rbegin());
+      if (anErased->ModelAPI_ResultVolume::isConcealed()) {
+        anErased->ModelAPI_ResultVolume::setIsConcealed(false);
+        std::dynamic_pointer_cast<Model_ResultVolume>(anErased)->updateConcealment();
+      }
+      anErased->setDisabled(anErased, true); // even if it is invalid (to erase subs on abort/undo)
+      mySubs.pop_back();
+    }
+    mySubsMap.clear();
+    // redisplay this because result with and without subs are displayed differently
+    aECreator->sendUpdated(data()->owner(), EVENT_DISP);
+  }
+}
+
+void Model_ResultVolume::updateSubs(
+  const GeomShapePtr& theThisShape, const std::list<GeomShapePtr>& theOlds,
+  const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape, const bool isGenerated)
+{
+  myAlgo = theMakeShape;
+  myOlds = theOlds;
+  myIsGenerated = isGenerated;
+  // to avoid changing of "isDisabled" flag in the "updateSubs" cycle
+  isDisabled();
+
+  updateSubs(theThisShape, true);
+  myAlgo.reset();
+  myOlds.clear();
+  myHistoryCash.Clear();
+}
+
+void  Model_ResultVolume::setTextureFile(const std::string & theTextureFile)
+{
+  ModelAPI_Result::setTextureFile(theTextureFile);
+  for( auto sub : mySubs){
+    sub->setTextureFile(theTextureFile);
+  }
+  for(auto map : mySubsMap){
+    map.first->setTextureFile(theTextureFile);
+  }
+}
+
+bool Model_ResultVolume::isConnectedTopology()
+{
+  TDF_Label aDataLab = std::dynamic_pointer_cast<Model_Data>(data())->label();
+  if (!aDataLab.IsNull()) {
+    if (aDataLab.IsAttribute(kUpdateConnectedTopologyVolume)) { // recompute state
+      aDataLab.ForgetAttribute(kUpdateConnectedTopologyVolume);
+      GeomShapePtr aShape = shape();
+      if (aShape.get() && aShape->isConnectedTopology()) {
+        TDataStd_UAttribute::Set(aDataLab, kIsConnectedTopologyVolume);
+      } else {
+        aDataLab.ForgetAttribute(kIsConnectedTopologyVolume);
+      }
+    }
+    return aDataLab.IsAttribute(kIsConnectedTopologyVolume);
+  }
+  return false; // invalid case
+}
+
+void Model_ResultVolume::cleanCash()
+{
+  myBuilder->cleanCash();
+  for (std::vector<ResultVolumePtr>::const_iterator aSubIter = mySubs.cbegin();
+    aSubIter != mySubs.cend(); ++aSubIter)
+  {
+    const ResultVolumePtr& aSub = *aSubIter;
+    aSub->cleanCash();
+  }
+}
+
+// adds to the theSubSubs map all sub-shapes of theSub if it is compound of compsolid
+static void collectSubs(
+  const GeomShapePtr theSub, TopTools_MapOfShape& theSubSubs, const bool theOneLevelMore)
+{
+  if (theSub->isNull())
+    return;
+  if (theSubSubs.Add(theSub->impl<TopoDS_Shape>()))  {
+    bool aIsComp = theSub->isCompound() || theSub->isCompSolid();
+    if (aIsComp) {
+      for(GeomAPI_ShapeIterator anIter(theSub); anIter.more(); anIter.next())
+        collectSubs(anIter.current(), theSubSubs, theOneLevelMore);
+    } else if (theOneLevelMore) {
+      GeomAPI_Shape::ShapeType aSubType = GeomAPI_Shape::ShapeType(int(theSub->shapeType()) + 1);
+      if (aSubType == GeomAPI_Shape::SHAPE)
+        return;
+      if (aSubType == GeomAPI_Shape::SHELL)
+        aSubType = GeomAPI_Shape::FACE;
+      if (aSubType == GeomAPI_Shape::WIRE)
+        aSubType = GeomAPI_Shape::EDGE;
+
+      for(GeomAPI_ShapeExplorer anExp(theSub, aSubType); anExp.more(); anExp.next()) {
+        collectSubs(anExp.current(), theSubSubs, false);
+      }
+    }
+  }
+}
+
+void Model_ResultVolume::computeOldForSub(const GeomShapePtr& theSub,
+  const std::list<GeomShapePtr>& theAllOlds, std::list<GeomShapePtr>& theOldForSub)
+{
+  // the old can be also used for sub-shape of theSub; collect all subs of compound or compsolid
+  TopTools_MapOfShape aSubSubs;
+  collectSubs(theSub, aSubSubs, false);
+
+  std::list<GeomShapePtr>::const_iterator aRootOlds = theAllOlds.cbegin();
+  for (; aRootOlds != theAllOlds.cend(); aRootOlds++) {
+    // use sub-shapes of olds too if they are compounds or compsolids
+    TopTools_MapOfShape anOldSubs;
+    // iterate one level more (for intersection of solids this is face)
+    collectSubs(*aRootOlds, anOldSubs, true);
+    for (TopTools_MapOfShape::Iterator anOldIter(anOldSubs); anOldIter.More(); anOldIter.Next()) {
+      TopoDS_Shape anOldShape = anOldIter.Value();
+      if (anOldShape.ShapeType() == TopAbs_COMPOUND || anOldShape.ShapeType() == TopAbs_SHELL ||
+          anOldShape.ShapeType() == TopAbs_WIRE || anOldShape.ShapeType() == TopAbs_COMPSOLID)
+        continue; // container old-shapes are not supported by the history, may cause crash
+      GeomShapePtr anOldSub(new GeomAPI_Shape);
+      anOldSub->setImpl<TopoDS_Shape>(new TopoDS_Shape(anOldShape));
+
+      ListOfShape aNews;
+      if (myHistoryCash.IsBound(anOldShape)) {
+        const TopTools_ListOfShape& aList = myHistoryCash.Find(anOldShape);
+        for(TopTools_ListIteratorOfListOfShape anIter(aList); anIter.More(); anIter.Next()) {
+          GeomShapePtr aShape(new GeomAPI_Shape);
+          aShape->setImpl<TopoDS_Shape>(new TopoDS_Shape(anIter.Value()));
+          aNews.push_back(aShape);
+        }
+      } else {
+        myIsGenerated ? myAlgo->generated(anOldSub, aNews) : myAlgo->modified(anOldSub, aNews);
+        // MakeShape may return alone old shape if there is no history information for this input
+        if (aNews.size() == 1 && aNews.front()->isEqual(anOldSub))
+          aNews.clear();
+        // store result in the history
+        TopTools_ListOfShape aList;
+        for (ListOfShape::iterator aNewIter = aNews.begin(); aNewIter != aNews.end(); aNewIter++) {
+          aList.Append((*aNewIter)->impl<TopoDS_Shape>());
+        }
+        myHistoryCash.Bind(anOldShape, aList);
+      }
+
+      for (ListOfShape::iterator aNewIter = aNews.begin(); aNewIter != aNews.end(); aNewIter++) {
+        if (aSubSubs.Contains((*aNewIter)->impl<TopoDS_Shape>())) {
+          // check list already contains this sub
+          std::list<GeomShapePtr>::iterator aResIter = theOldForSub.begin();
+          for(; aResIter != theOldForSub.end(); aResIter++)
+            if ((*aResIter)->isSame(anOldSub))
+              break;
+          if (aResIter == theOldForSub.end())
+            theOldForSub.push_back(anOldSub); // found old used for new theSubShape creation
+          break;
+        }
+      }
+    }
+  }
+}
index 63e5684bb18069781563b421eaeecd5b7a2ee678..598e52db35eacb40cbb9fefcf4fe1d6d523e5c64 100644 (file)
 */
 class Model_ResultVolume : public ModelAPI_ResultVolume
 {
+  /// Sub-bodies if this is compsolid or compound: zero-based index to subs
+  std::vector<ResultVolumePtr> mySubs;
+  /// Also keep map of result to index in mySubs to facilitate speed of access from OB
+  std::map<ObjectPtr, int> mySubsMap;
+  /// Keeps the last state of the concealment flag in order to update it when needed.
+  bool myLastConcealed;
+  /// History information for update subs
+  std::shared_ptr<GeomAlgoAPI_MakeShape> myAlgo;
+  /// All old shapes used for the root result construction
+  std::list<GeomShapePtr> myOlds;
+  /// Information about the kind of the history information: modified or generated
+  bool myIsGenerated;
+  /// Map from old shape to list of new shapes, cash for computeOldForSub method
+  TopTools_DataMapOfShapeListOfShape myHistoryCash;
 
-  public:
-    /// Removes the stored builders
-    MODEL_EXPORT virtual ~Model_ResultVolume();
+public:
+
+  /// Removes the stored builders
+  MODEL_EXPORT virtual ~Model_ResultVolume();
+
+  /// Records the subshape newShape which was generated during a topological construction.
+  /// As an example, consider the case of a face generated in construction of a box.
+  MODEL_EXPORT virtual bool generated(const GeomShapePtr& theNewShape,
+    const std::string& theName, const bool theCheckIsInResult = true) override;
+
+  /// load generated shapes
+  MODEL_EXPORT
+  virtual void loadGeneratedShapes(const std::shared_ptr<GeomAlgoAPI_MakeShape>& theAlgo,
+                                   const GeomShapePtr& theOldShape,
+                                   const GeomAPI_Shape::ShapeType theShapeTypeToExplore,
+                                   const std::string& theName = "",
+                                   const bool theSaveOldIfNotInTree = false) override;
+
+  /// load modified shapes for sub-objects
+  MODEL_EXPORT
+  virtual void loadModifiedShapes(const std::shared_ptr<GeomAlgoAPI_MakeShape>& theAlgo,
+                                  const GeomShapePtr& theOldShape,
+                                  const GeomAPI_Shape::ShapeType theShapeTypeToExplore,
+                                  const std::string& theName = "") override;
+
+  /// load shapes of the first level (to be used during shape import)
+  MODEL_EXPORT virtual void loadFirstLevel(GeomShapePtr theShape, const std::string& theName);
+
+  /// Returns the number of sub-elements
+  MODEL_EXPORT virtual int numberOfSubs(bool forTree = false) const;
+
+  /// Returns the sub-result by zero-base index
+  MODEL_EXPORT virtual ResultVolumePtr subResult(const int theIndex,
+    bool forTree = false) const;
+
+  /// Returns true if feature or result belong to this composite feature as subs
+  /// Returns theIndex - zero based index of sub if found
+  MODEL_EXPORT virtual bool isSub(ObjectPtr theObject, int& theIndex) const;
+
+  /// Returns the parameters of color definition in the resources configuration manager
+  MODEL_EXPORT virtual void colorConfigInfo(std::string& theSection, std::string& theName,
+                                            std::string& theDefault);
+
+  /// Disables the result body: keeps the resulting shape as selection, but erases the underlaying
+  /// naming data structure if theFlag if false. Or restores every  thing on theFlag is true.
+  MODEL_EXPORT virtual bool setDisabled(std::shared_ptr<ModelAPI_Result> theThis,
+    const bool theFlag);
+
+  /// The compsolid is concealed if at least one of the sub is concealed
+  MODEL_EXPORT virtual bool isConcealed();
+
+  /// Sets all subs as concealed in the data tree (referenced by other objects)
+  MODEL_EXPORT virtual void setIsConcealed(const bool theValue, const bool theForced = false);
+
+  /// Returns true is the topology is connected.
+  MODEL_EXPORT virtual bool isConnectedTopology();
+
+  /// Cleans cash related to the already stored elements
+  MODEL_EXPORT virtual void cleanCash() override;
+
+  /// sets the texture file
+  MODEL_EXPORT virtual void  setTextureFile(const std::string & theTextureFile) override;
+
+
+protected:
+  /// Makes a body on the given feature
+  Model_ResultVolume();
+
+  /// Updates the sub-bodies if shape of this object is composite-solid
+  void updateSubs(const std::shared_ptr<GeomAPI_Shape>& theThisShape,
+                  const bool theShapeChanged = true);
+
+  /// Updates the sub-bodies in accordance to the algorithm history information
+  void updateSubs(
+    const GeomShapePtr& theThisShape, const std::list<GeomShapePtr>& theOlds,
+    const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape, const bool isGenerated);
+
+  /// Checks the state of children and parents to send events of creation/erase when needed
+  void updateConcealment();
+
+  /// Adds to theOldForSub only old shapes that where used for theSub creation
+  void computeOldForSub(const GeomShapePtr& theSub,
+    const std::list<GeomShapePtr>& theAllOlds, std::list<GeomShapePtr>& theOldForSub);
+
+  friend class Model_Objects;
+
+  /// Add shape Name for read shape in step file
+  std::wstring addShapeName(std::shared_ptr<GeomAPI_Shape>,const std::wstring& theName) override;
+
+  /// Add color for shape Name read shape in step file
+  void addShapeColor( const std::wstring& theName,std::vector<int>& color) override;
+
+  /// Set the map of name and color read shape in step file
+  void setShapeName(std::map< std::wstring,
+                              std::shared_ptr<GeomAPI_Shape>>& theShapeName,
+                              std::map< std::wstring,
+                              std::vector<int>>& theColorsShape) override;
+
+  /// find the name of shapp read in step file
+  std::wstring findShapeName(std::shared_ptr<GeomAPI_Shape> theShape) override;
+
+  /// Clear the map of name and color read shape in step file
+  void clearShapeNameAndColor() override;
+
+  /// map with the name read in step file and shape
+  std::map< std::wstring, std::shared_ptr<GeomAPI_Shape> > myNamesShape;
+
+  /// map with the name contruct and color read
+  std::map< std::wstring, std::vector<int>> myColorsShape;
 
-  protected:
-    /// Makes a body on the given feature
-    Model_ResultVolume();
 };
 
 #endif
index 5a8668f2a0602a47b7b6c8f7c87c6a21ad73dbc7..b9977abdfc74a37480b5299ccb91fd9fbe3e0685 100644 (file)
@@ -108,6 +108,7 @@ SET(PROJECT_SOURCES
     ModelAPI_Plugin.cpp
     ModelAPI_Result.cpp
     ModelAPI_ResultBody.cpp
+    ModelAPI_ResultVolume.cpp
     ModelAPI_ResultConstruction.cpp
     ModelAPI_ResultField.cpp
     ModelAPI_ResultGroup.cpp
diff --git a/src/ModelAPI/ModelAPI_ResultVolume.cpp b/src/ModelAPI/ModelAPI_ResultVolume.cpp
new file mode 100644 (file)
index 0000000..39537a7
--- /dev/null
@@ -0,0 +1,157 @@
+// 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
+//
+
+#include "ModelAPI_ResultVolume.h"
+
+#include <ModelAPI_BodyBuilder.h>
+#include <Events_Loop.h>
+#include <ModelAPI_Events.h>
+
+ModelAPI_ResultVolume::ModelAPI_ResultVolume()
+  : myBuilder(0)
+{
+  myConnect = ConnectionNotComputed;
+}
+
+ModelAPI_ResultVolume::~ModelAPI_ResultVolume()
+{
+}
+
+std::string ModelAPI_ResultVolume::groupName()
+{
+  return group();
+}
+
+void ModelAPI_ResultVolume::store(const GeomShapePtr& theShape,
+                                const bool theIsStoreSameShapes)
+{
+  myBuilder->store(theShape, theIsStoreSameShapes);
+  myConnect = ConnectionNotComputed;
+
+  static Events_Loop* aLoop = Events_Loop::loop();
+  static Events_ID aRedispEvent = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY);
+  static const ModelAPI_EventCreator* aECreator = ModelAPI_EventCreator::get();
+  aECreator->sendUpdated(data()->owner(), aRedispEvent);
+
+  updateSubs(theShape);
+}
+
+void ModelAPI_ResultVolume::storeGenerated(const GeomShapePtr& theFromShape,
+                                         const GeomShapePtr& theToShape)
+{
+  myBuilder->storeGenerated(theFromShape, theToShape);
+  myConnect = ConnectionNotComputed;
+
+  static Events_Loop* aLoop = Events_Loop::loop();
+  static Events_ID aRedispEvent = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY);
+  static const ModelAPI_EventCreator* aECreator = ModelAPI_EventCreator::get();
+  aECreator->sendUpdated(data()->owner(), aRedispEvent);
+
+  updateSubs(theToShape);
+}
+
+void ModelAPI_ResultVolume::storeGenerated(
+  const std::list<GeomShapePtr>& theFromShapes, const GeomShapePtr& theToShape,
+  const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape)
+{
+  myBuilder->storeGenerated(theFromShapes, theToShape, theMakeShape);
+  myConnect = ConnectionNotComputed;
+
+  static Events_Loop* aLoop = Events_Loop::loop();
+  static Events_ID aRedispEvent = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY);
+  static const ModelAPI_EventCreator* aECreator = ModelAPI_EventCreator::get();
+  aECreator->sendUpdated(data()->owner(), aRedispEvent);
+
+  updateSubs(theToShape, theFromShapes, theMakeShape, true);
+}
+
+void ModelAPI_ResultVolume::storeModified(const GeomShapePtr& theOldShape,
+                                        const GeomShapePtr& theNewShape,
+                                        const bool theIsCleanStored)
+{
+  myBuilder->storeModified(theOldShape, theNewShape, theIsCleanStored);
+  myConnect = ConnectionNotComputed;
+
+  static Events_Loop* aLoop = Events_Loop::loop();
+  static Events_ID aRedispEvent = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY);
+  static const ModelAPI_EventCreator* aECreator = ModelAPI_EventCreator::get();
+  aECreator->sendUpdated(data()->owner(), aRedispEvent);
+
+  updateSubs(theNewShape);
+}
+
+void ModelAPI_ResultVolume::storeModified(
+  const std::list<GeomShapePtr>& theOldShapes, const GeomShapePtr& theNewShape,
+  const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape)
+{
+  myBuilder->storeModified(theOldShapes, theNewShape, theMakeShape);
+  myConnect = ConnectionNotComputed;
+
+  static Events_Loop* aLoop = Events_Loop::loop();
+  static Events_ID aRedispEvent = aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY);
+  static const ModelAPI_EventCreator* aECreator = ModelAPI_EventCreator::get();
+  aECreator->sendUpdated(data()->owner(), aRedispEvent);
+
+  updateSubs(theNewShape, theOldShapes, theMakeShape, false);
+}
+
+GeomShapePtr ModelAPI_ResultVolume::shape()
+{
+  return myBuilder->shape();
+}
+
+void ModelAPI_ResultVolume::generated(const GeomShapePtr& theOldShape,
+                                    const GeomShapePtr& theNewShape,
+                                    const std::string& theName)
+{
+  myBuilder->generated(theOldShape, theNewShape, theName);
+}
+
+void ModelAPI_ResultVolume::modified(const GeomShapePtr& theOldShape,
+                                   const GeomShapePtr& theNewShape,
+                                   const std::string& theName)
+{
+  myBuilder->modified(theOldShape, theNewShape, theName);
+}
+
+
+void ModelAPI_ResultVolume::loadDeletedShapes(const GeomMakeShapePtr& theAlgo,
+                                            const GeomShapePtr& theOldShape,
+                                            const GeomAPI_Shape::ShapeType theShapeTypeToExplore,
+                                            const GeomShapePtr& theShapesToExclude)
+{
+  myBuilder->loadDeletedShapes(theAlgo, theOldShape, theShapeTypeToExplore, theShapesToExclude);
+}
+
+// LCOV_EXCL_START
+bool ModelAPI_ResultVolume::isConnectedTopology()
+{
+  if (myConnect == ConnectionNotComputed) {
+    myConnect = shape()->isConnectedTopology() ? IsConnected : IsNotConnected;
+  }
+  return myConnect == IsConnected;
+}
+
+void ModelAPI_ResultVolume::setDisplayed(const bool theDisplay)
+{
+  ModelAPI_Result::setDisplayed(theDisplay);
+  for (int i = 0; i < numberOfSubs(); i++)
+    subResult(i)->setDisplayed(theDisplay);
+}
+// LCOV_EXCL_STOP
index ad15c197fcba476374016bf929fd41eab592b1e3..3bf86b1a61469597eaa8c3ae53d56662483ae39e 100644 (file)
 #ifndef ModelAPI_ResultVolume_H_
 #define ModelAPI_ResultVolume_H_
 
-#include "ModelAPI_ResultBody.h"
+#include "ModelAPI_Result.h"
+#include <GeomAPI_Shape.h>
+#include <GeomAPI_DataMapOfShapeShape.h>
+#include <string>
+#include <map>
+#include <vector>
 
 class ModelAPI_BodyBuilder;
 class GeomAlgoAPI_MakeShape;
@@ -34,18 +39,175 @@ class GeomAlgoAPI_MakeShape;
 * of result must be optimized.
 * Also provides a container of sub-body result in case it is compound or compsolid.
 */
-class ModelAPI_ResultVolume : public ModelAPI_ResultBody
+class ModelAPI_ResultVolume : public ModelAPI_Result
 {
-       public:
+public:
+  /// Internal enumeration for storage the information of connected topology flag
+  enum ConnectedTopologyFlag {
+    ConnectionNotComputed, ///< not yet computed
+    IsConnected,           ///< the topology is connected
+    IsNotConnected         ///< the topology is connected
+  };
 
-               inline static std::string group()
-               {
-                       static std::string MY_GROUP = "Volumes";
-                       return MY_GROUP;
-               }
+protected:
+  /// Keeps (not persistently) the connected topology flag
+  ConnectedTopologyFlag myConnect;
 
-       protected:
-               ModelAPI_BodyBuilder* myBuilder; ///< provides the body processing in naming shape
+  ModelAPI_BodyBuilder* myBuilder; ///< provides the body processing in naming shape
+
+public:
+  MODELAPI_EXPORT virtual ~ModelAPI_ResultVolume();
+
+  /// Returns the group identifier of this result
+  MODELAPI_EXPORT virtual std::string groupName();
+
+  /// Returns the group identifier of this result
+  inline static std::string group()
+  {
+    static std::string MY_GROUP = "Volumes";
+    return MY_GROUP;
+  }
+
+  /// default color for a result body
+  inline static const std::string& DEFAULT_COLOR()
+  {
+    static const std::string RESULT_BODY_COLOR("200,200,230");
+    return RESULT_BODY_COLOR;
+  }
+
+  /// default deflection for a result body
+  inline static const std::string DEFAULT_DEFLECTION()
+  {
+    return "0.0001";
+  }
+
+  /// Returns the number of sub-elements
+  MODELAPI_EXPORT virtual int numberOfSubs(bool forTree = false) const = 0;
+
+  /// Returns the sub-result by zero-base index
+  MODELAPI_EXPORT virtual std::shared_ptr<ModelAPI_ResultVolume> subResult(
+    const int theIndex, bool forTree = false) const = 0;
+
+  /// Returns true if theResult belong to this composite result as sub.
+  /// Returns theIndex - zero based index of sub if found
+  MODELAPI_EXPORT virtual bool isSub(ObjectPtr theResult, int& theIndex) const = 0;
+
+  /// \brief Stores the shape (called by the execution method).
+  /// param[in] theShape shape to store.
+  /// param[in] theIsStoreSameShapes if false stores reference to the same shape
+  ///                                if it is already in document.
+  MODELAPI_EXPORT virtual void store(const GeomShapePtr& theShape,
+                                     const bool theIsStoreSameShapes = true);
+
+  /// Stores the generated shape (called by the execution method).
+  MODELAPI_EXPORT virtual void storeGenerated(const GeomShapePtr& theFromShape,
+                                              const GeomShapePtr& theToShape);
+
+  /// Stores the root modified shapes (called by the execution method).
+  MODELAPI_EXPORT virtual void storeGenerated(
+    const std::list<GeomShapePtr>& theFromShapes, const GeomShapePtr& theToShape,
+    const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape);
+
+  /// Stores the modified shape (called by the execution method).
+  MODELAPI_EXPORT virtual void storeModified(const GeomShapePtr& theOldShape,
+                                             const GeomShapePtr& theNewShape,
+                                             const bool theIsCleanStored = true);
+
+  /// Stores the root modified shapes (called by the execution method).
+  MODELAPI_EXPORT virtual void storeModified(
+    const std::list<GeomShapePtr>& theOldShapes, const GeomShapePtr& theNewShape,
+    const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape);
+
+  /// Returns the shape-result produced by this feature
+  MODELAPI_EXPORT virtual GeomShapePtr shape();
+
+  /// Records the subshape newShape which was generated during a topological construction.
+  /// As an example, consider the case of a face generated in construction of a box.
+  /// Returns true if it is stored correctly (the final shape contains this new sub-shape)
+  MODELAPI_EXPORT virtual bool generated(const GeomShapePtr& theNewShape,
+    const std::string& theName, const bool theCheckIsInResult = true) = 0;
+
+  /// Records the shape newShape which was generated from the shape oldShape during a topological
+  /// construction. As an example, consider the case of a face generated from an edge in
+  /// construction of a prism.
+  MODELAPI_EXPORT virtual void generated(const GeomShapePtr& theOldShape,
+                                         const GeomShapePtr& theNewShape,
+                                         const std::string& theName = "");
+
+  /// Records the shape newShape which is a modification of the shape oldShape.
+  /// As an example, consider the case of a face split or merged in a Boolean operation.
+  MODELAPI_EXPORT virtual void modified(const GeomShapePtr& theOldShape,
+                                        const GeomShapePtr& theNewShape,
+                                        const std::string& theName = "");
+
+  /// load deleted shapes
+  MODELAPI_EXPORT
+  virtual void loadDeletedShapes(const std::shared_ptr<GeomAlgoAPI_MakeShape>& theAlgo,
+                                 const GeomShapePtr& theOldShape,
+                                 const GeomAPI_Shape::ShapeType theShapeTypeToExplore,
+                                 const GeomShapePtr& theShapesToExclude = GeomShapePtr());
+
+  /// load and orient modified shapes
+  MODELAPI_EXPORT
+  virtual void loadModifiedShapes(const std::shared_ptr<GeomAlgoAPI_MakeShape>& theAlgo,
+                                  const GeomShapePtr& theOldShape,
+                                  const GeomAPI_Shape::ShapeType theShapeTypeToExplore,
+                                  const std::string& theName = "") = 0;
+
+  /// load and orient generated shapes
+  MODELAPI_EXPORT
+  virtual void loadGeneratedShapes(const std::shared_ptr<GeomAlgoAPI_MakeShape>& theAlgo,
+                                   const GeomShapePtr& theOldShape,
+                                   const GeomAPI_Shape::ShapeType theShapeTypeToExplore,
+                                   const std::string& theName = "",
+                                   const bool theSaveOldIfNotInTree = false) = 0;
+
+  /// load shapes of the first level (to be used during shape import)
+  MODELAPI_EXPORT virtual void loadFirstLevel(GeomShapePtr theShape,
+                                              const std::string& theName) = 0;
+
+  /// Returns true is the topology is connected.
+  MODELAPI_EXPORT virtual bool isConnectedTopology() = 0;
+
+  /// Set displayed flag to the result and all sub results
+  /// \param theDisplay a boolean value
+  MODELAPI_EXPORT virtual void setDisplayed(const bool theDisplay);
+
+  /// Updates the sub-bodies if shape of this object is compsolid or compound
+  MODELAPI_EXPORT virtual void updateSubs(const GeomShapePtr& theThisShape,
+    const bool theShapeChanged = true) = 0;
+
+  /// Updates the sub-bodies in accordance to the algorithm history information
+  MODELAPI_EXPORT virtual void updateSubs(
+    const GeomShapePtr& theThisShape, const std::list<GeomShapePtr>& theOlds,
+    const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape, const bool isGenerated) = 0;
+
+  /// Cleans cash related to the already stored elements
+  MODELAPI_EXPORT virtual void cleanCash() = 0;
+
+  /// Add shape Name for read shape in step file
+  MODELAPI_EXPORT virtual std::wstring addShapeName
+                              (std::shared_ptr<GeomAPI_Shape>,const std::wstring& theName) = 0;
+
+  /// Add color for shape Name read shape in step file
+  MODELAPI_EXPORT virtual void addShapeColor
+                              (const std::wstring& theName,std::vector<int>& theColor) = 0;
+
+  /// Set the map of name and color read shape in step file
+  MODELAPI_EXPORT virtual void setShapeName
+                          (std::map< std::wstring, std::shared_ptr<GeomAPI_Shape> > &theShapeName,
+                           std::map< std::wstring, std::vector<int>> & theColorsShape) = 0;
+
+  /// Clear the map of name and color read shape in step file
+  MODELAPI_EXPORT virtual void clearShapeNameAndColor() = 0;
+
+  /// find the name of shapp read in step file
+  MODELAPI_EXPORT virtual std::wstring findShapeName(std::shared_ptr<GeomAPI_Shape> theShape) = 0;
+
+
+protected:
+  /// Default constructor accessible only from Model_Objects
+  MODELAPI_EXPORT ModelAPI_ResultVolume();
 
 };
 
index 9b9a83531fc38acfda061e5208d52001049dfe19..b9d547f3a284aba0806e5d5be0a3f827140ef34a 100644 (file)
@@ -25,6 +25,7 @@
 #include <ModelAPI_AttributeDouble.h>
 #include <ModelAPI_AttributeSelectionList.h>
 #include <ModelAPI_ResultBody.h>
+#include <ModelAPI_ResultVolume.h>
 #include <ModelAPI_ResultParameter.h>
 #include <ModelAPI_ResultPart.h>
 #include <ModelAPI_ResultGroup.h>
@@ -304,6 +305,23 @@ int bodyIndex(const ResultPtr& theSub)
   return anIndex; // not found
 }
 
+ResultVolumePtr volumeOwner(const ResultPtr& theSub, const bool theRoot)
+{
+  if (theSub.get()) {
+    ObjectPtr aParent = theSub->document()->parent(theSub);
+    if (aParent.get()) {
+      if (theRoot) { // try to find parent of parent
+        ResultPtr aResultParent = std::dynamic_pointer_cast<ModelAPI_Result>(aParent);
+        ResultVolumePtr aGrandParent = volumeOwner(aResultParent, true);
+        if (aGrandParent.get())
+          aParent = aGrandParent;
+      }
+      return std::dynamic_pointer_cast<ModelAPI_ResultVolume>(aParent);
+    }
+  }
+  return ResultVolumePtr(); // not found
+}
+
 bool hasSubResults(const ResultPtr& theResult)
 {
   ResultBodyPtr aCompSolid = std::dynamic_pointer_cast<ModelAPI_ResultBody>(theResult);
index e740cd1c95c59801de766a54963eb8fc1f01fcf5..a74dc6568d1b0139cf7e793ab6f4a81b5db25ff1 100644 (file)
@@ -28,6 +28,7 @@ class ModelAPI_Feature;
 class ModelAPI_Result;
 class ModelAPI_ResultParameter;
 class ModelAPI_ResultBody;
+class ModelAPI_ResultVolume;
 
 class GeomAPI_Shape;
 class GeomAPI_ShapeHierarchy;
@@ -50,7 +51,7 @@ MODELAPI_EXPORT std::shared_ptr<GeomAPI_Shape> shape(
 MODELAPI_EXPORT std::string getFeatureError(const std::shared_ptr<ModelAPI_Feature>& theFeature);
 
 /*!
- * Searches for variable with name \param theName in \param theDocument. 
+ * Searches for variable with name \param theName in \param theDocument.
  * If found, set it value in the \param outValue and returns true.
  * theSearcher must be located later in the history than the found variable.
  */
@@ -114,6 +115,15 @@ MODELAPI_EXPORT std::shared_ptr<ModelAPI_ResultBody>
  */
 MODELAPI_EXPORT int bodyIndex(const std::shared_ptr<ModelAPI_Result>& theSub);
 
+/*!
+ * Returns the result - parent of this result.
+ * \param theSub the sub-element of composit result
+ * \param theRoot if it is true, returns the root father
+ * \returns null if it is not sub-element of composite
+ */
+MODELAPI_EXPORT std::shared_ptr<ModelAPI_ResultVolume>
+  volumeOwner(const std::shared_ptr<ModelAPI_Result>& theSub, const bool theRoot = false);
+
 /*!
 * Returns true if the result contains a not empty list of sub results.
 * It processes result compsolid.
index 5ef8b4bbbccdc9ade1c4f4832d0b03a04b5dd1a3..ac2c3bfe23d37c53009cfbc07f604d42027109bd 100644 (file)
 
 #include <OperaPlugin_Volume.h>
 
-#include <ModelAPI_Data.h>
-#include <ModelAPI_ResultBody.h>
-#include <ModelAPI_AttributeDouble.h>
-#include <ModelAPI_AttributeSelection.h>
-#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_AttributeInteger.h>
 #include <ModelAPI_AttributeString.h>
+#include <ModelAPI_AttributeSelectionList.h>
+#include <ModelAPI_AttributeIntArray.h>
+#include <ModelAPI_Data.h>
+#include <ModelAPI_Document.h>
+#include <ModelAPI_ResultVolume.h>
+#include <ModelAPI_Tools.h>
 
-#include <GeomAlgoAPI_PointBuilder.h>
-
-
-#include <ModelAPI_ResultPart.h>
-#include <GeomAPI_ShapeHierarchy.h>
-
-
+#include <sstream>
 #include <memory>
 #include <iostream>
 
@@ -44,26 +40,24 @@ OperaPlugin_Volume::OperaPlugin_Volume() // Nothing to do during instantiation
 //=================================================================================================
 void OperaPlugin_Volume::initAttributes()
 {
+  //Get Medium
   data()->addAttribute(OperaPlugin_Volume::MEDIUM(), ModelAPI_AttributeString::typeId());
-
-  // AttributeSelectionListPtr aList =
-  //   std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
-  //   OperaPlugin_Volume::LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
-
+  //Get Objects
   AttributeSelectionListPtr aList = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(
-    data()->addAttribute(OperaPlugin_Volume::LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
+    data()->addAttribute(LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
   aList->setWholeResultAllowed(true); // allow to select the whole result
-
 }
 
-#include <GeomAlgoAPI_MakeShapeList.h>
 //=================================================================================================
 void OperaPlugin_Volume::execute()
 {
   // Getting objects.
   std::cout << "Before" << std::endl;
 
-  std::cout << "EXECUTE" << std::endl;
+  if (results().empty() || firstResult()->isDisabled()) { // just create result if not exists
+    ResultPtr aGroup = document()->createVolume(data());
+    setResult(aGroup);
+  }
 
   std::cout << "After" << std::endl;
 }
index ccddc413d2e6e806fe79f3251afaba8c11ce2cd4..a13d2ff98abedc43377ec123e756eef86d52bc94 100644 (file)
@@ -164,27 +164,6 @@ void PrimitivesPlugin_Box::createBoxByTwoPoints()
   setResult(aResultBox, aResultIndex);
 }
 
-//=================================================================================================
-static void toto(std::shared_ptr<GeomAlgoAPI_Box> theBoxAlgo,
-                                        std::shared_ptr<ModelAPI_ResultVolume> theResultBox)
-{
-  // Load the result
-  theResultBox->store(theBoxAlgo->shape());
-
-  // Prepare the naming
-  theBoxAlgo->prepareNamingFaces();
-
-  // Insert to faces
-  std::map< std::string, std::shared_ptr<GeomAPI_Shape> > listOfFaces =
-    theBoxAlgo->getCreatedFaces();
-  for (std::map< std::string, std::shared_ptr<GeomAPI_Shape> >::iterator it = listOfFaces.begin();
-       it != listOfFaces.end();
-       ++it)
-  {
-    theResultBox->generated((*it).second, (*it).first);
-  }
-}
-
 //=================================================================================================
 void PrimitivesPlugin_Box::createBoxByOnePointAndDims()
 {
@@ -224,9 +203,9 @@ void PrimitivesPlugin_Box::createBoxByOnePointAndDims()
   }
 
   int aResultIndex = 0;
-  ResultVolumePtr aResultBox = document()->createVolume(data(), aResultIndex);
-  toto(aBoxAlgo, aResultBox);
-  setVolume(aResultBox, aResultIndex);
+  ResultBodyPtr aResultBox = document()->createBody(data(), aResultIndex);
+  loadNamingDS(aBoxAlgo, aResultBox);
+  setResult(aResultBox, aResultIndex);
 }
 
 //=================================================================================================