1 # Copyright (C) 2019-2020 CEA/DEN, EDF R&D
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.
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.
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
17 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 import SHAPERSTUDY_ORB__POA
21 import SHAPERSTUDY_ORB
22 import SALOME_ComponentPy
23 import SALOME_DriverPy
25 from SHAPERSTUDY_utils import findOrCreateComponent, moduleName, getStudy, getORB
27 import SHAPERSTUDY_Object
28 import SHAPERSTUDY_IOperations
34 # for unit tests correct execution
38 __entry2DumpName__ = {}
40 class SHAPERSTUDY(SHAPERSTUDY_ORB__POA.Gen,
41 SALOME_ComponentPy.SALOME_ComponentPy_i,
42 SALOME_DriverPy.SALOME_DriverPy_i):
45 ShapeType = {"AUTO":-1, "COMPOUND":0, "COMPSOLID":1, "SOLID":2, "SHELL":3, "FACE":4, "WIRE":5, "EDGE":6, "VERTEX":7, "SHAPE":8, "FLAT":9}
47 ShaperIcons = {GEOM.COMPOUND:"compsolid.png",
48 GEOM.COMPSOLID:"compsolid.png",
49 GEOM.SOLID:"solid.png",
50 GEOM.SHELL:"shell.png",
54 GEOM.VERTEX:"vertex.png",
55 GEOM.SHAPE:"solid.png",
59 def __init__ ( self, orb, poa, contID, containerName, instanceName, interfaceName ):
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).
67 global __entry2IOR__, __entry2DumpName__
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)
74 #self._naming_service = SALOME_ComponentPy.SALOME_NamingServicePy_i( self._orb )
78 def FindOrCreateShape( self, theInternalEntry ):
80 Searches existing or creates a new SHAPERSTUDY_Object to interact with SHAPER
82 # Searching in the study tree
83 aComponent = findOrCreateComponent()
84 aSOIter = getStudy().NewChildIterator(aComponent)
89 anObj = salome.orb.string_to_object(anIOR)
90 if anObj and isinstance(anObj, SHAPERSTUDY_ORB._objref_SHAPER_Object):
91 if anObj.GetEntry() == theInternalEntry:
95 aShapeObj = SHAPERSTUDY_Object.SHAPERSTUDY_Object()
96 aShapeObj.SetEntry(theInternalEntry)
97 return aShapeObj._this()
99 def AddInStudy( self, theObject, theName, theFather ):
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
105 if not theObject.GetEntry():
106 return None # object not existing in shaper
108 aBuilder = aStudy.NewBuilder()
109 isGroup = theObject.GetType() == 37 or theObject.GetType() == 52
112 return None # Group may be added only under the shape-father
113 theFatherSO = findOrCreateComponent()
115 theFatherSO = theFather.GetSO()
119 anIter = aStudy.NewChildIterator(theFatherSO)
121 if anIter.Value().Tag() == 10000: # skip the history folder
124 aCurrentTag = anIter.Value().Tag() + 1
126 if aTag < aCurrentTag:
128 if aTag == 10000: # to avoid putting the object to the history folder
130 aResultSO = aBuilder.NewObjectToTag(theFatherSO, aTag)
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)
139 aAttr = aBuilder.FindOrCreateAttribute(aResultSO, "AttributePixMap")
140 aPixmap = aAttr._narrow(salome.SALOMEDS.AttributePixMap)
143 aType = SHAPERSTUDY_Object.__shape_types__[theObject.GetSelectionType()]
145 aType = theObject.GetShapeType()
146 aPixmap.SetPixMap(self.ShaperIcons[aType])
148 # add a red-reference that means that this is an active reference to SHAPER result
150 aSub = aBuilder.NewObjectToTag(aResultSO, 1)
151 aBuilder.Addreference(aSub, aResultSO)
155 def StoreVariableName(self, theEntry, theVarName):
157 Stores the variable names of the SHAPER dump to python
159 __entry2DumpName__["s" + theEntry] = theVarName
162 def AddSubShape( theMainShape, theIndices ):
164 Add a sub-shape defined by indices in theIndices
165 (contains unique IDs of sub-shapes inside theMainShape)
167 # no sub-shapes for the moment
168 go = SHAPERSTUDY_Object()._this()
171 # For now it is impossible to remove anything from the SHAPER-STUDY
172 def RemoveObject( self, theObject ):
174 Removes the object from the component
176 # can not be removed for the moment
179 def GetIFieldOperations( self ):
182 return SHAPERSTUDY_IOperations.SHAPERSTUDY_IFieldOperations()._this()
184 def GetIGroupOperations( self ):
187 return SHAPERSTUDY_IOperations.SHAPERSTUDY_IGroupOperations()._this()
189 def GetIShapesOperations( self ):
192 return SHAPERSTUDY_IOperations.SHAPERSTUDY_IShapesOperations()._this()
194 def GetIMeasureOperations( self ):
197 return SHAPERSTUDY_IOperations.SHAPERSTUDY_IMeasureOperations()._this()
199 def GetStringFromIOR( self, theObject ):
201 Returns a string which contains an IOR of the SHAPERSTUDY_Object
204 if theObject and getORB():
205 IOR = getORB().object_to_string( theObject )
209 def Save( self, component, URL, isMultiFile ):
211 Saves data: all objects into one file
213 aResult = "" # string-pairs of internal entries and shape streams
215 # get all sub-SObjects with IOR defined
216 anIters = [aStudy.NewChildIterator(findOrCreateComponent())]
219 aLast = anIters[len(anIters) - 1]
225 anIters.append(aStudy.NewChildIterator(aSO))
228 anIters.remove(aLast)
230 for aSO in aSOList: # for each sobject export shapes stream if exists
234 anObj = salome.orb.string_to_object(anIOR)
235 if type(anObj) == SHAPERSTUDY_ORB._objref_SHAPER_Group:
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:
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()
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
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):
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()
276 return aResult.encode()
278 def Load( self, component, stream, URL, isMultiFile ):
283 __entry2IOR__.clear()
284 aList=stream.decode().split('|')
293 aNewShapeStream = aSub
295 else: # create objects by 3 arguments
297 if anId.startswith('group') or (anId.startswith('dead') and anId.count("group") > 0): # group object
298 anObj = SHAPERSTUDY_Object.SHAPERSTUDY_Group()
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()
308 aSel = aSub.split(";")
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)
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])
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])
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()
345 anObj.SetShapeByStream(aSub)
346 anObj.SetShapeByStream(aNewShapeStream)
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
357 def IORToLocalPersistentID(self, sobject, IOR, isMultiFile, isASCII):
359 Gets persistent ID for the CORBA object.
360 The internal entry of the Object is returned.
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()
368 def LocalPersistentIDToIOR(self, sobject, persistentID, isMultiFile, isASCII):
369 "Converts persistent ID of the object to its IOR."
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()))
378 def UniqueDumpName( self, theBaseName, theID ):
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__.
383 global __entry2DumpName__
385 # to avoid spaces and parenthesis in the variable name
386 aBaseName = theBaseName.replace(" ", "_").replace("(", "").replace(")", "")
388 while aName in __entry2DumpName__.values():
389 aName = aBaseName + "_" + str(aPrefix)
390 aPrefix = aPrefix + 1
391 __entry2DumpName__[theID] = aName
394 def GetShaperEntry(self, theShapeObj):
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.
399 global __entry2DumpName__
400 anEntry = "s" + theShapeObj.GetEntry()
401 if anEntry in __entry2DumpName__:
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() + "\""
408 def DumpPython( self, isPublished, isMultiFile ):
410 Dump module data to the Python script.
412 global __entry2DumpName__
413 # remove all non-SHAPER entries
415 for anEntry in __entry2DumpName__:
416 if anEntry.startswith("s"):
417 aCopyMap[anEntry] = __entry2DumpName__[anEntry]
418 __entry2DumpName__ = aCopyMap
421 # collect all shape-objects in the SHAPERSTUDY tree
424 aRoots = aStudy.NewChildIterator(findOrCreateComponent())
429 anObj = salome.orb.string_to_object(anIOR)
430 if anObj and type(anObj) == SHAPERSTUDY_ORB._objref_SHAPER_Object:
431 aShapeObjects.append(anObj)
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
440 aSOIter = aStudy.NewChildIterator(aShapeObj.GetSO())
441 while aSOIter.More():
442 aGroupSO = aSOIter.Value()
443 anIOR = aGroupSO.GetIOR()
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)
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
460 aDeads = aStudy.NewChildIterator(aHistSO)
462 aDSO = aDeads.Value()
463 aDIOR = aDSO.GetIOR()
465 aDeadShape = salome.orb.string_to_object(aDIOR)
466 if aDeadShape and type(aDeadShape) == SHAPERSTUDY_ORB._objref_SHAPER_Object:
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
474 aDeadVarName = self.UniqueDumpName(aDeadShape.GetName(), aDSO.GetID())
475 aDeadString += aDeadVarName + ", "
476 aDGroupIter = aStudy.NewChildIterator(aDSO)
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()
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))
503 aXAO.Export(anArchiveName)
504 aDeadString += " = SHAPERSTUDY.archive(" + aShapeVar + ", \"" + anArchiveName + "\")"
505 script.append(aDeadString)
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)
514 def GetAllDumpNames( self ):
516 Returns all names with which Object's was dumped
517 into python script to avoid the same names in SMESH script
519 global __entry2DumpName__
521 for anEntry in __entry2DumpName__:
522 aResultList.append(__entry2DumpName__[anEntry])
525 def GetDumpName( self, theStudyEntry ):
527 Returns a name with which a GEOM_Object was dumped into python script
530 theStudyEntry is an entry of the Object in the study
532 global __entry2DumpName__
533 if theStudyEntry in __entry2DumpName__:
534 return __entry2DumpName__[theStudyEntry]
537 def BreakLink(self, theEntry):
539 Breaks links to not-dead shape, make the shape as dead
542 aSO = aStudy.FindObjectID(theEntry)
545 aRes, aSSO = aSO.ReferencedObject()
547 return # only SObjects referenced to the SHAPER STUDY objects are allowed
548 anIOR = aSSO.GetIOR()
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):
555 return # do nothing for reference to already dead shape
556 aDeadShape = anObj.MakeDead()
558 aMeshSObject = aSO.GetFather()
559 aMeshObject = aMeshSObject.GetObject()
561 aBuilder = aStudy.NewBuilder()
562 aBuilder.RemoveReference(aSO) # reset reference to the dead shape
563 aBuilder.Addreference(aSO, aDeadShape.GetSO())
565 # check also sub-structure of the mesh to find references to sub-objects that become dead
566 breakLinkForSubElements(aSO, aDeadShape)
568 # Replace shape object in the parent mesh
569 aMeshObject.ReplaceShape(aDeadShape)
573 Searches a shape object by the SHAPER entry. Used in the python dump script
576 aRoots = aStudy.NewChildIterator(findOrCreateComponent())
581 anObj = salome.orb.string_to_object(anIOR)
582 if anObj and type(anObj) == SHAPERSTUDY_ORB._objref_SHAPER_Object and anObj.GetEntry() == theEntry:
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()
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,)
597 return None # not found
599 def archive(theShape, theXAOFile):
601 Creates a dead shapes under the theShape and restores these dead objects state basing on theXAOFile
605 # searching for the last dead
606 aDeads = aStudy.NewChildIterator(theShape.GetSO().FindSubObject(10000)[1])
607 aLastDeadSO = aDeads.Value()
609 aLastDeadSO = aDeads.Value()
612 aDShape = aLastDeadSO.GetObject()
614 aXAO = StudyData_Swig.StudyData_XAO()
615 anError = aXAO.Import(theXAOFile)
617 print("Error of XAO file import: " + anError)
619 aDShape.SetShapeByPointer(aXAO.GetShape())
621 # add groups and fields to the result
624 aSOIter = aStudy.NewChildIterator(aLastDeadSO)
625 while aSOIter.More():
626 aGroupSO = aSOIter.Value()
627 anIOR = aGroupSO.GetIOR()
629 aGroup = salome.orb.string_to_object(anIOR)
630 if isinstance(aGroup, SHAPERSTUDY_ORB._objref_SHAPER_Group):
632 aGroup.SetSelectionType(aXAO.GetGroupDimension(aGroupIndex))
634 for aSel in aXAO.GetGroupSelection(aGroupIndex):
635 aSelection.append(aSel)
636 aGroup.SetSelection(aSelection)
638 elif isinstance(aGroup, SHAPERSTUDY_ORB._objref_SHAPER_Field):
641 aValType = aXAO.GetValuesType(aFieldIndex)
642 aField.SetValuesType(aValType)
643 aField.SetSelectionType(aXAO.GetSelectionType(aFieldIndex))
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):
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)
664 return None # not found
666 def isFather(theFather, theChild):
668 Returns true if theChild SObject is a child of theFather SObject
670 aChild = theChild.GetFather()
671 while aChild.Depth() > theFather.Depth():
672 aChild = aChild.GetFather()
673 return aChild.GetID() == theFather.GetID()
675 def breakLinkForSubElements(theMainShapeSO, theDeadShape):
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
682 aBuilder = aStudy.NewBuilder()
683 aRoot = theMainShapeSO.GetFather()
684 anIters = [aStudy.NewChildIterator(aRoot)]
686 anOriginShapeSO = theDeadShape.GetSO().GetFather().GetFather()
688 aLast = anIters[len(anIters) - 1]
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))
699 anIters.remove(aLast)
701 # associate the number of sub-objects of the referenced objects
702 aMapSubEntryToIndex = {}
703 aSSOIter = aStudy.NewChildIterator(anOriginShapeSO)
705 while aSSOIter.More():
706 aSub = aSSOIter.Value()
708 aMapSubEntryToIndex[aSub.GetID()] = anIndex
709 anIndex = anIndex + 1
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
721 aBuilder.RemoveReference(aSubSO) # reset reference to the dead shape
722 aBuilder.Addreference(aSubSO, aDeadSubSO)