]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Fix for the issue #1799 : split faces in groups when move in history
authormpv <mpv@opencascade.com>
Wed, 21 Dec 2016 14:20:06 +0000 (17:20 +0300)
committermpv <mpv@opencascade.com>
Wed, 21 Dec 2016 14:20:06 +0000 (17:20 +0300)
src/Model/Model_AttributeSelection.cpp
src/Model/Model_AttributeSelection.h
src/Model/Model_AttributeSelectionList.cpp
src/Model/Model_Update.cpp
src/XGUI/CMakeLists.txt

index 2b3fe9b7850e20c4e765f16612469fe012c8e48a..6ffe934a62f5af16b46f2a0e86fdb13167bc323b 100644 (file)
@@ -11,6 +11,7 @@
 #include "Model_Document.h"
 #include "Model_SelectionNaming.h"
 #include <Model_Objects.h>
+#include <Model_AttributeSelectionList.h>
 #include <ModelAPI_Feature.h>
 #include <ModelAPI_ResultBody.h>
 #include <ModelAPI_ResultConstruction.h>
@@ -295,6 +296,7 @@ Model_AttributeSelection::Model_AttributeSelection(TDF_Label& theLabel)
   : myRef(theLabel)
 {
   myIsInitialized = myRef.isInitialized();
+  myParent = NULL;
 }
 
 void Model_AttributeSelection::setID(const std::string theID)
@@ -429,9 +431,6 @@ bool Model_AttributeSelection::update()
       aBuilder.Generated(aContext->shape()->impl<TopoDS_Shape>());
       std::shared_ptr<Model_Document> aMyDoc =
         std::dynamic_pointer_cast<Model_Document>(owner()->document());
-      //std::string aName = contextName(aContext);
-      //aMyDoc->addNamingName(aSelLab, aName);
-      //TDataStd_Name::Set(aSelLab, aName.c_str());
     }
     return setInvalidIfFalse(aSelLab, aContext->shape() && !aContext->shape()->isNull());
   }
@@ -461,10 +460,39 @@ bool Model_AttributeSelection::update()
       aNewShape = aSelector.NamedShape()->Get();
     }
     if (anOldShape.IsNull() || aNewShape.IsNull() ||
-        !anOldShape.IsEqual(aSelector.NamedShape()->Get())) // send updated if shape is changed
-      owner()->data()->sendAttributeUpdated(this);
+        !anOldShape.IsEqual(aSelector.NamedShape()->Get())) {
+      // shape type shoud not not changed: if shape becomes compound of such shapes, then split
+      if (myParent && !anOldShape.IsNull() && !aNewShape.IsNull() &&
+          anOldShape.ShapeType() != aNewShape.ShapeType() &&
+          aNewShape.ShapeType() == TopAbs_COMPOUND) {
+        TopTools_ListOfShape aSubs;
+        for(TopoDS_Iterator anExplorer(aNewShape); anExplorer.More(); anExplorer.Next()) {
+          if (!anExplorer.Value().IsNull() &&
+              anExplorer.Value().ShapeType() == anOldShape.ShapeType()) {
+            aSubs.Append(anExplorer.Value());
+          } else { // invalid case; bad result shape, so, impossible to split easily
+            aSubs.Clear();
+            break;
+          }
+        }
+        if (aSubs.Extent() > 1) { // ok to split
+          TopTools_ListIteratorOfListOfShape aSub(aSubs);
+          GeomShapePtr aSubSh(new GeomAPI_Shape);
+          aSubSh->setImpl(new TopoDS_Shape(aSub.Value()));
+          setValue(aContext, aSubSh);
+          for(aSub.Next(); aSub.More(); aSub.Next()) {
+            GeomShapePtr aSubSh(new GeomAPI_Shape);
+            aSubSh->setImpl(new TopoDS_Shape(aSub.Value()));
+            myParent->append(aContext, aSubSh);
+          }
+        }
+      }
+      owner()->data()->sendAttributeUpdated(this);  // send updated if shape is changed
+    }
     return aResult;
