-# Copyright (C) 2007-2019 CEA/DEN, EDF R&D, OPEN CASCADE
-#
-# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+# Copyright (C) 2019-2021 CEA/DEN, EDF R&D
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
import StudyData_Swig
+# for unit tests correct execution
+salome.salome_init(1)
+
__entry2IOR__ = {}
__entry2DumpName__ = {}
-class SHAPERSTUDY(SHAPERSTUDY_ORB__POA.Gen,
- SALOME_ComponentPy.SALOME_ComponentPy_i,
- SALOME_DriverPy.SALOME_DriverPy_i):
-
+class SHAPERSTUDY_Gen(SHAPERSTUDY_ORB__POA.Gen, SALOME_ComponentPy.SALOME_ComponentPy_i, SALOME_DriverPy.SALOME_DriverPy_i):
ShapeType = {"AUTO":-1, "COMPOUND":0, "COMPSOLID":1, "SOLID":2, "SHELL":3, "FACE":4, "WIRE":5, "EDGE":6, "VERTEX":7, "SHAPE":8, "FLAT":9}
- ShaperIcons = {GEOM.COMPOUND:"SHAPER_ICON_COMPSOLID",
- GEOM.COMPSOLID:"SHAPER_ICON_COMPSOLID",
- GEOM.SOLID:"SHAPER_ICON_SOLID",
- GEOM.SHELL:"SHAPER_ICON_SHELL",
- GEOM.FACE:"SHAPER_ICON_FACE",
- GEOM.WIRE:"SHAPER_ICON_WIRE",
- GEOM.EDGE:"SHAPER_ICON_EDGE",
- GEOM.VERTEX:"SHAPER_ICON_VERTEX",
- GEOM.SHAPE:"SHAPER_ICON_SOLID",
- GEOM.FLAT:"SHAPER_ICON_FACE"
+ ShaperIcons = {GEOM.COMPOUND:"compsolid.png",
+ GEOM.COMPSOLID:"compsolid.png",
+ GEOM.SOLID:"solid.png",
+ GEOM.SHELL:"shell.png",
+ GEOM.FACE:"face.png",
+ GEOM.WIRE:"wire.png",
+ GEOM.EDGE:"edge.png",
+ GEOM.VERTEX:"vertex.png",
+ GEOM.SHAPE:"solid.png",
+ GEOM.FLAT:"face.png"
}
- def __init__ ( self, orb, poa, contID, containerName, instanceName, interfaceName ):
- """
- Construct an instance of SHAPERSTUDY module engine.
- The class SHAPERSTUDY implements CORBA interface Gen (see SHAPERSTUDY_Gen.idl).
- It is inherited (via GEOM_Gen) from the classes SALOME_ComponentPy_i (implementation of
- Engines::EngineComponent CORBA interface - SALOME component) and SALOME_DriverPy_i
- (implementation of SALOMEDS::Driver CORBA interface - SALOME module's engine).
- """
- SALOME_ComponentPy.SALOME_ComponentPy_i.__init__(self, orb, poa,
- contID, containerName, instanceName, interfaceName, False)
- SALOME_DriverPy.SALOME_DriverPy_i.__init__(self, interfaceName)
- #
- #self._naming_service = SALOME_ComponentPy.SALOME_NamingServicePy_i( self._orb )
- #
- pass
-
def FindOrCreateShape( self, theInternalEntry ):
"""
Searches existing or creates a new SHAPERSTUDY_Object to interact with SHAPER
while aSOIter.More():
aSO = aSOIter.Value()
anIOR = aSO.GetIOR()
- anObj = salome.orb.string_to_object(anIOR)
- if isinstance(anObj, SHAPERSTUDY_ORB._objref_SHAPER_Object):
- if anObj.GetEntry() == theInternalEntry:
- return anObj
+ if len(anIOR):
+ anObj = salome.orb.string_to_object(anIOR)
+ if anObj and isinstance(anObj, SHAPERSTUDY_ORB._objref_SHAPER_Object):
+ if anObj.GetEntry() == theInternalEntry:
+ return anObj
aSOIter.Next()
aShapeObj = SHAPERSTUDY_Object.SHAPERSTUDY_Object()
anIter = aStudy.NewChildIterator(theFatherSO)
while anIter.More():
if anIter.Value().Tag() == 10000: # skip the history folder
+ anIter.Next()
continue
aCurrentTag = anIter.Value().Tag() + 1
+ anIter.Next()
if aTag < aCurrentTag:
aTag = aCurrentTag
- anIter.Next()
if aTag == 10000: # to avoid putting the object to the history folder
aTag += 1
aResultSO = aBuilder.NewObjectToTag(theFatherSO, aTag)
aResult += anObj.GetEntry() + "|" + str(anObj.GetSelectionType())
aSelList = anObj.GetSelection()
aResult += "|" + str(' '.join(str(anI) for anI in aSelList))
+ aSelListOld = anObj.GetSelectionOld()
+ aResult += ";" + str(' '.join(str(anI) for anI in aSelListOld))
elif type(anObj) == SHAPERSTUDY_ORB._objref_SHAPER_Field:
if len(aResult):
aResult += '|'
aResult += " " + str(aVal) # all values of step
aSelList = anObj.GetSelection()
aResult += "|" + str(' '.join(str(anI) for anI in aSelList))
+ aSelListOld = anObj.GetSelectionOld()
+ aResult += ";" + str(' '.join(str(anI) for anI in aSelListOld))
elif isinstance(anObj, SHAPERSTUDY_ORB._objref_SHAPER_Object):
if len(aResult):
aResult += '|'
- # store internal entry, current and old shapes in BRep format
- aResult += anObj.GetEntry() + "|" + anObj.GetShapeStream().decode()
+ # store internal entry + tick, current and old shapes in BRep format
+ aResult += anObj.GetEntry() + " " + str(anObj.GetTick())
+ aResult += "|" + anObj.GetShapeStream().decode()
aResult += "|" + anObj.GetOldShapeStream().decode()
return aResult.encode()
if anId.startswith('group') or (anId.startswith('dead') and anId.count("group") > 0): # group object
anObj = SHAPERSTUDY_Object.SHAPERSTUDY_Group()
if len(aSub):
- anObj.SetSelection([int(anI) for anI in aSub.split(' ')])
+ aSel = aSub.split(";")
+ if len(aSel) > 1 and len(aSel[1]):
+ anObj.SetSelection([int(anI) for anI in aSel[1].split(' ')]) # old selection
+ anObj.SetSelection([int(anI) for anI in aSel[0].split(' ')])
anObj.SetSelectionType(int(aNewShapeStream))
elif anId.startswith('field') or (anId.startswith('dead') and anId.count("field") > 0): # field object
anObj = SHAPERSTUDY_Object.SHAPERSTUDY_Field()
if len(aSub):
- anObj.SetSelection([int(anI) for anI in aSub.split(' ')])
+ aSel = aSub.split(";")
+ if len(aSel) > 1:
+ anObj.SetSelection([int(anI) for anI in aSel[1].split(' ')]) # old selection
+ anObj.SetSelection([int(anI) for anI in aSel[0].split(' ')])
aParams = aNewShapeStream.split(" ")
anObj.SetSelectionType(int(aParams[0]))
aTypeStr = aParams[1]
for aValIndex in range(aNumValsInStep):
aVals.append(float(aParams[aStepStartIndex + aValIndex + 1]))
anObj.AddFieldStep(aStampId, aStepNum + 1, aVals)
+ anObj.SetTick(-3)
else: # shape object by BRep in the stream: set old first then new
anObj = SHAPERSTUDY_Object.SHAPERSTUDY_Object()
if len(aSub):
anObj.SetShapeByStream(aSub)
anObj.SetShapeByStream(aNewShapeStream)
if anObj:
- anObj.SetEntry(anId)
+ anEntryAndTick = anId.split(" ")
+ anObj.SetEntry(anEntryAndTick[0])
+ if len(anEntryAndTick) > 1:
+ anObj.SetTick(int(anEntryAndTick[1]))
anIOR = salome.orb.object_to_string(anObj._this())
- __entry2IOR__[anId] = anIOR
+ __entry2IOR__[anEntryAndTick[0]] = anIOR
aSubNum = 1
return 1
if persistentID in __entry2IOR__:
aRes = __entry2IOR__[persistentID]
if len(aRes): # set SO from the study, the sobject param is temporary, don't store it
- salome.orb.string_to_object(aRes).SetSO(getStudy().FindObjectID(sobject.GetID()))
+ aSO = getStudy().FindObjectID(sobject.GetID())
+ anObj = salome.orb.string_to_object(aRes)
+ anObj.SetSO(aSO)
+ # restore tick of the sub-object
+ anIOR = aSO.GetFather().GetIOR()
+ if len(anIOR):
+ anFatherObj = salome.orb.string_to_object(anIOR)
+ if anFatherObj and isinstance(anFatherObj, SHAPERSTUDY_ORB._objref_SHAPER_Object):
+ anObj.SetTick(anFatherObj.GetTick())
return aRes
return ""
global __entry2DumpName__
anEntry = "s" + theShapeObj.GetEntry()
if anEntry in __entry2DumpName__:
- return "model.featureStringId(" + __entry2DumpName__[anEntry] + ")"
+ anArg = ""
+ if anEntry.count(":") == 2: # not first result of the feature, set argument as a number
+ anArg = ", " + anEntry[anEntry.rfind(":") + 1:]
+ return "model.featureStringId(" + __entry2DumpName__[anEntry] + anArg + ")"
return "\"" + theShapeObj.GetEntry() + "\""
+ def OrderGroups(self, theStudy, theStartSO, theIsGroup):
+ """
+ An internal method for returning sub-groups or sub-fields in a correct order basing on their IDs
+ """
+ aResult = []
+ anIter = theStudy.NewChildIterator(theStartSO)
+ anOrder = {} # entry to object
+ while anIter.More():
+ anSO = anIter.Value()
+ anIter.Next()
+ anIOR = anSO.GetIOR()
+ if len(anIOR):
+ anObj = salome.orb.string_to_object(anIOR)
+ if (theIsGroup and isinstance(anObj, SHAPERSTUDY_ORB._objref_SHAPER_Group)) or \
+ (not theIsGroup and isinstance(anObj, SHAPERSTUDY_ORB._objref_SHAPER_Field)):
+ anEntry = anObj.GetEntry()
+ aSplit = anEntry.split(":")
+ if len(aSplit) > 1 and aSplit[1].isdecimal():
+ anID = int(aSplit[1])
+ anOrder[anID] = anObj
+
+ for aKey in sorted(anOrder.keys()):
+ aResult.append(anOrder[aKey])
+
+ return aResult
+
+
def DumpPython( self, isPublished, isMultiFile ):
"""
Dump module data to the Python script.
aRoots.Next()
script = []
if len(aShapeObjects):
- script.append("if 'model' in globals():")
- script.append("\tmodel.publishToShaperStudy()")
+ script.append("model.publishToShaperStudy()")
script.append("import SHAPERSTUDY")
for aShapeObj in aShapeObjects:
# check this shape also has sub-groups and fields
+ anOrderedGroups = self.OrderGroups(aStudy, aShapeObj.GetSO(), True)
+ anOrderedFields = self.OrderGroups(aStudy, aShapeObj.GetSO(), False)
+ anObjects = anOrderedGroups + anOrderedFields
+
aGroupVarNames = []
- aSOIter = aStudy.NewChildIterator(aShapeObj.GetSO())
- while aSOIter.More():
- aGroupSO = aSOIter.Value()
- anIOR = aGroupSO.GetIOR()
- if len(anIOR):
- aGroup = salome.orb.string_to_object(anIOR)
- if isinstance(aGroup, SHAPERSTUDY_ORB._objref_SHAPER_Group) or \
- isinstance(aGroup, SHAPERSTUDY_ORB._objref_SHAPER_Field):
- aGroupVarName = self.UniqueDumpName(aGroup.GetName(), aGroupSO.GetID())
- aGroupVarNames.append(aGroupVarName)
- aSOIter.Next()
+ for anObj in anObjects:
+ aGroupVarName = self.UniqueDumpName(anObj.GetName(), anObj.GetSO().GetID())
+ aGroupVarNames.append(aGroupVarName)
+
aShapeVar = self.UniqueDumpName(aShapeObj.GetName(), aShapeObj.GetSO().GetID())
aShapeStr = aShapeVar + ", "
for aGName in aGroupVarNames:
aShapeStr += aGName + ", "
- aShapeStr += "= SHAPERSTUDY.shape(" + self.GetShaperEntry(aShapeObj) +")"
+ aShaperEntry = self.GetShaperEntry(aShapeObj)
+ aShapeStr += "= SHAPERSTUDY.shape(" + aShaperEntry +")"
+ # 18884 : comment the line with dead shapes for now
+ if aShaperEntry.startswith("\"dead"):
+ script.append("# This shape does not exist among the SHAPER results; if it is referenced by SMESH, this may cause an error")
+ aShapeStr = "# " + aShapeStr
script.append(aShapeStr)
# dump also dead-shapes with groups and fields in the XAO format
aRes, aHistSO = aShapeObj.GetSO().FindSubObject(10000) # the History folder
anArchiveNum += 1
aDeadVarName = self.UniqueDumpName(aDeadShape.GetName(), aDSO.GetID())
aDeadString += aDeadVarName + ", "
- aDGroupIter = aStudy.NewChildIterator(aDSO)
-
- while aDGroupIter.More():
- aDeadGroup = aDGroupIter.Value().GetObject()
- if isinstance(aDeadGroup, SHAPERSTUDY_ORB._objref_SHAPER_Group):
- aDGroupVarName = self.UniqueDumpName(aDeadGroup.GetName(), aDGroupIter.Value().GetID())
- aDeadString += aDGroupVarName + ", "
- aGroupID = aXAO.AddGroup(aDeadGroup.GetSelectionType(), aDGroupVarName)
- for aSel in aDeadGroup.GetSelection():
- aXAO.AddGroupSelection(aGroupID, aSel)
- elif isinstance(aDeadGroup, SHAPERSTUDY_ORB._objref_SHAPER_Field):
- aDeadField = aDeadGroup
- aDFieldVarName = self.UniqueDumpName(aDeadField.GetName(), aDGroupIter.Value().GetID())
- aDeadString += aDFieldVarName + ", "
- aComponents = aDeadField.GetComponents()
- aFieldID = aXAO.AddField(aDeadField.GetValuesType(), aDeadField.GetSelectionType(), \
- len(aComponents), aDFieldVarName)
- for aCompIndex in range(len(aComponents)):
- aXAO.SetFieldComponent(aFieldID, aCompIndex, aComponents[aCompIndex])
- aSteps = aDeadField.GetSteps()
- for aStep in aSteps:
- aFieldStep = aDeadField.GetStep(aStep)
- aXAO.AddStep(aFieldID, aStep, aFieldStep.GetStamp())
- aStepVals = aFieldStep.GetValues()
- for aValue in aStepVals:
- aXAO.AddStepValue(aFieldID, aStep, str(aValue))
- aDGroupIter.Next()
+
+ aGroups = self.OrderGroups(aStudy, aDSO, True)
+ for aDeadGroup in aGroups:
+ aDGroupVarName = self.UniqueDumpName(aDeadGroup.GetName(), aDeadGroup.GetSO().GetID())
+ aDeadString += aDGroupVarName + ", "
+ aGroupID = aXAO.AddGroup(aDeadGroup.GetSelectionType(), aDGroupVarName)
+ for aSel in aDeadGroup.GetSelection():
+ aXAO.AddGroupSelection(aGroupID, aSel)
+
+ aFields = self.OrderGroups(aStudy, aDSO, False)
+ for aDeadField in aFields:
+ aDFieldVarName = self.UniqueDumpName(aDeadField.GetName(), aDeadField.GetSO().GetID())
+ aDeadString += aDFieldVarName + ", "
+ aComponents = aDeadField.GetComponents()
+ aFieldID = aXAO.AddField(aDeadField.GetValuesType(), aDeadField.GetSelectionType(), \
+ len(aComponents), aDFieldVarName)
+ for aCompIndex in range(len(aComponents)):
+ aXAO.SetFieldComponent(aFieldID, aCompIndex, aComponents[aCompIndex])
+ aSteps = aDeadField.GetSteps()
+ for aStep in aSteps:
+ aFieldStep = aDeadField.GetStep(aStep)
+ aXAO.AddStep(aFieldID, aStep, aFieldStep.GetStamp())
+ aStepVals = aFieldStep.GetValues()
+ for aValue in aStepVals:
+ aXAO.AddStepValue(aFieldID, aStep, str(aValue))
+
aXAO.Export(anArchiveName)
aDeadString += " = SHAPERSTUDY.archive(" + aShapeVar + ", \"" + anArchiveName + "\")"
script.append(aDeadString)
return __entry2DumpName__[theStudyEntry]
return ""
- def IsFather(theFather, theChild):
- """
- Returns true if theChild SObject is a child of theFather SObject
- """
- aChild = theChild.GetFather()
- while aChild.Depth() > theFather.Depth():
- aChild = aChild.GetFather()
- return aChild.GetID() == theFather.GetID()
-
def BreakLink(self, theEntry):
"""
Breaks links to not-dead shape, make the shape as dead
aBuilder.Addreference(aSO, aDeadShape.GetSO())
# check also sub-structure of the mesh to find references to sub-objects that become dead
- aRoot = aSO.GetFather()
- anIters = [aStudy.NewChildIterator(aRoot)]
- aSubList = []
- while len(anIters):
- aLast = anIters[len(anIters) - 1]
- if aLast.More():
- aSub = aLast.Value()
- aRes, aSubRef = aSub.ReferencedObject()
- if aRes and SHAPERSTUDY.IsFather(aSSO, aSubRef):
- aReferenced = aSubRef.GetObject()
- if aReferenced and not aReferenced.IsDead():
- aSubList.append(aSub)
- anIters.append(aStudy.NewChildIterator(aSub))
- aLast.Next()
- else:
- anIters.remove(aLast)
- if len(aSubList):
- # associate the number of sub-objects of the referenced objects
- aMapSubEntryToIndex = {}
- aSSOIter = aStudy.NewChildIterator(aSSO)
- anIndex = 1
- while aSSOIter.More():
- aSub = aSSOIter.Value()
- if aSub.GetIOR():
- aMapSubEntryToIndex[aSub.GetID()] = anIndex
- anIndex = anIndex + 1
- aSSOIter.Next()
- for aSubSO in aSubList:
- aRes, aSubRef = aSubSO.ReferencedObject()
- if aRes and aSubRef.GetID() in aMapSubEntryToIndex:
- anIndex = aMapSubEntryToIndex[aSubRef.GetID()]
- aDeadIter = aStudy.NewChildIterator(aDeadShape.GetSO())
- while aDeadIter.More(): # iterate dead subs to find object with the same index
- aDeadSubSO = aDeadIter.Value()
- if aDeadSubSO.GetIOR():
- anIndex = anIndex - 1
- if anIndex == 0:
- # for a submesh there is no ReplaceShape, but the shape is not updated
- # anyway, so no need to update it here
- #aSubMeshSO = aSubSO.GetFather() # Replace shape object in the parent mesh
- #aSubMeshObject = aSubMeshSO.GetObject()
- #if aSubMeshObject:
- # aSubMeshObject.ReplaceShape(aDeadSubSO.GetObject())
- aBuilder.RemoveReference(aSubSO) # reset reference to the dead shape
- aBuilder.Addreference(aSubSO, aDeadSubSO)
- aDeadIter.Next()
+ breakLinkForSubElements(aSO, aDeadShape)
# Replace shape object in the parent mesh
aMeshObject.ReplaceShape(aDeadShape)
aSOIter.Next()
return aRes
return None # not found
+
+def isFather(theFather, theChild):
+ """
+ Returns true if theChild SObject is a child of theFather SObject
+ """
+ aChild = theChild.GetFather()
+ while aChild.Depth() > theFather.Depth():
+ aChild = aChild.GetFather()
+ return aChild.GetID() == theFather.GetID()
+
+def breakLinkForSubElements(theMainShapeSO, theDeadShape):
+ """
+ Checks sub-structure of the SMESH-mesh to find references to sub-objects that become dead.
+ theMainShapeSO is SObject with reference to real SHAPERSTUDY shape, located under the Mesh node.
+ theDeadShape is a newly created dead shape instance
+ """
+ aStudy = getStudy()
+ aBuilder = aStudy.NewBuilder()
+ aRoot = theMainShapeSO.GetFather()
+ anIters = [aStudy.NewChildIterator(aRoot)]
+ aSubList = []
+ anOriginShapeSO = theDeadShape.GetSO().GetFather().GetFather()
+ while len(anIters):
+ aLast = anIters[len(anIters) - 1]
+ if aLast.More():
+ aSub = aLast.Value()
+ aRes, aSubRef = aSub.ReferencedObject()
+ if aRes and isFather(anOriginShapeSO, aSubRef):
+ aReferenced = aSubRef.GetObject()
+ if aReferenced and not aReferenced.IsDead():
+ aSubList.append(aSub)
+ anIters.append(aStudy.NewChildIterator(aSub))
+ aLast.Next()
+ else:
+ anIters.remove(aLast)
+ if len(aSubList):
+ # associate the number of sub-objects of the referenced objects
+ aMapSubEntryToIndex = {}
+ aSSOIter = aStudy.NewChildIterator(anOriginShapeSO)
+ anIndex = 1
+ while aSSOIter.More():
+ aSub = aSSOIter.Value()
+ if aSub.GetIOR():
+ aMapSubEntryToIndex[aSub.GetID()] = anIndex
+ anIndex = anIndex + 1
+ aSSOIter.Next()
+ for aSubSO in aSubList:
+ aRes, aSubRef = aSubSO.ReferencedObject()
+ if aRes and aSubRef.GetID() in aMapSubEntryToIndex:
+ anIndex = aMapSubEntryToIndex[aSubRef.GetID()]
+ aDeadIter = aStudy.NewChildIterator(theDeadShape.GetSO())
+ while aDeadIter.More(): # iterate dead subs to find object with the same index
+ aDeadSubSO = aDeadIter.Value()
+ if aDeadSubSO.GetIOR():
+ anIndex = anIndex - 1
+ if anIndex == 0:
+ aBuilder.RemoveReference(aSubSO) # reset reference to the dead shape
+ aBuilder.Addreference(aSubSO, aDeadSubSO)
+ aDeadIter.Next()
+ pass
+
+class SHAPERSTUDY(SHAPERSTUDY_Gen, SHAPERSTUDY_ORB__POA.Gen, SALOME_ComponentPy.SALOME_ComponentPy_i, SALOME_DriverPy.SALOME_DriverPy_i):
+ """
+ Implementation with naming_service server.
+ """
+ def __init__ ( self, orb, poa, contID, containerName, instanceName, interfaceName ):
+ """
+ Construct an instance of SHAPERSTUDY module engine.
+ The class SHAPERSTUDY implements CORBA interface Gen (see SHAPERSTUDY_Gen.idl).
+ It is inherited (via GEOM_Gen) from the classes SALOME_ComponentPy_i (implementation of
+ Engines::EngineComponent CORBA interface - SALOME component) and SALOME_DriverPy_i
+ (implementation of SALOMEDS::Driver CORBA interface - SALOME module's engine).
+ """
+ global __entry2IOR__, __entry2DumpName__
+ __entry2IOR__.clear()
+ __entry2DumpName__.clear()
+ SALOME_ComponentPy.SALOME_ComponentPy_i.__init__(self, orb, poa, contID, containerName, instanceName, interfaceName, False)
+ SALOME_DriverPy.SALOME_DriverPy_i.__init__(self, interfaceName)
+ pass
+
+class SHAPERSTUDY_No_Session(SHAPERSTUDY_Gen, SHAPERSTUDY_ORB__POA.Gen, SALOME_ComponentPy.SALOME_ComponentPy_Gen_i, SALOME_DriverPy.SALOME_DriverPy_i):
+ """
+ Implementation without naming_service server.
+ """
+ def __init__ ( self, orb, poa, contID, containerName, instanceName, interfaceName ):
+ global __entry2IOR__, __entry2DumpName__
+ __entry2IOR__.clear()
+ __entry2DumpName__.clear()
+ SALOME_ComponentPy.SALOME_ComponentPy_Gen_i.__init__(self, orb, poa, contID, containerName, instanceName, interfaceName, False)
+ SALOME_DriverPy.SALOME_DriverPy_i.__init__(self, interfaceName)
+ pass