From bba22bcf3746bc39943df94c2e5cffa3f34316a0 Mon Sep 17 00:00:00 2001 From: mpv Date: Mon, 30 Dec 2019 17:16:41 +0300 Subject: [PATCH] Implementation of Groups support by the SHAPER-STUDY module --- .../ConnectorPlugin_PublishToStudyFeature.py | 69 ++++++++++++++++--- src/ModelAPI/ModelAPI_Tools.cpp | 49 +++++++++++++ src/ModelAPI/ModelAPI_Tools.h | 9 +++ 3 files changed, 119 insertions(+), 8 deletions(-) diff --git a/src/ConnectorPlugin/ConnectorPlugin_PublishToStudyFeature.py b/src/ConnectorPlugin/ConnectorPlugin_PublishToStudyFeature.py index a6b8d91e0..afa8cfdc2 100644 --- a/src/ConnectorPlugin/ConnectorPlugin_PublishToStudyFeature.py +++ b/src/ConnectorPlugin/ConnectorPlugin_PublishToStudyFeature.py @@ -23,13 +23,14 @@ 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) diff --git a/src/ModelAPI/ModelAPI_Tools.cpp b/src/ModelAPI/ModelAPI_Tools.cpp index 413f52c4c..54fa5488d 100644 --- a/src/ModelAPI/ModelAPI_Tools.cpp +++ b/src/ModelAPI/ModelAPI_Tools.cpp @@ -865,4 +865,53 @@ void copyVisualizationAttrs( } } +std::list referencedFeatures( + std::shared_ptr theTarget, const std::string& theFeatureKind, + const bool theSortResults) +{ + std::set aResSet; // collect in the set initially to avoid duplicates + std::list allSubRes; + allSubRes.push_back(theTarget); + ResultBodyPtr aBody = std::dynamic_pointer_cast(theTarget); + if (aBody.get()) + allSubs(aBody, allSubRes); + std::list::iterator aSub = allSubRes.begin(); + for(; aSub != allSubRes.end(); aSub++) { + const std::set& aRefs = (*aSub)->data()->refsToMe(); + std::set::const_iterator aRef = aRefs.cbegin(); + for(; aRef != aRefs.cend(); aRef++) { + FeaturePtr aFeat = std::dynamic_pointer_cast((*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& aRefs = aTargetFeature->data()->refsToMe(); + std::set::const_iterator aRef = aRefs.cbegin(); + for(; aRef != aRefs.cend(); aRef++) { + FeaturePtr aFeat = std::dynamic_pointer_cast((*aRef)->owner()); + if (aFeat.get() && (theFeatureKind.empty() || aFeat->getKind() == theFeatureKind)) + aResSet.insert(aFeat); + } + + std::list aResList; + std::set::iterator aResIter = aResSet.begin(); + for(; aResIter != aResSet.end(); aResIter++) { + if (theSortResults) { // sort results by creation-order + std::list::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 diff --git a/src/ModelAPI/ModelAPI_Tools.h b/src/ModelAPI/ModelAPI_Tools.h index b0af5520b..a91e62509 100644 --- a/src/ModelAPI/ModelAPI_Tools.h +++ b/src/ModelAPI/ModelAPI_Tools.h @@ -236,6 +236,15 @@ MODELAPI_EXPORT double getTransparency(const std::shared_ptr& t MODELAPI_EXPORT void copyVisualizationAttrs(std::shared_ptr theSource, std::shared_ptr 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 > referencedFeatures( + std::shared_ptr theTarget, const std::string& theFeatureKind, + const bool theSortResults); + } #endif -- 2.39.2