-  } else if (aContext->groupName() == ModelAPI_ResultConstruction::group()) {
+  }
+  
+  if (aContext->groupName() == ModelAPI_ResultConstruction::group()) {
     // construction: identification by the results indexes, recompute faces and
     // take the face that more close by the indexes
     ResultConstructionPtr aConstructionContext =
@@ -633,7 +661,7 @@ void Model_AttributeSelection::selectBody(
   TNaming_Selector aSel(selectionLabel());
   TopoDS_Shape aContext;
 
-  ResultBodyPtr aBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(myRef.value());
+  ResultBodyPtr aBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(theContext);//myRef.value()
   if (aBody) {
     aContext = aBody->shape()->impl<TopoDS_Shape>();
   } else {
@@ -694,6 +722,13 @@ void Model_AttributeSelection::selectBody(
       }
     }
     if (!isFound) { // sub-shape is not found in the up-to-date instance of the context shape
+      // if context is sub-result of compound/compsolid, selection of sub-shape better propagate to
+      // the main result (which is may be modified), case is in 1799
+      ResultCompSolidPtr aMain = ModelAPI_Tools::compSolidOwner(theContext);
+      if (aMain.get()) {
+        selectBody(aMain, theSubShape);
+        return;
+      }
       setInvalidIfFalse(aSelLab, false);
       Events_InfoMessage("Model_AttributeSelection",
         "Failed to select sub-shape already modified").send();
@@ -1151,15 +1186,6 @@ void Model_AttributeSelection::updateInHistory()
         aCurrentModifierFeat = aModifierFeat;
         TNaming_Iterator aPairIter(aNewNS);
         aNewShape = aPairIter.NewShape();
-        /*
-        // searching for sub-shape equivalent on the sub-label of the new context result
-        TDF_ChildIDIterator aNSIter(aNewNS->Label(), TNaming_NamedShape::GetID());
-        for(; aNSIter.More(); aNSIter.Next()) {
-          TNaming_Iterator aPairsIter(aNSIter.Value()->Label());
-          for(; aPairsIter.More(); aPairsIter.Next()) {
-            if (aSubShape->impl<TopoDS_Shape>().IsEqual()
-          }
-        }*/
         anIterate = true;
         break;
       } else if (aNewNS->Evolution() == TNaming_DELETE) { // a shape was deleted => result is null
@@ -1171,36 +1197,6 @@ void Model_AttributeSelection::updateInHistory()
         continue;
       }
     }
-
-    /*
-    TNaming_NewShapeIterator aModifIter(aPairIter.NewShape(), aContLab);
-    if (aModifIter.More()) aModifIter.Next(); // skip this shape result
-    for(; aModifIter.More(); aModifIter.Next()) {
-      ResultPtr aModifierObj = std::dynamic_pointer_cast<ModelAPI_Result>
-        (aDoc->objects()->object(aModifIter.Label().Father()));
-      if (!aModifierObj.get())
-        break;
-      FeaturePtr aModifierFeat = aDoc->feature(aModifierObj);
-      if (!aModifierFeat.get())
-        break;
-      if (aModifierFeat == aThisFeature || aDoc->objects()->isLater(aModifierFeat, aThisFeature))
-        break; // the modifier feature is later than this, so, should not be used
-      Handle(TNaming_NamedShape) aNewNS = aModifIter.NamedShape();
-      if (aNewNS->Evolution() == TNaming_MODIFY || aNewNS->Evolution() == TNaming_GENERATED) {
-        aModifierResFound = aModifierObj;
-      } else if (aNewNS->Evolution() == TNaming_DELETE) { // a shape was deleted => result is null
-        ResultPtr anEmptyContext;
-        std::shared_ptr<GeomAPI_Shape> anEmptyShape;
-        setValue(anEmptyContext, anEmptyShape); // nullify the selection
-        return;
-      } else { // not-precessed modification => don't support it
-        break;
-      }
-    }
-    // already found what is needed, don't iterate the next pair since normally
-    if (aModifierResFound.get()) //  there must be only one pair in the result-shape
-      break;
-    */
   }
   if (aModifierResFound.get()) {
     // update scope to reset to a new one
@@ -1208,38 +1204,9 @@ void Model_AttributeSelection::updateInHistory()
     myRef.setValue(aModifierResFound);
     update(); // it must recompute a new sub-shape automatically
   }
-  /*
-  if (aModifierResFound.get()) {
-    // update scope to reset to a new one
-    myScope.Clear();
-    if (!aSubShape.get() || aSubShape->isNull()) { // no sub-shape, so, just update a context
-      setValue(aModifierResFound, aSubShape);
-      return;
-    }
-    // seaching for the same sub-shape: the old topology stays the same
-    TopoDS_Shape anOldShape = aSubShape->impl<TopoDS_Shape>();
-    TopAbs_ShapeEnum aSubType = anOldShape.ShapeType();
-    TopoDS_Shape aNewContext = aModifierResFound->shape()->impl<TopoDS_Shape>();
-    TopExp_Explorer anExp(aNewContext, aSubType);
-    for(; anExp.More(); anExp.Next()) {
-      if (anExp.Current().IsEqual(anOldShape))
-        break;
-    }
-    if (anExp.More()) { // found
-      setValue(aModifierResFound, aSubShape);
-      return;
-    }
-    // seaching for the same sub-shape: equal geometry
-    for(anExp.Init(aNewContext, aSubType); anExp.More(); anExp.Next()) {
-      if (aSubType == TopAbs_VERTEX) {
-
-      }
-    }
-  }*/
-  // if sub-shape selection exists, search also sub-shape new instance
-  /*
-  GeomShapePtr aSubShape = value();
-  if (aSubShape.get() && aSubShape != aContext->shape()) {
+}
 
-  }*/
+void Model_AttributeSelection::setParent(Model_AttributeSelectionList* theParent)
+{
+  myParent = theParent;
 }
