]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
refactor ConnectorPlugin: split PublishToStudy in redable methods.
authorSONOLET Aymeric <aymeric.sonolet@cea.fr>
Fri, 24 Nov 2023 17:55:06 +0000 (18:55 +0100)
committerSONOLET Aymeric <aymeric.sonolet@cea.fr>
Wed, 14 Feb 2024 17:07:35 +0000 (18:07 +0100)
refactor ConnectorPlugin: integrate PublishToStudy split functions into
the class

src/ConnectorPlugin/ConnectorPlugin_PublishToStudyFeature.py

index 98bcdd5b59e5f0d37bb8f354576a82c2c38b0b4c..7eaa6b278e3359471dab2ce29e9e044342be7290 100644 (file)
 ## @package Plugins
 #  ExportFeature class definition
 
-import ModelAPI
-import EventsAPI
-import GeomAPI
-import GeomAlgoAPI
-
 import SHAPERSTUDY_ORB
 import SHAPERSTUDY_utils
 
 import salome
 from salome.shaper import model
 
+import EventsAPI
+import ModelAPI
+import GeomAPI
+import GeomAlgoAPI
+
 
-## @ingroup Plugins
-#  Feature to export all shapes and groups into the GEOM module
+# @ingroup Plugins
+#  Feature to export all shapes and groups into the SHAPERSTUDY module
 class PublishToStudyFeature(ModelAPI.ModelAPI_Feature):
     """
     Feature to export all shapes into SHAPERSTUDY module.
     """
 
-    ## The constructor.
+    # The constructor.
     def __init__(self):
         ModelAPI.ModelAPI_Feature.__init__(self)
+        self.engine = None
+        self.partSet = None
+        self.currentPartFeatureId = None
+        self.currentShaperShape = None
+        # collect all processed internal entries to break the link of
+        # unprocessed later
+        self.allProcessed = set()
 
     @staticmethod
-    ## Export kind. Static.
+    # Export kind. Static.
     def ID():
         return "PublishToStudy"
 
-    ## Returns the kind of a feature.
+    # Returns the kind of a feature.
     def getKind(self):
         return PublishToStudyFeature.ID()
 
-    ## This feature is action: has no property panel and executes immediately.
+    # This feature is action: has no property panel and executes immediately.
     def isAction(self):
         return True
 
-    ## This feature has no attributes, as it is action.
+    # This feature has no attributes, as it is action.
     def initAttributes(self):
         pass
 
-    ## Exports all shapes and groups into the GEOM module.
+    # Exports all shapes and groups into the SHAPERSTUDY module.
     def execute(self):
