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