index 144ff01c957ce0593f39263db3d45c2ae988fdd9..a24ca2d818c6d3bc639862b9ce21e0d2f8c86eae 100644 (file)
 #include <ModelAPI_AttributeSelection.h>
 #include <TDF_LabelMap.hxx>
 
+class Model_AttributeSelectionList;
+
 /**\class Model_AttributeSelection
  * \ingroup DataModel
  * \brief Attribute that contains reference to the sub-shape of some result, the selected shape.
  */
-
 class Model_AttributeSelection : public ModelAPI_AttributeSelection
 {
   Model_AttributeReference myRef;  ///< The reference functionality reusage
@@ -25,6 +26,8 @@ class Model_AttributeSelection : public ModelAPI_AttributeSelection
   ResultPtr myTmpContext;
   /// temporarily storages to avoid keeping in the data structure if not needed
   std::shared_ptr<GeomAPI_Shape> myTmpSubShape;
+  /// Reference to the partent attribute, if any (to split selection compounds in issue 1799)
+  Model_AttributeSelectionList* myParent;
 public:
   /// Defines the result and its selected sub-shape
   /// \param theContext object where the sub-shape was selected
@@ -115,6 +118,9 @@ protected:
   /// Returns the name by context. Adds the part name if the context is located in other document
   std::string contextName(const ResultPtr& theContext) const;
 
+  /// Sets the parent attribute
+  void setParent(Model_AttributeSelectionList* theParent);
+
   friend class Model_Data;
   friend class Model_AttributeSelectionList;
 };
index d8ea9da5c0c6c12616dace412a2947b6b1d53a89..72e830852a424de3f5f87461d1b33b22f8b0e95b 100644 (file)
@@ -45,6 +45,7 @@ void Model_AttributeSelectionList::append(
     std::shared_ptr<Model_AttributeSelection>(new Model_AttributeSelection(aNewLab));
   if (owner()) {
     aNewAttr->setObject(owner());
+    aNewAttr->setParent(this);
   }
   aNewAttr->setID(id());
   mySize->Set(aNewTag);
@@ -66,6 +67,7 @@ void Model_AttributeSelectionList::append(
     std::shared_ptr<Model_AttributeSelection>(new Model_AttributeSelection(aNewLab));
   if (owner()) {
     aNewAttr->setObject(owner());
+    aNewAttr->setParent(this);
   }
   aNewAttr->setID(id());
   mySize->Set(aNewTag);
@@ -272,6 +274,7 @@ std::shared_ptr<ModelAPI_AttributeSelection>
   aNewAttr->setID(id());
   if (owner()) {
     aNewAttr->setObject(owner());
+    aNewAttr->setParent(this);
   }
   return aNewAttr;
 }
@@ -288,6 +291,7 @@ void Model_AttributeSelectionList::clear()
         std::shared_ptr<Model_AttributeSelection>(new Model_AttributeSelection(aLab));
       if (owner()) {
         aNewAttr->setObject(owner());
+        aNewAttr->setParent(this);
       }
       REMOVE_BACK_REF(aNewAttr->context());
 
index 6efd1b1a7578d4c1d84830531e8fcfa06c156d63..f95f59d7c0f81a202ca8d4f42d8eba5f1338feb4 100755 (executable)
@@ -445,6 +445,8 @@ bool Model_Update::processFeature(FeaturePtr theFeature)
       // too many repetition of processing (in VS it may crash on 330 with stack overflow)
       Events_InfoMessage("Model_Update",
         "Feature '%1' is updated in infinitive loop").arg(theFeature->data()->name()).send();
+      // to stop iteration
+      myModified.clear();
       return false;
     }
     myProcessed[theFeature] = aCount + 1;
index 7adccd4ebf73dbf309d2502227ffc1bcfa0bb558..83469a5d6a8b782ac35813005e66e8ede36231be 100644 (file)
@@ -129,7 +129,7 @@ SET(PROJECT_INCLUDES
     ${CAS_INCLUDE_DIRS}
     ${SUIT_INCLUDE})
 
-IF(${VInspectorAPI})
+IF(VInspectorAPI)
     message("VINSPECTOR is defined")
     SET(PROJECT_LIBRARIES ${PROJECT_LIBRARIES} ${VInspectorAPI})
     SET(PROJECT_INCLUDES ${PROJECT_INCLUDES} ${VINSPECTOR_INCLUDE_DIR})
@@ -141,7 +141,7 @@ IF(NOT ${HAVE_SALOME})
     SET(PROJECT_INCLUDES ${PROJECT_INCLUDES} ${APPELEMENTS_INCLUDE_DIR})
 ENDIF(NOT ${HAVE_SALOME})
 
-IF(${DFBrowserAPI})
+IF(DFBrowserAPI)
     message("DFBROWSER is defined")
     SET(PROJECT_LIBRARIES ${PROJECT_LIBRARIES} ${DFBrowserAPI})
     SET(PROJECT_INCLUDES ${PROJECT_INCLUDES} ${DFBROWSER_INCLUDE_DIR})