-        aSession = ModelAPI.ModelAPI_Session.get()
-        aPartSet = aSession.moduleDocument()
-        # check that the PartSet document current feature is the last to avoid problems with all
-        # features update
-        if aPartSet.size(model.ModelAPI_Feature.group()) > 0:
-            aLastFeature = ModelAPI.objectToFeature(
-                aPartSet.object(
+        """Exports all shapes and groups into the SHAPERSTUDY module."""
+        session = ModelAPI.ModelAPI_Session.get()
+        self.partSet = session.moduleDocument()
+        # check that the PartSet document current feature is the last to avoid
+        # problems with all features update
+        if self.partSet.size(model.ModelAPI_Feature.group()) > 0:
+            lastFeature = ModelAPI.objectToFeature(
+                self.partSet.object(
                     model.ModelAPI_Feature.group(),
-                    aPartSet.size(model.ModelAPI_Feature.group()) - 1,
+                    self.partSet.size(model.ModelAPI_Feature.group()) - 1,
                 )
             )
-            aCurrentFeature = aPartSet.currentFeature(True)
-            if aLastFeature.data().featureId() != aCurrentFeature.data().featureId():
+            currentFeature = self.partSet.currentFeature(True)
+            if (
+                lastFeature.data().featureId()
+                != currentFeature.data().featureId()
+            ):
                 EventsAPI.Events_InfoMessage(
                     "PublishToStudy",
-                    "Not all PartSet parts are up-to-date, nothing is published. Please, make the last PartSet feature as current.",
+                    "Not all PartSet parts are up-to-date, nothing is "
+                    "published. Please, make the last PartSet feature as "
+                    "current.",
                     self,
                 ).send()
                 return
         # find a shaper-study component
         salome.salome_init(embedded=True)
-        anEngine = SHAPERSTUDY_utils.getEngine()
-        # collect all processed internal entries to break the link of unprocessed later
-        allProcessed = []
-
-        # iterate all parts and all results to publish them in SHAPER_STUDY
-        for aPartId in range(aPartSet.size(model.ModelAPI_ResultPart.group())):
-            aPartObject = aPartSet.object(model.ModelAPI_ResultPart.group(), aPartId)
-            aPartRes = ModelAPI.modelAPI_ResultPart(
-                ModelAPI.modelAPI_Result(aPartObject)
+        self.engine = SHAPERSTUDY_utils.getEngine()
+
+        # iterate all parts and all results to publish them in SHAPERSTUDY
+        self._publishToShaperStudy()
+
+        self._findDeadShapesInShaperStudy()
+
+    def _publishToShaperStudy(self):
+        """
+        Iterate all parts and all results to publish them in SHAPERSTUDY.
+        """
+        # TODO: iterate only on changed parts.
+        for partId in range(
+            self.partSet.size(model.ModelAPI_ResultPart.group())
+        ):
+            partObject = self.partSet.object(
+                model.ModelAPI_ResultPart.group(), partId
             )
-            aPartDoc = aPartRes.partDoc()
-            if aPartDoc is None and aPartObject is not None:
+            partRes = ModelAPI.modelAPI_ResultPart(
+                ModelAPI.modelAPI_Result(partObject)
+            )
+            partDoc = partRes.partDoc()
+            if partDoc is None and partObject is not None:
                 EventsAPI.Events_InfoMessage(
                     "PublishToStudy",
                     "To publish to SHAPER-STUDY, activate Parts in SHAPER",
                     self,
                 ).send()
                 break
-            aPartFeatureId = aPartSet.feature(aPartRes.original()).data().featureId()
-            # Collects all features of exported results to find results of the same features and extend id.
-            # Map from feature index to index of result. If index is zero (initial), no surrfix to entry is added.
-            allProcessed += fromFeatureToRes(aPartDoc, anEngine, aPartFeatureId)
+            processedEntries = self._publishPartToShaperStudy(partDoc, partRes)
+            self.allProcessed.update(processedEntries)
 
-        # process all SHAPER-STUDY shapes to find dead
-        aComponent = SHAPERSTUDY_utils.findOrCreateComponent()
-        aSOIter = SHAPERSTUDY_utils.getStudy().NewChildIterator(aComponent)
-        processAllSO(aSOIter, allProcessed)
+    def _findDeadShapesInShaperStudy(self):
+        """
+        Process all SHAPERSTUDY shapes (sOIter) to find dead shapes and mark
+        them.
 
+        Parameters
+        ----------
+        sOIter:
+            The iterator on all SHAPERSTUDY shapes
+        allProcessed:
+            set of entry processed during calls to `fromFeatureToRes`
+        """
+        component = SHAPERSTUDY_utils.findOrCreateComponent()
+        sOIter = SHAPERSTUDY_utils.getStudy().NewChildIterator(component)
+        while sOIter.More():
+            sO = sOIter.Value()
+            sOIter.Next()  # here because there is continue inside the loop
+            iOR = sO.GetIOR()
+            if len(iOR) == 0:
+                continue
+            obj = salome.orb.string_to_object(iOR)
+            if not isinstance(obj, SHAPERSTUDY_ORB._objref_SHAPER_Object):
+                continue
+            entry = obj.GetEntry()
+            if len(entry) == 0:
+                continue
+            if (
+                entry not in self.allProcessed
+            ):  # found a removed shape: make it dead for the moment
+                # remove the reference - red node
+                res, sO2 = sO.FindSubObject(1)
+                if res:
+                    res, _ = sO2.ReferencedObject()
+                    if res:
+                        builder = SHAPERSTUDY_utils.getStudy().NewBuilder()
+                        builder.RemoveReference(sO2)
+                # if the object is not marked as dead, mark it (#3201) to
+                # make all entries unique
+                deadEntry = obj.GetEntry()
+                if not deadEntry.startswith("dead"):
+                    index = sO.Tag()
+                    obj.SetEntry("dead0" + str(index) + "_" + deadEntry)
+                    # also for groups
+                    self._manageDeadGroups(sO)
 
-def fromFeatureToRes(thePartDoc, theEngine, thePartFeatureId):
-    """
-    Collects all features of exported results to find results of the same
-    features and extend id.  Map from feature index to index of result. If
-    index is zero (initial), no surrfix to entry is added.
-
-    Parameters
-    ------
-    thePartDoc:
-        SHAPER PartRes Document
-    theEngine:
-        CORBA Engine
-    thePartFeatureId:
-        part feature Id
-
-    Returns
-    -------
-    list:
-        the list of processed ShaperStudy entries
-    """
-    processed = []
-    aFeaturesIndices = {}
-    for aResId in range(thePartDoc.size(model.ModelAPI_ResultBody.group())):
-        aResObject = thePartDoc.object(model.ModelAPI_ResultBody.group(), aResId)
-        aRes = model.objectToResult(aResObject)
-        # do not export images
-        if aRes.hasTexture() is True:
-            continue
-        aResFeatureId = str(thePartDoc.feature(aRes).data().featureId())
-        if aResFeatureId in aFeaturesIndices:
-            aFeaturesIndices[aResFeatureId] += 1
-            aResFeatureId += ":" + str(aFeaturesIndices[aResFeatureId])
+    def _publishPartToShaperStudy(self, partDoc, partRes):
+        """
+        Collects all features of exported results to find results of the same
+        features and extend id.  Map from feature index to index of result. If
+        index is zero (initial), no surrfix to entry is added.
+
+        Parameters
+        ----------
+        partDoc:
+            SHAPER PartRes Document
+        partFeatureId:
+            part feature Id
+
+        Returns
+        -------
+        set:
+            a set of processed ShaperStudy entries
+        """
+        self.currentPartFeatureId = (
+            self.partSet.feature(partRes.original()).data().featureId()
+        )
+        processed = set()
+        featuresIndices = {}
+        for resId in range(partDoc.size(model.ModelAPI_ResultBody.group())):
+            resObject = partDoc.object(
+                model.ModelAPI_ResultBody.group(), resId
+            )
+            res = model.objectToResult(resObject)
+            # do not export images
+            if res.hasTexture() is True:
+                continue
+            resFeatureId = str(partDoc.feature(res).data().featureId())
+
+            sSEntry = self._processRes(res, resFeatureId, featuresIndices)
+            processed.add(sSEntry)
+
+            self._processGroups(res)
+            self._processFields(res)
+
+        return processed
+
+    def _processRes(self, res, resFeatureId, featuresIndices):
+        if resFeatureId in featuresIndices:
+            featuresIndices[resFeatureId] += 1
+            resFeatureId += ":" + str(featuresIndices[resFeatureId])
         else:
-            aFeaturesIndices[aResFeatureId] = 0
-        aSSEntry = str(thePartFeatureId) + ":" + aResFeatureId
-        aSShape = theEngine.FindOrCreateShape(aSSEntry)
-        aSShape.SetShapeByStream(aRes.shape().getShapeStream(False))
-        if not aSShape.GetSO():  # publish in case it is a new shape
-            theEngine.AddInStudy(aSShape, aRes.data().name(), None)
+            featuresIndices[resFeatureId] = 0
+        sSEntry = str(self.currentPartFeatureId) + ":" + resFeatureId
+        self.currentShaperShape = self.engine.FindOrCreateShape(sSEntry)
+        self.currentShaperShape.SetShapeByStream(
+            res.shape().getShapeStream(False)
+        )
+        if (
+            not self.currentShaperShape.GetSO()
+        ):  # publish in case it is a new shape
+            self.engine.AddInStudy(
+                self.currentShaperShape, res.data().name(), None
+            )
         else:  # restore a red reference if it was deleted
-            aDone, aSO2 = aSShape.GetSO().FindSubObject(1)
-            if aDone:
-                aDone, _ = aSO2.ReferencedObject()
-                if not aDone:
-                    aBuilder = SHAPERSTUDY_utils.getStudy().NewBuilder()
-                    aBuilder.Addreference(aSO2, aSShape.GetSO())
-        processed.append(aSSEntry)
-        # Groups
-        processGroups(aRes, theEngine, thePartFeatureId, aSShape, False)
-        # Fields
-        processGroups(aRes, theEngine, thePartFeatureId, aSShape, True)
-    return processed
-
-
-# Part of the "execute" method: processes the Groups of theRes result publication.
-# If theFields is true, the same is performed for Fields.
-def processGroups(theRes, theEngine, thePartFeatureId, theStudyShape, theFields):
-    allGroupsProcessed = []
-    allRefGroups = []
-    if theFields:
-        allRefGroups.append(ModelAPI.referencedFeatures(theRes, "Field", True))
-    else:
-        allRefGroups.append(ModelAPI.referencedFeatures(theRes, "Group", True))
-        allRefGroups.append(ModelAPI.referencedFeatures(theRes, "Shared_faces", True))
-    aResShape = theRes.shape()
-    aMapOfShape = GeomAlgoAPI.GeomAPI_IndexedMapOfShape(aResShape)
-    for aRefGroups in allRefGroups:
-        for aRef in aRefGroups:
-            aGroupIndices = []
-            aGroupHasIndex = {}
-            if theFields:
-                aSelList = aRef.selectionList("selected")
-            else:
-                aSelList = aRef.selectionList("group_list")
-            aSelType = GeomAPI.GeomAPI_Shape.shapeTypeByStr(aSelList.selectionType())
-            for aGroupRes in aRef.results():
-                aShape = aGroupRes.shape()
-                anExplorer = GeomAPI.GeomAPI_ShapeExplorer(aShape, aSelType)
-                while anExplorer.more():
-                    anId = aMapOfShape.FindIndexEqualLocations(anExplorer.current())
-                    if anId > 0 and anId not in aGroupHasIndex:
-                        aGroupIndices.append(anId)
-                        aGroupHasIndex[anId] = 0
-                    anExplorer.next()
-            if len(aGroupIndices) > 0:  # create group
-                aGroupFeatureId = aRef.data().featureId()
-                if theFields:
-                    aFieldOp = theEngine.GetIFieldOperations()
-                    aGroupEntry = (
-                        "field" + str(thePartFeatureId) + ":" + str(aGroupFeatureId)
-                    )
-                    aGroup = aFieldOp.FindField(theStudyShape, aGroupEntry)
-                else:
-                    aGroupOp = theEngine.GetIGroupOperations()
-                    aGroupEntry = (
-                        "group" + str(thePartFeatureId) + ":" + str(aGroupFeatureId)
-                    )
-                    aGroup = aGroupOp.FindGroup(theStudyShape, aGroupEntry)
-                if not aGroup:  # create a new
-                    if theFields:
-                        aGroup = aFieldOp.CreateFieldByType(theStudyShape, aSelType)
-                    else:
-                        aGroup = aGroupOp.CreateGroup(theStudyShape, aSelType)
-                    aGroup.SetEntry(aGroupEntry)
-                    theEngine.AddInStudy(
-                        aGroup, aRef.firstResult().data().name(), theStudyShape
-                    )
-                aGroup.SetSelection(aGroupIndices)
-                if theFields:
-                    fillField(aGroup, aRef, theEngine, 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(theStudyShape.GetSO())
-    while aSOIter.More():
-        aSO = aSOIter.Value()
-        anIOR = aSO.GetIOR()
-        if len(anIOR) > 0:
-            anObj = salome.orb.string_to_object(anIOR)
-            if (
-                theFields and isinstance(anObj, SHAPERSTUDY_ORB._objref_SHAPER_Field)
-            ) or (
-                not theFields and type(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()
-
-
-# Part of the "execute" method: theFiled fields filling.
-def fillField(theField, theFeature, theEngine, theSelectionIndices):
-    aTables = theFeature.tables("values")
-    aValType = aTables.type()  # type of the values
-    aValTypeToSet = aValType
-    if (
-        aValType == 3
-    ):  # strings do not supported by SMESH, so, make them empty boolean table
-        aValTypeToSet = 0
-    theField.SetValuesType(aValTypeToSet)
-    aNumSteps = aTables.tables()  # number of steps is number of tables
-    aSteps = []
-    for aVal in range(aNumSteps):
-        aSteps.append(aVal + 1)
-    theField.SetSteps(aSteps)
-    aCompNames = []
-    aCompNamesAttr = theFeature.stringArray("components_names")
-    for anIndex in range(aCompNamesAttr.size()):
-        aCompNames.append(aCompNamesAttr.value(anIndex))
-    theField.SetComponents(aCompNames)
-    # prepare the sub-shapes indices: all values for all sub-shapes must be defined
-    aShapeOp = theEngine.GetIShapesOperations()
-    allIndices = aShapeOp.GetAllSubShapesIDs(
-        theField.GetShape(), theField.GetSelectionType(), False
-    )
-    # define steps
-    theField.ClearFieldSteps()
-    for aVal in range(aNumSteps):
-        aVals = []
-        for aCol in range(aTables.columns()):
-            # for aRow in range(aTables.rows()):
-            for anIndex in allIndices:
-                if anIndex in theSelectionIndices:
-                    aRow = (
-                        theSelectionIndices.index(anIndex) + 1
-                    )  # starting from the first line
-                else:
-                    aRow = 0  # default value
-                aStrVal = aTables.valueStr(aRow, aCol, aVal)
-                if aValType == 0:  # boolean
-                    if aStrVal == "True":
-                        aVals.append(1)
-                    else:
-                        aVals.append(0)
-                elif aValType == 1:  # int
-                    aVals.append(int(aStrVal))
-                elif aValType == 2:  # double
-                    aVals.append(float(aStrVal))
-        theField.AddFieldStep(
-            theFeature.intArray("stamps").value(aVal), aVal + 1, aVals
+            done, sO2 = self.currentShaperShape.GetSO().FindSubObject(1)
+            if done:
+                done, _ = sO2.ReferencedObject()
+                if not done:
+                    builder = SHAPERSTUDY_utils.getStudy().NewBuilder()
+                    builder.Addreference(sO2, self.currentShaperShape.GetSO())
+        return sSEntry
+
+    def _processGroups(self, res):
+        """
+        Part of the "execute" method: processes the Groups of res result
+        publication.  If fields is true, the same is performed for Fields.
+        """
+        allGroupsProcessed = set()
+        allRefGroups = []
+        allRefGroups.append(ModelAPI.referencedFeatures(res, "Group", True))
+        allRefGroups.append(
+            ModelAPI.referencedFeatures(res, "Shared_faces", True)
+        )
+        resShape = res.shape()
+        mapOfShape = GeomAlgoAPI.GeomAPI_IndexedMapOfShape(resShape)
+        for refGroups in allRefGroups:
+            for ref in refGroups:
+                groupsProcessed = self._processARefGroup(res.shape(), ref, mapOfShape)
+                allGroupsProcessed.update(groupsProcessed)
+        # check all existing groups: if some does not processed, remove it from
+        # the tree
+        self._removeNotProcessedType(
+            allGroupsProcessed, SHAPERSTUDY_ORB._objref_SHAPER_Group
+        )
+
+    def _processFields(self, res):
+        """
+        Part of the "execute" method: processes the Fields of res result
+        publication.
+        """
+        allFieldsProcessed = {}
+        allRefFields = []
+        allRefFields.append(ModelAPI.referencedFeatures(res, "Field", True))
+        resShape = res.shape()
+        mapOfShape = GeomAlgoAPI.GeomAPI_IndexedMapOfShape(resShape)
+        for refFields in allRefFields:
+            for ref in refFields:
+                fieldsProcessed = self._processARefField(res.shape(), ref, mapOfShape)
+                allFieldsProcessed.update(fieldsProcessed)
+
+        # check all existing groups: if some does not processed, remove it from
+        # the tree
+        self._removeNotProcessedType(
+            allFieldsProcessed, SHAPERSTUDY_ORB._objref_SHAPER_Field
+        )
+
+    def _processARefGroup(self, resShape, ref, mapOfShape):
+        groupsProcessed = set()
+        groupIndices = []
+        groupHasIndex = {}
+        selType = GeomAPI.GeomAPI_Shape.shapeTypeByStr(
+            ref.selectionList("group_list").selectionType()
+        )
+        for groupRes in ref.results():
+            shape = groupRes.shape()
+            explorer = GeomAPI.GeomAPI_ShapeExplorer(shape, selType)
+            while explorer.more():
+                idty = mapOfShape.FindIndexEqualLocations(explorer.current())
+                if (idty > 0) and (idty not in groupHasIndex):
+                    groupIndices.append(idty)
+                    groupHasIndex[idty] = 0
+                explorer.next()
+        if len(groupIndices) > 0:  # create group
+            groupOp = self.engine.GetIGroupOperations()
+            groupEntry = (
+                "group"
+                + str(self.currentPartFeatureId)
+                + ":"
+                + str(ref.data().featureId())
+            )
+            group = groupOp.FindGroup(self.currentShaperShape, groupEntry)
+            if not group:  # create a new
+                group = groupOp.CreateGroup(self.currentShaperShape, selType)
+                group.SetEntry(groupEntry)
+                self.engine.AddInStudy(
+                    group,
+                    ref.firstResult().data().name(),
+                    self.currentShaperShape,
+                )
+            group.SetSelection(groupIndices)
+            # a group takes shape from the main result
+            groupsProcessed.add(groupEntry)
+        return groupsProcessed
+
+    def _processARefField(self, resShape, ref, mapOfShape):
+        fieldIndices = []
+        fieldHasIndex = {}
+        processedEntries = set()
+        selType = GeomAPI.GeomAPI_Shape.shapeTypeByStr(
+            ref.selectionList("selected").selectionType()
         )
+        for fieldRes in ref.results():
+            explorer = GeomAPI.GeomAPI_ShapeExplorer(fieldRes.shape(), selType)
+            while explorer.more():
+                idty = mapOfShape.FindIndexEqualLocations(explorer.current())
+                if (idty > 0) and (idty not in fieldHasIndex):
+                    fieldIndices.append(idty)
+                    fieldHasIndex[idty] = 0
+                explorer.next()
+        if len(fieldIndices) > 0:  # create field
+            fieldFeatureId = ref.data().featureId()
+            fieldOp = self.engine.GetIFieldOperations()
+            fieldEntry = (
+                "field"
+                + str(self.currentPartFeatureId)
+                + ":"
+                + str(fieldFeatureId)
+            )
+            field = fieldOp.FindField(self.currentShaperShape, fieldEntry)
+            if not field:  # create a new
+                field = fieldOp.CreateFieldByType(
+                    self.currentShaperShape, selType
+                )
+                field.SetEntry(fieldEntry)
+                self.engine.AddInStudy(
+                    field,
+                    ref.firstResult().data().name(),
+                    self.currentShaperShape,
+                )
+            field.SetSelection(fieldIndices)
+            self._fillField(field, ref, fieldIndices)
+            processedEntries.add(fieldEntry)
+        return processedEntries
+
+    def _fillField(self, field, feature, selectionIndices):
+        """
+        Part of the "execute" method: filed fields filling.
 
+        Parameters
+        ----------
+        field:
+        feature:
+        selectionIndices:
 
-def processAllSO(theSOIter, theAllProcessed):
-    while theSOIter.More():
-        aSO = theSOIter.Value()
-        theSOIter.Next()  # here because there is continue inside the loop
-        anIOR = aSO.GetIOR()
-        if len(anIOR) > 0:
-            anObj = salome.orb.string_to_object(anIOR)
-            if isinstance(anObj, SHAPERSTUDY_ORB._objref_SHAPER_Object):
-                anEntry = anObj.GetEntry()
-                if len(anEntry) == 0:
-                    continue
-                if (
-                    anEntry not in theAllProcessed
-                ):  # found a removed shape: make it dead for the moment
-                    # remove the reference - red node
-                    aRes, aSO2 = aSO.FindSubObject(1)
-                    if aRes:
-                        aRes, _ = aSO2.ReferencedObject()
-                        if aRes:
-                            aBuilder = SHAPERSTUDY_utils.getStudy().NewBuilder()
-                            aBuilder.RemoveReference(aSO2)
-                    # if the object is not marked as dead, mark it (#3201) to make all entries unique
-                    aDeadEntry = anObj.GetEntry()
-                    if not aDeadEntry.startswith("dead"):
-                        anIndex = aSO.Tag()
-                        anObj.SetEntry("dead0" + str(anIndex) + "_" + aDeadEntry)
-
-                        # also for groups
-                        aGrSOIter = SHAPERSTUDY_utils.getStudy().NewChildIterator(aSO)
-                        while aGrSOIter.More():
-                            aGroupSO = aGrSOIter.Value()
-                            aGrSOIter.Next()
-                            anIOR = aGroupSO.GetIOR()
-                            if len(anIOR):
-                                aGroup = salome.orb.string_to_object(anIOR)
-                                if isinstance(
-                                    aGroup, SHAPERSTUDY_ORB._objref_SHAPER_Group
-                                ) or isinstance(
-                                    aGroup, SHAPERSTUDY_ORB._objref_SHAPER_Field
-                                ):
-                                    if not aGroup.GetEntry().startswith("dead"):
-                                        aDeadGroupEntry = (
-                                            "dead0"
-                                            + str(anIndex)
-                                            + "_"
-                                            + aGroup.GetEntry()
-                                        )
-                                        aGroup.SetEntry(aDeadGroupEntry)
+        """
+        tables = feature.tables("values")
+        valType = tables.type()  # type of the values
+        valTypeToSet = valType
+        if valType == 3:
+            # strings do not supported by SMESH, so, make them empty boolean
+            # table
+            valTypeToSet = 0
+        field.SetValuesType(valTypeToSet)
+        numSteps = tables.tables()  # number of steps is number of tables
+        steps = []
+        for val in range(numSteps):
+            steps.append(val + 1)
+        field.SetSteps(steps)
+        compNames = []
+        compNamesAttr = feature.stringArray("components_names")
+        for index in range(compNamesAttr.size()):
+            compNames.append(compNamesAttr.value(index))
+        field.SetComponents(compNames)
+        # prepare the sub-shapes indices: all values for all sub-shapes must be
+        # defined
+        shapeOp = self.engine.GetIShapesOperations()
+        allIndices = shapeOp.GetAllSubShapesIDs(
+            field.GetShape(), field.GetSelectionType(), False
+        )
+        # define steps
+        field.ClearFieldSteps()
+        for val in range(numSteps):
+            vals = []
+            for col in range(tables.columns()):
+                # for row in range(tables.rows()):
+                for index in allIndices:
+                    if index in selectionIndices:
+                        row = (
+                            selectionIndices.index(index) + 1
+                        )  # starting from the first line
+                    else:
+                        row = 0  # default value
+                    strVal = tables.valueStr(row, col, val)
+                    if valType == 0:  # boolean
+                        if strVal == "True":
+                            vals.append(1)
+                        else:
+                            vals.append(0)
+                    elif valType == 1:  # int
+                        vals.append(int(strVal))
+                    elif valType == 2:  # double
+                        vals.append(float(strVal))
+            field.AddFieldStep(
+                feature.intArray("stamps").value(val), val + 1, vals
+            )
+
+    @staticmethod
+    def _manageDeadGroups(sO):
+        index = sO.Tag()
+        grSOIter = SHAPERSTUDY_utils.getStudy().NewChildIterator(sO)
+        while grSOIter.More():
+            groupSO = grSOIter.Value()
+            grSOIter.Next()
+            iOR = groupSO.GetIOR()
+            if len(iOR) == 0:
+                continue
+            group = salome.orb.string_to_object(iOR)
+            if isinstance(
+                group,
+                (
+                    SHAPERSTUDY_ORB._objref_SHAPER_Group,
+                    SHAPERSTUDY_ORB._objref_SHAPER_Field,
+                ),
+            ):
+                if not group.GetEntry().startswith("dead"):
+                    deadGroupEntry = (
+                        "dead0" + str(index) + "_" + group.GetEntry()
+                    )
+                    group.SetEntry(deadGroupEntry)
+
+    def _removeNotProcessedType(self, allGroupsProcessed, Type):
+        """
+        Check all existing groups of Type: if some does not processed, remove
+        it from the tree.
+        """
+        sOIter = SHAPERSTUDY_utils.getStudy().NewChildIterator(
+            self.currentShaperShape.GetSO()
+        )
+        while sOIter.More():
+            sO = sOIter.Value()
+            iOR = sO.GetIOR()
+            if len(iOR) > 0:
+                obj = salome.orb.string_to_object(iOR)
+                if isinstance(obj, Type):
+                    entry = obj.GetEntry()
+                    if entry not in allGroupsProcessed:
+                        # found a removed group => remove
+                        builder = SHAPERSTUDY_utils.getStudy().NewBuilder()
+                        builder.RemoveObject(obj.GetSO())
+            sOIter.Next()