Salome HOME
Implementation of Groups support by the SHAPER-STUDY module
authormpv <mpv@opencascade.com>
Mon, 30 Dec 2019 14:16:41 +0000 (17:16 +0300)
committermpv <mpv@opencascade.com>
Mon, 30 Dec 2019 14:16:41 +0000 (17:16 +0300)
src/ConnectorPlugin/ConnectorPlugin_PublishToStudyFeature.py
src/ModelAPI/ModelAPI_Tools.cpp
src/ModelAPI/ModelAPI_Tools.h

index a6b8d91e0a8d8c3549cf6195ae5e7f3c10ce3700..afa8cfdc21aff19b91d5f3dda657f56187f8b28c 100644 (file)
 import ModelAPI
 import ExchangeAPI
 import EventsAPI
+from GeomAPI import *
+import GeomAlgoAPI
 
 import salome
 from salome.shaper import model
 
-import os
-
 import SHAPERSTUDY_ORB
+import SHAPERSTUDY_utils
 
 ## @ingroup Plugins
 #  Feature to export all shapes and groups into the GEOM module
@@ -71,7 +72,6 @@ class PublishToStudyFeature(ModelAPI.ModelAPI_Feature):
             return
         # find a shaper-study component
         salome.salome_init(1)
-        import SHAPERSTUDY_utils
         aComponent = SHAPERSTUDY_utils.findOrCreateComponent()
         anEngine = SHAPERSTUDY_utils.getEngine()
         # collect all processed internal entries to break the link of unprocessed later
@@ -97,14 +97,67 @@ class PublishToStudyFeature(ModelAPI.ModelAPI_Feature):
             if not aSShape.GetSO(): # publish in case it is a new shape
               anEngine.AddInStudy(aSShape, aRes.data().name(), None)
             else: # restore a red reference if it was deleted
-              aRes, aSO2 = aSShape.GetSO().FindSubObject(1)
-              if aRes:
-                aRes, aRef = aSO2.ReferencedObject()
-                if not aRes:
+              aDone, aSO2 = aSShape.GetSO().FindSubObject(1)
+              if aDone:
+                aDone, aRef = aSO2.ReferencedObject()
+                if not aDone:
                   aBuilder = SHAPERSTUDY_utils.getStudy().NewBuilder()
                   aBuilder.Addreference(aSO2, aSShape.GetSO())
-
             allProcessed.append(aSSEntry)
+            # Groups
+            allGroupsProcessed = []
+            aRefGroups = ModelAPI.referencedFeatures(aRes, "Group", True)
+            for aRef in aRefGroups:
+              aGroupIndices = []
+              aGroupHasIndex = {}
+              aResShape = aRes.shape()
+              aSelList = aRef.selectionList("group_list")
+              aSelType = GeomAPI_Shape.shapeTypeByStr(aSelList.selectionType())
+              for aSelIndex in range(aSelList.size()):
+                aSelection = aSelList.value(aSelIndex)
+                if aSelection.contextObject():
+                  aShape = aSelection.value()
+                  if aShape:
+                    allShapesList = [] # collect all sub-shapes selected in the group
+                    if aShape.shapeType() == 0: # compound
+                      anExplorer = GeomAPI_ShapeExplorer(aShape, aSelType)
+                      while anExplorer.more():
+                        allShapesList.append(anExplorer.current())
+                        anExplorer.next()
+                    else:
+                      allShapesList.append(aShape)
+                    # get index of each selected shape: if 0, this sub-shape is not in our result
+                    for aSelected in allShapesList:
+                      anId = GeomAlgoAPI.GeomAlgoAPI_CompoundBuilder.id(aResShape, aSelected)
+                      if anId > 0 and not anId in aGroupHasIndex:
+                        aGroupIndices.append(anId)
+                        aGroupHasIndex[anId] = 0
+              if len(aGroupIndices): # create group
+                aGroupOp = anEngine.GetIGroupOperations()
+                aGroupFeatureId = aRef.data().featureId()
+                aGroupEntry = "group" + str(aPartFeatureId) + ":" + str(aGroupFeatureId)
+                aGroup = aGroupOp.FindGroup(aSShape, aGroupEntry)
+                if not aGroup: # create a new
+                  aGroup = aGroupOp.CreateGroup(aSShape, aSelType)
+                  aGroup.SetEntry(aGroupEntry)
+                  anEngine.AddInStudy(aGroup, aRef.firstResult().data().name(), aSShape.GetSO())
+                aGroup.SetSelection(aGroupIndices)
+                # a group takes shape from the main result
+                #aGroup.SetShapeByStream(aRef.firstResult().shape().getShapeStream(False)) # group shape
+                allGroupsProcessed.append(aGroupEntry)
+            # check all existing groups: if some does not processed, remove it from the tree
+            aSOIter = SHAPERSTUDY_utils.getStudy().NewChildIterator(aSShape.GetSO())
+            while aSOIter.More():
+              aSO = aSOIter.Value()
+              anIOR = aSO.GetIOR()
+              if len(anIOR):
+                anObj = salome.orb.string_to_object(anIOR)
+                if isinstance(anObj, SHAPERSTUDY_ORB._objref_SHAPER_Group):
+                  anEntry = anObj.GetEntry()
+                  if anEntry not in allGroupsProcessed: # found a removed group => remove
+                    aBuilder = SHAPERSTUDY_utils.getStudy().NewBuilder()
+                    aBuilder.RemoveObject(anObj.GetSO())
+              aSOIter.Next()
 
         # process all SHAPER-STUDY shapes to find dead
         aSOIter = SHAPERSTUDY_utils.getStudy().NewChildIterator(aComponent)
