]> SALOME platform Git repositories - modules/shaper_study.git/blob - src/PY/SHAPERSTUDY.py
Salome HOME
Make the SHAPERSTUDY python dump works on SHAPER objects stable, even after modificat...
[modules/shaper_study.git] / src / PY / SHAPERSTUDY.py
1 # Copyright (C) 2007-2019  CEA/DEN, EDF R&D, OPEN CASCADE
2 #
3 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 #
6 # This library is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU Lesser General Public
8 # License as published by the Free Software Foundation; either
9 # version 2.1 of the License, or (at your option) any later version.
10 #
11 # This library is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 # Lesser General Public License for more details.
15 #
16 # You should have received a copy of the GNU Lesser General Public
17 # License along with this library; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 #
20 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 #
22
23 import SHAPERSTUDY_ORB__POA
24 import SHAPERSTUDY_ORB
25 import SALOME_ComponentPy
26 import SALOME_DriverPy
27 import SALOMEDS
28 from SHAPERSTUDY_utils import findOrCreateComponent, moduleName, getStudy, getORB
29 import salome
30 import SHAPERSTUDY_Object
31 import SHAPERSTUDY_IOperations
32 import GEOM
33 import SMESH
34
35 import StudyData_Swig
36
37 __entry2IOR__ = {}
38 __entry2DumpName__ = {}
39
40 class SHAPERSTUDY(SHAPERSTUDY_ORB__POA.Gen,
41                   SALOME_ComponentPy.SALOME_ComponentPy_i,
42                   SALOME_DriverPy.SALOME_DriverPy_i):
43
44
45     ShapeType = {"AUTO":-1, "COMPOUND":0, "COMPSOLID":1, "SOLID":2, "SHELL":3, "FACE":4, "WIRE":5, "EDGE":6, "VERTEX":7, "SHAPE":8, "FLAT":9}
46     
47     ShaperIcons = {GEOM.COMPOUND:"SHAPER_ICON_COMPSOLID",
48         GEOM.COMPSOLID:"SHAPER_ICON_COMPSOLID",
49         GEOM.SOLID:"SHAPER_ICON_SOLID",
50         GEOM.SHELL:"SHAPER_ICON_SHELL",
51         GEOM.FACE:"SHAPER_ICON_FACE",
52         GEOM.WIRE:"SHAPER_ICON_WIRE",
53         GEOM.EDGE:"SHAPER_ICON_EDGE",
54         GEOM.VERTEX:"SHAPER_ICON_VERTEX",
55         GEOM.SHAPE:"SHAPER_ICON_SOLID",
56         GEOM.FLAT:"SHAPER_ICON_FACE"
57         }
58
59     def __init__ ( self, orb, poa, contID, containerName, instanceName, interfaceName ):
60         """
61         Construct an instance of SHAPERSTUDY module engine.
62         The class SHAPERSTUDY implements CORBA interface Gen (see SHAPERSTUDY_Gen.idl).
63         It is inherited (via GEOM_Gen) from the classes SALOME_ComponentPy_i (implementation of
64         Engines::EngineComponent CORBA interface - SALOME component) and SALOME_DriverPy_i
65         (implementation of SALOMEDS::Driver CORBA interface - SALOME module's engine).
66         """
67         SALOME_ComponentPy.SALOME_ComponentPy_i.__init__(self, orb, poa,
68                     contID, containerName, instanceName, interfaceName, False)
69         SALOME_DriverPy.SALOME_DriverPy_i.__init__(self, interfaceName)
70         #
71         #self._naming_service = SALOME_ComponentPy.SALOME_NamingServicePy_i( self._orb )
72         #
73         pass
74
75     def FindOrCreateShape( self, theInternalEntry ):
76         """
77         Searches existing or creates a new SHAPERSTUDY_Object to interact with SHAPER
78         """
79         # Searching in the study tree
80         aComponent = findOrCreateComponent()
81         aSOIter = getStudy().NewChildIterator(aComponent)
82         while aSOIter.More():
83           aSO = aSOIter.Value()
84           anIOR = aSO.GetIOR()
85           anObj = salome.orb.string_to_object(anIOR)
86           if isinstance(anObj, SHAPERSTUDY_ORB._objref_SHAPER_Object):
87             if anObj.GetEntry() == theInternalEntry:
88               return anObj
89           aSOIter.Next()
90
91         aShapeObj = SHAPERSTUDY_Object.SHAPERSTUDY_Object()
92         aShapeObj.SetEntry(theInternalEntry)
93         return aShapeObj._this()
94
95     def AddInStudy( self, theObject, theName, theFather ):
96         """
97         Adds in theStudy a object theObject under theFather with a name theName,
98         if theFather is not NULL the object is placed under theFather's SObject.
99         Returns a SObject where theObject is placed
100         """
101         if not theObject.GetEntry():
102             return None # object not existing in shaper
103         aStudy = getStudy()
104         aBuilder = aStudy.NewBuilder()
105         isGroup = theObject.GetType() == 37 or theObject.GetType() == 52
106         if not theFather:
107           if isGroup:
108             return None # Group may be added only under the shape-father
109           theFatherSO = findOrCreateComponent()
110         else:
111           theFatherSO = theFather.GetSO()
112         aResultSO = None
113         if isGroup: # add group to the third sub-label or later to keep space for reference and "History"
114           aTag = 3
115           anIter = aStudy.NewChildIterator(theFatherSO)
116           while anIter.More():
117             aCurrentTag = anIter.Value().Tag() + 1
118             if aTag < aCurrentTag:
119               aTag = aCurrentTag
120             anIter.Next()
121           aResultSO = aBuilder.NewObjectToTag(theFatherSO, aTag)
122         else:
123           aResultSO = aBuilder.NewObject(theFatherSO);
124         aResultSO.SetAttrString("AttributeName", theName)
125         if theObject is not None:
126             anIOR = salome.orb.object_to_string(theObject)
127             aResultSO.SetAttrString("AttributeIOR", anIOR)
128             theObject.SetSO(aResultSO)
129           
130             aAttr = aBuilder.FindOrCreateAttribute(aResultSO, "AttributePixMap")
131             aPixmap = aAttr._narrow(salome.SALOMEDS.AttributePixMap)
132             aType = 0
133             if isGroup:
134               aType = SHAPERSTUDY_Object.__shape_types__[theObject.GetSelectionType()]
135             else:
136               aType = theObject.GetShapeType()
137             aPixmap.SetPixMap(self.ShaperIcons[aType])
138             
139         # add a red-reference that means that this is an active reference to SHAPER result
140         if not isGroup:
141           aSub = aBuilder.NewObjectToTag(aResultSO, 1)
142           aBuilder.Addreference(aSub, aResultSO)
143
144         return aResultSO
145
146     def StoreVariableName(self, theEntry, theVarName):
147         """
148         Stores the variable names of the SHAPER dump to python
149         """
150         __entry2DumpName__["s" + theEntry] = theVarName
151
152
153     def AddSubShape( theMainShape, theIndices ):
154         """
155         Add a sub-shape defined by indices in theIndices
156         (contains unique IDs of sub-shapes inside theMainShape)
157         """
158         # no sub-shapes for the moment
159         go = SHAPERSTUDY_Object()._this()
160         return go
161
162     # For now it is impossible to remove anything from the SHAPER-STUDY
163     def RemoveObject( self, theObject ):
164         """
165         Removes the object from the component
166         """
167         # can not be removed for the moment
168         return
169
170     def GetIFieldOperations( self ):
171         """
172         """
173         return SHAPERSTUDY_IOperations.SHAPERSTUDY_IFieldOperations()._this()
174
175     def GetIGroupOperations( self ):
176         """
177         """
178         return SHAPERSTUDY_IOperations.SHAPERSTUDY_IGroupOperations()._this()
179
180     def GetIShapesOperations( self ):
181         """
182         """
183         return SHAPERSTUDY_IOperations.SHAPERSTUDY_IShapesOperations()._this()
184
185     def GetIMeasureOperations( self ):
186         """
187         """
188         return SHAPERSTUDY_IOperations.SHAPERSTUDY_IMeasureOperations()._this()
189
190     def GetStringFromIOR( self, theObject ):
191         """
192         Returns a string which contains an IOR of the SHAPERSTUDY_Object
193         """
194         IOR = ""
195         if theObject and getORB():
196             IOR = getORB().object_to_string( theObject )
197             pass
198         return IOR
199
200     def Save( self, component, URL, isMultiFile ):
201         """
202         Saves data: all objects into one file
203         """
204         aResult = "" # string-pairs of internal entries and shape streams
205         aStudy = getStudy()
206         # get all sub-SObjects with IOR defined
207         anIters = [aStudy.NewChildIterator(findOrCreateComponent())]
208         aSOList = []
209         while len(anIters):
210           aLast = anIters[len(anIters) - 1]
211           if aLast.More():
212             aSO = aLast.Value()
213             anIOR = aSO.GetIOR()
214             if len(anIOR):
215               aSOList.append(aSO)
216             anIters.append(aStudy.NewChildIterator(aSO))
217             aLast.Next()
218           else:
219             anIters.remove(aLast)
220
221         for aSO in aSOList: # for each sobject export shapes stream if exists
222           anIOR = aSO.GetIOR()
223           if not len(anIOR):
224             continue
225           anObj = salome.orb.string_to_object(anIOR)
226           if type(anObj) == SHAPERSTUDY_ORB._objref_SHAPER_Group:
227             if len(aResult):
228               aResult += '|'
229             # store internal entry, type and list of indices of the group selection (separated by spaces)
230             aResult += anObj.GetEntry() + "|" + str(anObj.GetSelectionType())
231             aSelList = anObj.GetSelection()
232             aResult += "|" + str(' '.join(str(anI) for anI in aSelList))
233           elif type(anObj) == SHAPERSTUDY_ORB._objref_SHAPER_Field:
234             if len(aResult):
235               aResult += '|'
236             # same as for group, but in addition to the second string part - field specifics
237             aResult += anObj.GetEntry() + "|" + str(anObj.GetSelectionType())
238             aResult += " " + str(anObj.GetDataType()) # values type
239             aSteps = anObj.GetSteps()
240             aResult += " " + str(len(aSteps)) # number of steps
241             aComps = anObj.GetComponents()
242             aResult += " " + str(len(aComps)) # number of components
243             for aComp in aComps: # components strings: but before remove spaces and '|'
244               aCoded = aComp.replace(" ", "__space__").replace("|", "__vertical_bar__")
245               aResult += " " + aCoded
246             for aStepNum in range(len(aSteps)):
247               aVals = anObj.GetStep(aStepNum + 1).GetValues()
248               if aStepNum == 0:
249                 aResult += " " + str(len(aVals)) # first the number of values in the step
250               aResult += " " + str(anObj.GetStep(aStepNum + 1).GetStamp()) # ID of stamp in step
251               for aVal in aVals:
252                 aResult += " " + str(aVal) # all values of step
253             aSelList = anObj.GetSelection()
254             aResult += "|" + str(' '.join(str(anI) for anI in aSelList))
255           elif isinstance(anObj, SHAPERSTUDY_ORB._objref_SHAPER_Object):
256             if len(aResult):
257               aResult += '|'
258             # store internal entry, current and old shapes in BRep format
259             aResult += anObj.GetEntry() + "|" + anObj.GetShapeStream().decode()
260             aResult += "|" + anObj.GetOldShapeStream().decode()
261
262         return aResult.encode()
263
264     def Load( self, component, stream, URL, isMultiFile ):
265         """
266         Loads data
267         """
268         global __entry2IOR__
269         __entry2IOR__.clear()
270         aList=stream.decode().split('|')
271         aSubNum = 1
272         anId = ""
273         aNewShapeStream = ""
274         for aSub in aList:
275           if aSubNum == 1:
276             anId = aSub
277             aSubNum = 2
278           elif aSubNum == 2:
279             aNewShapeStream = aSub
280             aSubNum = 3
281           else: # create objects by 3 arguments
282             anObj = None
283             if anId.startswith('group') or (anId.startswith('dead') and anId.count("group") > 0): # group object
284               anObj = SHAPERSTUDY_Object.SHAPERSTUDY_Group()
285               if len(aSub):
286                 anObj.SetSelection([int(anI) for anI in aSub.split(' ')])
287               anObj.SetSelectionType(int(aNewShapeStream))
288             elif anId.startswith('field') or (anId.startswith('dead') and anId.count("field") > 0): # field object
289               anObj = SHAPERSTUDY_Object.SHAPERSTUDY_Field()
290               if len(aSub):
291                 anObj.SetSelection([int(anI) for anI in aSub.split(' ')])
292               aParams = aNewShapeStream.split(" ")
293               anObj.SetSelectionType(int(aParams[0]))
294               aTypeStr = aParams[1]
295               if (aTypeStr == "FDT_Bool"):
296                 anObj.SetValuesType(0)
297               elif (aTypeStr == "FDT_Int"):
298                 anObj.SetValuesType(1)
299               elif (aTypeStr == "FDT_Double"):
300                 anObj.SetValuesType(2)
301               elif (aTypeStr == "FDT_String"):
302                 anObj.SetValuesType(3)
303               aSteps = []
304               aNumSteps = int(aParams[2])
305               for aVal in range(aNumSteps):
306                 aSteps.append(aVal + 1)
307               anObj.SetSteps(aSteps)
308               aCompNum = int(aParams[3])
309               aCompNames = []
310               for aCompNameIndex in range(aCompNum):
311                 aCompName = aParams[4 + aCompNameIndex].replace("__space__", " ").replace("__vertical_bar__", "|")
312                 aCompNames.append(aCompName)
313               anObj.SetComponents(aCompNames)
314               aNumValsInStep = int(aParams[4 + aCompNum])
315               for aStepNum in range(aNumSteps):
316                 aStepStartIndex = 4 + aCompNum + aStepNum * (aNumValsInStep + 1) + 1
317                 aStampId = int(aParams[aStepStartIndex])
318                 aVals = []
319                 for aValIndex in range(aNumValsInStep):
320                   aVals.append(float(aParams[aStepStartIndex + aValIndex + 1]))
321                 anObj.AddFieldStep(aStampId, aStepNum + 1, aVals)
322             else: # shape object by BRep in the stream: set old first then new
323               anObj = SHAPERSTUDY_Object.SHAPERSTUDY_Object()
324               if len(aSub):
325                 anObj.SetShapeByStream(aSub)
326               anObj.SetShapeByStream(aNewShapeStream)
327             if anObj:
328               anObj.SetEntry(anId)
329               anIOR = salome.orb.object_to_string(anObj._this())
330               __entry2IOR__[anId] = anIOR
331             aSubNum = 1
332         return 1
333         
334     def IORToLocalPersistentID(self, sobject, IOR, isMultiFile, isASCII):
335         """
336         Gets persistent ID for the CORBA object.
337         The internal entry of the Object is returned.
338         """
339         anObj = salome.orb.string_to_object(IOR)
340         if anObj and (isinstance(anObj, SHAPERSTUDY_ORB._objref_SHAPER_Object) or \
341                       isinstance(anObj, SHAPERSTUDY_ORB._objref_SHAPER_Field)):
342           return anObj.GetEntry()
343         return ""
344
345     def LocalPersistentIDToIOR(self, sobject, persistentID, isMultiFile, isASCII):
346         "Converts persistent ID of the object to its IOR."
347         global __entry2IOR__
348         if persistentID in __entry2IOR__:
349           aRes = __entry2IOR__[persistentID]
350           if len(aRes): # set SO from the study, the sobject param is temporary, don't store it
351             salome.orb.string_to_object(aRes).SetSO(getStudy().FindObjectID(sobject.GetID()))
352           return aRes
353         return ""
354     
355     def UniqueDumpName( self, theBaseName, theID ):
356         """
357         Returns a unique name from the theBaseName. Keeps theBaseName if it was not used yet.
358         Stores the newly generated name into the global map __entry2DumpName__.
359         """
360         global __entry2DumpName__
361         aPrefix = 1
362         # to avoid spaces and parenthesis in the variable name
363         aBaseName = theBaseName.replace(" ", "_").replace("(", "").replace(")", "")
364         aName = aBaseName
365         while aName in __entry2DumpName__.values():
366           aName = aBaseName + "_" + str(aPrefix)
367           aPrefix = aPrefix + 1
368         __entry2DumpName__[theID] = aName
369         return aName
370
371     def GetShaperEntry(self, theShapeObj):
372         """
373         Returns string in the python dump that generates the SHAPER entry:
374         it may be just entry string, or call for the SHAPER dump variable.
375         """
376         global __entry2DumpName__
377         anEntry = "s" + theShapeObj.GetEntry()
378         if anEntry in __entry2DumpName__:
379           return "model.featureStringId(" + __entry2DumpName__[anEntry] + ")"
380         return "\"" + theShapeObj.GetEntry() + "\""
381
382     def DumpPython( self, isPublished, isMultiFile ):
383         """
384         Dump module data to the Python script.
385         """
386         global __entry2DumpName__
387         # remove all non-SHAPER entries
388         aCopyMap = {}
389         for anEntry in __entry2DumpName__:
390           if anEntry.startswith("s"):
391             aCopyMap[anEntry] = __entry2DumpName__[anEntry]
392         __entry2DumpName__ = aCopyMap
393
394         anArchiveNum = 1
395         # collect all shape-objects in the SHAPERSTUDY tree
396         aShapeObjects = []
397         aStudy = getStudy()
398         aRoots = aStudy.NewChildIterator(findOrCreateComponent())
399         while aRoots.More():
400           aSO = aRoots.Value()
401           anIOR = aSO.GetIOR()
402           if len(anIOR):
403             anObj = salome.orb.string_to_object(anIOR)
404             if anObj and type(anObj) == SHAPERSTUDY_ORB._objref_SHAPER_Object:
405               aShapeObjects.append(anObj)
406           aRoots.Next()
407         script = []
408         if len(aShapeObjects):
409           script.append("if 'model' in globals():")
410           script.append("\tmodel.publishToShaperStudy()")
411           script.append("import SHAPERSTUDY")
412           for aShapeObj in aShapeObjects:
413             # check this shape also has sub-groups and fields
414             aGroupVarNames = []
415             aSOIter = aStudy.NewChildIterator(aShapeObj.GetSO())
416             while aSOIter.More():
417               aGroupSO = aSOIter.Value()
418               anIOR = aGroupSO.GetIOR()
419               if len(anIOR):
420                 aGroup = salome.orb.string_to_object(anIOR)
421                 if isinstance(aGroup, SHAPERSTUDY_ORB._objref_SHAPER_Group) or \
422                    isinstance(aGroup, SHAPERSTUDY_ORB._objref_SHAPER_Field):
423                   aGroupVarName = self.UniqueDumpName(aGroup.GetName(), aGroupSO.GetID())
424                   aGroupVarNames.append(aGroupVarName)
425               aSOIter.Next()
426             aShapeVar = self.UniqueDumpName(aShapeObj.GetName(), aShapeObj.GetSO().GetID())
427             aShapeStr = aShapeVar + ", "
428             for aGName in aGroupVarNames:
429               aShapeStr += aGName + ", "
430             aShapeStr += "= SHAPERSTUDY.shape(" + self.GetShaperEntry(aShapeObj) +")"
431             script.append(aShapeStr)
432             # dump also dead-shapes with groups and fields in the XAO format
433             aRes, aHistSO = aShapeObj.GetSO().FindSubObject(2) # the History folder
434             if aRes:
435               aDeads = aStudy.NewChildIterator(aHistSO)
436               while aDeads.More():
437                 aDSO = aDeads.Value()
438                 aDIOR = aDSO.GetIOR()
439                 if len(aDIOR):
440                   aDeadShape = salome.orb.string_to_object(aDIOR)
441                   if aDeadShape and type(aDeadShape) == SHAPERSTUDY_ORB._objref_SHAPER_Object:
442                     aDeadString = ""
443                     aXAO = StudyData_Swig.StudyData_XAO()
444                     aXAO.SetShape(aDeadShape.getShape())
445                     anArchiveName = "archive_" + str(anArchiveNum) + ".xao"
446                     if len(aStudy.GetDumpPath()):
447                       anArchiveName = aStudy.GetDumpPath() + "/" + anArchiveName
448                     anArchiveNum += 1
449                     aDeadVarName = self.UniqueDumpName(aDeadShape.GetName(), aDSO.GetID())
450                     aDeadString += aDeadVarName + ", "
451                     aDGroupIter = aStudy.NewChildIterator(aDSO)
452
453                     while aDGroupIter.More():
454                       aDeadGroup = aDGroupIter.Value().GetObject()
455                       if isinstance(aDeadGroup, SHAPERSTUDY_ORB._objref_SHAPER_Group):
456                         aDGroupVarName = self.UniqueDumpName(aDeadGroup.GetName(), aDGroupIter.Value().GetID())
457                         aDeadString += aDGroupVarName + ", "
458                         aGroupID = aXAO.AddGroup(aDeadGroup.GetSelectionType(), aDGroupVarName)
459                         for aSel in aDeadGroup.GetSelection():
460                           aXAO.AddGroupSelection(aGroupID, aSel)
461                       elif isinstance(aDeadGroup, SHAPERSTUDY_ORB._objref_SHAPER_Field):
462                         aDeadField = aDeadGroup
463                         aDFieldVarName = self.UniqueDumpName(aDeadField.GetName(), aDGroupIter.Value().GetID())
464                         aDeadString += aDFieldVarName + ", "
465                         aComponents = aDeadField.GetComponents()
466                         aFieldID = aXAO.AddField(aDeadField.GetValuesType(), aDeadField.GetSelectionType(), \
467                           len(aComponents), aDFieldVarName)
468                         for aCompIndex in range(len(aComponents)):
469                           aXAO.SetFieldComponent(aFieldID, aCompIndex, aComponents[aCompIndex])
470                         aSteps = aDeadField.GetSteps()
471                         for aStep in aSteps:
472                           aFieldStep = aDeadField.GetStep(aStep)
473                           aXAO.AddStep(aFieldID, aStep, aFieldStep.GetStamp())
474                           aStepVals = aFieldStep.GetValues()
475                           for aValue in aStepVals:
476                             aXAO.AddStepValue(aFieldID, aStep, str(aValue))
477                       aDGroupIter.Next()
478                     aXAO.Export(anArchiveName)
479                     aDeadString += " = SHAPERSTUDY.archive(" + aShapeVar + ", \"" + anArchiveName + "\")"
480                     script.append(aDeadString)
481                 aDeads.Next()
482           pass
483         
484         script.append("") # to have an end-line in the end
485         result_str = "\n".join(script)
486         encoded_str = result_str.encode() + b'\0' # to avoid garbage symbols in the end
487         return (encoded_str, 1)
488
489     def GetAllDumpNames( self ):
490         """
491         Returns all names with which Object's was dumped
492         into python script to avoid the same names in SMESH script
493         """
494         global __entry2DumpName__
495         aResultList = []
496         for anEntry in __entry2DumpName__:
497           aResultList.append(__entry2DumpName__[anEntry])
498         return aResultList
499
500     def GetDumpName( self, theStudyEntry ):
501         """
502         Returns a name with which a GEOM_Object was dumped into python script
503
504         Parameters:
505             theStudyEntry is an entry of the Object in the study
506         """
507         global __entry2DumpName__
508         if theStudyEntry in __entry2DumpName__:
509           return __entry2DumpName__[theStudyEntry]
510         return ""
511
512     def IsFather(theFather, theChild):
513         """
514         Returns true if theChild SObject is a child of theFather SObject
515         """
516         aChild = theChild.GetFather()
517         while aChild.Depth() > theFather.Depth():
518           aChild = aChild.GetFather()
519         return aChild.GetID() == theFather.GetID()
520
521     def BreakLink(self, theEntry):
522         """
523         Breaks links to not-dead shape, make the shape as dead
524         """
525         aStudy = getStudy()
526         aSO = aStudy.FindObjectID(theEntry)
527         if not aSO:
528           return
529         aRes, aSSO = aSO.ReferencedObject()
530         if not aRes:
531           return # only SObjects referenced to the SHAPEr STUDY objects are allowed
532         anIOR = aSSO.GetIOR()
533         if not anIOR:
534           return # must be referenced to the SHAPER STUDY shape
535         anObj = salome.orb.string_to_object(anIOR)
536         if not anObj or not isinstance(anObj, SHAPERSTUDY_ORB._objref_SHAPER_Object):
537           return
538         if anObj.IsDead():
539           return # do nothing for reference to already dead shape
540         aDeadShape = anObj.MakeDead()
541         
542         aMeshSObject = aSO.GetFather()
543         aMeshObject = aMeshSObject.GetObject()
544
545         aBuilder = aStudy.NewBuilder()
546         aBuilder.RemoveReference(aSO) # reset reference to the dead shape
547         aBuilder.Addreference(aSO, aDeadShape.GetSO())
548
549         # check also sub-structure of the mesh to find references to sub-objects that become dead
550         aRoot = aSO.GetFather()
551         anIters = [aStudy.NewChildIterator(aRoot)]
552         aSubList = []
553         while len(anIters):
554           aLast = anIters[len(anIters) - 1]
555           if aLast.More():
556             aSub = aLast.Value()
557             aRes, aSubRef = aSub.ReferencedObject()
558             if aRes and SHAPERSTUDY.IsFather(aSSO, aSubRef):
559               aReferenced = aSubRef.GetObject()
560               if aReferenced and not aReferenced.IsDead():
561                 aSubList.append(aSub)
562             anIters.append(aStudy.NewChildIterator(aSub))
563             aLast.Next()
564           else:
565             anIters.remove(aLast)
566         if len(aSubList):
567           # associate the number of sub-objects of the referenced objects
568           aMapSubEntryToIndex = {}
569           aSSOIter = aStudy.NewChildIterator(aSSO)
570           anIndex = 1
571           while aSSOIter.More():
572             aSub = aSSOIter.Value()
573             if aSub.GetIOR():
574               aMapSubEntryToIndex[aSub.GetID()] = anIndex
575               anIndex = anIndex + 1
576             aSSOIter.Next()
577           for aSubSO in aSubList:
578             aRes, aSubRef = aSubSO.ReferencedObject()
579             if aRes and aSubRef.GetID() in aMapSubEntryToIndex:
580               anIndex = aMapSubEntryToIndex[aSubRef.GetID()]
581               aDeadIter = aStudy.NewChildIterator(aDeadShape.GetSO())
582               while aDeadIter.More(): # iterate dead subs to find object with the same index
583                 aDeadSubSO = aDeadIter.Value()
584                 if aDeadSubSO.GetIOR():
585                   anIndex = anIndex - 1
586                   if anIndex == 0:
587                     # for a submesh there is no ReplaceShape, but the shape is not updated
588                     # anyway, so no need to update it here
589                     #aSubMeshSO = aSubSO.GetFather() # Replace shape object in the parent mesh
590                     #aSubMeshObject = aSubMeshSO.GetObject()
591                     #if aSubMeshObject:
592                     #  aSubMeshObject.ReplaceShape(aDeadSubSO.GetObject())
593                     aBuilder.RemoveReference(aSubSO) # reset reference to the dead shape
594                     aBuilder.Addreference(aSubSO, aDeadSubSO)
595                 aDeadIter.Next()
596
597         # Replace shape object in the parent mesh
598         aMeshObject.ReplaceShape(aDeadShape)
599
600 def shape(theEntry):
601   """
602   Searches a shape object by the SHAPER entry. Used in the python dump script
603   """
604   aStudy = getStudy()
605   aRoots = aStudy.NewChildIterator(findOrCreateComponent())
606   while aRoots.More():
607     aSO = aRoots.Value()
608     anIOR = aSO.GetIOR()
609     if len(anIOR):
610       anObj = salome.orb.string_to_object(anIOR)
611       if anObj and type(anObj) == SHAPERSTUDY_ORB._objref_SHAPER_Object and anObj.GetEntry() == theEntry:
612         aRes = (anObj,)
613         # add groups and fields to the result
614         aSOIter = aStudy.NewChildIterator(aSO)
615         while aSOIter.More():
616           aGroupSO = aSOIter.Value()
617           anIOR = aGroupSO.GetIOR()
618           if len(anIOR):
619             aGroup = salome.orb.string_to_object(anIOR)
620             if isinstance(aGroup, SHAPERSTUDY_ORB._objref_SHAPER_Group) or \
621                isinstance(aGroup, SHAPERSTUDY_ORB._objref_SHAPER_Field):
622               aRes = aRes + (aGroup,)
623           aSOIter.Next()
624         return aRes
625     aRoots.Next()
626   return None # not found
627
628 def archive(theShape, theXAOFile):
629   """
630   Creates a dead shapes under the theShape and restores these dead objects state basing on theXAOFile
631   """
632   theShape.MakeDead()
633   aStudy = getStudy()
634   # searching for the last dead
635   aDeads = aStudy.NewChildIterator(theShape.GetSO().FindSubObject(2)[1])
636   aLastDeadSO = aDeads.Value()
637   while aDeads.More():
638     aLastDeadSO = aDeads.Value()
639     aDeads.Next()
640
641   aDShape = aLastDeadSO.GetObject()
642   if aDShape:
643     aXAO = StudyData_Swig.StudyData_XAO()
644     anError = aXAO.Import(theXAOFile)
645     if (len(anError)):
646       print("Error of XAO file import: " + anError)
647       return None
648     aDShape.SetShapeByPointer(aXAO.GetShape())
649     aRes = (aDShape,)
650     # add groups and fields to the result
651     aGroupIndex = 0
652     aFieldIndex = 0
653     aSOIter = aStudy.NewChildIterator(aLastDeadSO)
654     while aSOIter.More():
655       aGroupSO = aSOIter.Value()
656       anIOR = aGroupSO.GetIOR()
657       if len(anIOR):
658         aGroup = salome.orb.string_to_object(anIOR)
659         if isinstance(aGroup, SHAPERSTUDY_ORB._objref_SHAPER_Group):
660           aRes += (aGroup,)
661           aGroup.SetSelectionType(aXAO.GetGroupDimension(aGroupIndex))
662           aSelection = []
663           for aSel in aXAO.GetGroupSelection(aGroupIndex):
664             aSelection.append(aSel)
665           aGroup.SetSelection(aSelection)
666           aGroupIndex += 1
667         elif isinstance(aGroup, SHAPERSTUDY_ORB._objref_SHAPER_Field):
668           aField = aGroup
669           aRes += (aField,)
670           aValType = aXAO.GetValuesType(aFieldIndex)
671           aField.SetValuesType(aValType)
672           aField.SetSelectionType(aXAO.GetSelectionType(aFieldIndex))
673           aCompNames = []
674           for aCompName in aXAO.GetComponents(aFieldIndex):
675             aCompNames.append(aCompName)
676           aField.SetComponents(aCompNames)
677           aField.ClearFieldSteps()
678           aXAO.BeginSteps(aFieldIndex)
679           while aXAO.More(aFieldIndex):
680             aValsList = []
681             for aVal in aXAO.GetValues():
682               if aValType == 0: # boolean
683                 aValsList.append(int(aVal))
684               elif aValType == 1: # int
685                 aValsList.append(int(aVal))
686               elif aValType == 2: # double
687                 aValsList.append(float(aVal))
688             aField.AddFieldStep(aXAO.GetStamp(), aXAO.GetStepIndex(), aValsList)
689             aXAO.Next()
690           aFieldIndex += 1
691       aSOIter.Next()
692     return aRes
693   return None # not found