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