index 413f52c4ce616edd2c2e4cb49f84f0621dde2737..54fa5488d558f913289bad9707bbdebe9486d284 100644 (file)
@@ -865,4 +865,53 @@ void copyVisualizationAttrs(
   }
 }
 
+std::list<FeaturePtr> referencedFeatures(
+  std::shared_ptr<ModelAPI_Result> theTarget, const std::string& theFeatureKind,
+  const bool theSortResults)
+{
+  std::set<FeaturePtr> aResSet; // collect in the set initially to avoid duplicates
+  std::list<ResultPtr> allSubRes;
+  allSubRes.push_back(theTarget);
+  ResultBodyPtr aBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(theTarget);
+  if (aBody.get())
+    allSubs(aBody, allSubRes);
+  std::list<ResultPtr>::iterator aSub = allSubRes.begin();
+  for(; aSub != allSubRes.end(); aSub++) {
+    const std::set<AttributePtr>& aRefs = (*aSub)->data()->refsToMe();
+    std::set<AttributePtr>::const_iterator aRef = aRefs.cbegin();
+    for(; aRef != aRefs.cend(); aRef++) {
+      FeaturePtr aFeat = std::dynamic_pointer_cast<ModelAPI_Feature>((*aRef)->owner());
+      if (aFeat.get() && (theFeatureKind.empty() || aFeat->getKind() == theFeatureKind))
+        aResSet.insert(aFeat);
+    }
+  }
+  // add also feature of the target that may be referenced as a whole
+  FeaturePtr aTargetFeature = theTarget->document()->feature(theTarget);
+  const std::set<AttributePtr>& aRefs = aTargetFeature->data()->refsToMe();
+  std::set<AttributePtr>::const_iterator aRef = aRefs.cbegin();
+  for(; aRef != aRefs.cend(); aRef++) {
+    FeaturePtr aFeat = std::dynamic_pointer_cast<ModelAPI_Feature>((*aRef)->owner());
+    if (aFeat.get() && (theFeatureKind.empty() || aFeat->getKind() == theFeatureKind))
+      aResSet.insert(aFeat);
+  }
+
+  std::list<FeaturePtr> aResList;
+  std::set<FeaturePtr>::iterator aResIter = aResSet.begin();
+  for(; aResIter != aResSet.end(); aResIter++) {
+    if (theSortResults) { // sort results by creation-order
+      std::list<FeaturePtr>::iterator aListIter = aResList.begin();
+      for(; aListIter != aResList.end(); aListIter++) {
+        if ((*aResIter)->document()->isLater(*aListIter, *aResIter))
+          break;
+      }
+      if (aListIter == aResList.end()) // goes to the end
+        aResList.push_back(*aResIter);
+      else
+        aResList.insert(aListIter, *aResIter);
+    } else //just push to the end unsorted
+      aResList.push_back(*aResIter);
+  }
+  return aResList;
+}
+
 } // namespace ModelAPI_Tools
index b0af5520bae730e1b3a1252f24df5a358bb42e70..a91e6250962e2a6feb5536760b643528850402c3 100644 (file)
@@ -236,6 +236,15 @@ MODELAPI_EXPORT double getTransparency(const std::shared_ptr<ModelAPI_Result>& t
 MODELAPI_EXPORT void copyVisualizationAttrs(std::shared_ptr<ModelAPI_Result> theSource,
                                             std::shared_ptr<ModelAPI_Result> theDest);
 
+/*! Produces list of features that reference to the given target (directly or through sub-results)
+* \param theTarget the referenced result
+* \param theFeatureKind the resulting features filter: the feature kind or all for the empty string
+* \param theSortResults to sort the resulting list of features by the features creation order
+*/
+MODELAPI_EXPORT std::list<std::shared_ptr<ModelAPI_Feature> > referencedFeatures(
+  std::shared_ptr<ModelAPI_Result> theTarget, const std::string& theFeatureKind,
+  const bool theSortResults);
+
 }
 
 #endif