X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FPY%2FSHAPERSTUDY.py;h=f7d50d21fb90ef70a33b3e7a28dc14b5e8cbba31;hb=6a1ca8d833e9b3d06da192cc3e14704885a99098;hp=4f26ea701bcf333829e7c8d9b71ee77913fd3bda;hpb=b6987d7406dded684f1c541cca3016d45b4f336a;p=modules%2Fshaper_study.git diff --git a/src/PY/SHAPERSTUDY.py b/src/PY/SHAPERSTUDY.py index 4f26ea7..f7d50d2 100644 --- a/src/PY/SHAPERSTUDY.py +++ b/src/PY/SHAPERSTUDY.py @@ -1,7 +1,4 @@ -# 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 @@ -32,44 +29,30 @@ import SHAPERSTUDY_IOperations import GEOM import SMESH -__entry2IOR__ = {} +import StudyData_Swig +# for unit tests correct execution +salome.salome_init(1) -class SHAPERSTUDY(SHAPERSTUDY_ORB__POA.Gen, - SALOME_ComponentPy.SALOME_ComponentPy_i, - SALOME_DriverPy.SALOME_DriverPy_i): +__entry2IOR__ = {} +__entry2DumpName__ = {} +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 @@ -80,10 +63,11 @@ class SHAPERSTUDY(SHAPERSTUDY_ORB__POA.Gen, 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() @@ -96,25 +80,34 @@ class SHAPERSTUDY(SHAPERSTUDY_ORB__POA.Gen, if theFather is not NULL the object is placed under theFather's SObject. Returns a SObject where theObject is placed """ + if not theObject.GetEntry(): + return None # object not existing in shaper aStudy = getStudy() aBuilder = aStudy.NewBuilder() isGroup = theObject.GetType() == 37 or theObject.GetType() == 52 if not theFather: if isGroup: return None # Group may be added only under the shape-father - theFather = findOrCreateComponent() + theFatherSO = findOrCreateComponent() + else: + theFatherSO = theFather.GetSO() aResultSO = None - if isGroup: # add group to the third sub-label or later to keep space for reference and "History" - aTag = 3 - anIter = aStudy.NewChildIterator(theFather) + if isGroup: + aTag = 2 + 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() - aResultSO = aBuilder.NewObjectToTag(theFather, aTag) + if aTag == 10000: # to avoid putting the object to the history folder + aTag += 1 + aResultSO = aBuilder.NewObjectToTag(theFatherSO, aTag) else: - aResultSO = aBuilder.NewObject(theFather); + aResultSO = aBuilder.NewObject(theFatherSO); aResultSO.SetAttrString("AttributeName", theName) if theObject is not None: anIOR = salome.orb.object_to_string(theObject) @@ -128,7 +121,7 @@ class SHAPERSTUDY(SHAPERSTUDY_ORB__POA.Gen, aType = SHAPERSTUDY_Object.__shape_types__[theObject.GetSelectionType()] else: aType = theObject.GetShapeType() - aPixmap.SetPixMap(SHAPERSTUDY.ShaperIcons[aType]) + aPixmap.SetPixMap(self.ShaperIcons[aType]) # add a red-reference that means that this is an active reference to SHAPER result if not isGroup: @@ -137,6 +130,13 @@ class SHAPERSTUDY(SHAPERSTUDY_ORB__POA.Gen, return aResultSO + def StoreVariableName(self, theEntry, theVarName): + """ + Stores the variable names of the SHAPER dump to python + """ + __entry2DumpName__["s" + theEntry] = theVarName + + def AddSubShape( theMainShape, theIndices ): """ Add a sub-shape defined by indices in theIndices @@ -184,22 +184,6 @@ class SHAPERSTUDY(SHAPERSTUDY_ORB__POA.Gen, pass return IOR - def GetAllDumpNames( self ): - """ - Returns all names with which Object's was dumped - into python script to avoid the same names in SMESH script - """ - return [""] - - def GetDumpName( self, theStudyEntry ): - """ - Returns a name with which a GEOM_Object was dumped into python script - - Parameters: - theStudyEntry is an entry of the Object in the study - """ - return "test" - def Save( self, component, URL, isMultiFile ): """ Saves data: all objects into one file @@ -223,20 +207,49 @@ class SHAPERSTUDY(SHAPERSTUDY_ORB__POA.Gen, for aSO in aSOList: # for each sobject export shapes stream if exists anIOR = aSO.GetIOR() + if not len(anIOR): + continue anObj = salome.orb.string_to_object(anIOR) - if isinstance(anObj, SHAPERSTUDY_ORB._objref_SHAPER_Group): + if type(anObj) == SHAPERSTUDY_ORB._objref_SHAPER_Group: if len(aResult): - aResult = aResult + '|' + aResult += '|' # store internal entry, type and list of indices of the group selection (separated by spaces) - aResult = aResult + anObj.GetEntry() + "|" + str(anObj.GetSelectionType()) + aResult += anObj.GetEntry() + "|" + str(anObj.GetSelectionType()) aSelList = anObj.GetSelection() - aResult = aResult + "|" + str(' '.join(str(anI) for anI in aSelList)) + 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 += '|' + # same as for group, but in addition to the second string part - field specifics + aResult += anObj.GetEntry() + "|" + str(anObj.GetSelectionType()) + aResult += " " + str(anObj.GetDataType()) # values type + aSteps = anObj.GetSteps() + aResult += " " + str(len(aSteps)) # number of steps + aComps = anObj.GetComponents() + aResult += " " + str(len(aComps)) # number of components + for aComp in aComps: # components strings: but before remove spaces and '|' + aCoded = aComp.replace(" ", "__space__").replace("|", "__vertical_bar__") + aResult += " " + aCoded + for aStepNum in range(len(aSteps)): + aVals = anObj.GetStep(aStepNum + 1).GetValues() + if aStepNum == 0: + aResult += " " + str(len(aVals)) # first the number of values in the step + aResult += " " + str(anObj.GetStep(aStepNum + 1).GetStamp()) # ID of stamp in step + for aVal in aVals: + 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 = aResult + '|' - # store internal entry, current and old shapes in BRep format - aResult = aResult + anObj.GetEntry() + "|" + anObj.GetShapeStream().decode() - aResult = aResult + "|" + anObj.GetOldShapeStream().decode() + aResult += '|' + # 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() @@ -259,20 +272,64 @@ class SHAPERSTUDY(SHAPERSTUDY_ORB__POA.Gen, aSubNum = 3 else: # create objects by 3 arguments anObj = None - if anId.startswith('group'): # group object + if anId.startswith('group') or (anId.startswith('dead') and anId.count("group") > 0): # group object anObj = SHAPERSTUDY_Object.SHAPERSTUDY_Group() - if len(aNewShapeStream): - anObj.SetSelection([int(anI) for anI in aSub.split(' ')]) + if len(aSub): + 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): + 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] + if (aTypeStr == "FDT_Bool"): + anObj.SetValuesType(0) + elif (aTypeStr == "FDT_Int"): + anObj.SetValuesType(1) + elif (aTypeStr == "FDT_Double"): + anObj.SetValuesType(2) + elif (aTypeStr == "FDT_String"): + anObj.SetValuesType(3) + aSteps = [] + aNumSteps = int(aParams[2]) + for aVal in range(aNumSteps): + aSteps.append(aVal + 1) + anObj.SetSteps(aSteps) + aCompNum = int(aParams[3]) + aCompNames = [] + for aCompNameIndex in range(aCompNum): + aCompName = aParams[4 + aCompNameIndex].replace("__space__", " ").replace("__vertical_bar__", "|") + aCompNames.append(aCompName) + anObj.SetComponents(aCompNames) + aNumValsInStep = int(aParams[4 + aCompNum]) + for aStepNum in range(aNumSteps): + aStepStartIndex = 4 + aCompNum + aStepNum * (aNumValsInStep + 1) + 1 + aStampId = int(aParams[aStepStartIndex]) + aVals = [] + 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 @@ -282,7 +339,8 @@ class SHAPERSTUDY(SHAPERSTUDY_ORB__POA.Gen, The internal entry of the Object is returned. """ anObj = salome.orb.string_to_object(IOR) - if anObj and isinstance(anObj, SHAPERSTUDY_ORB._objref_SHAPER_Object): + if anObj and (isinstance(anObj, SHAPERSTUDY_ORB._objref_SHAPER_Object) or \ + isinstance(anObj, SHAPERSTUDY_ORB._objref_SHAPER_Field)): return anObj.GetEntry() return "" @@ -292,127 +350,205 @@ class SHAPERSTUDY(SHAPERSTUDY_ORB__POA.Gen, 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 "" + + def UniqueDumpName( self, theBaseName, theID ): + """ + Returns a unique name from the theBaseName. Keeps theBaseName if it was not used yet. + Stores the newly generated name into the global map __entry2DumpName__. + """ + global __entry2DumpName__ + aPrefix = 1 + # to avoid spaces and parenthesis in the variable name + aBaseName = theBaseName.replace(" ", "_").replace("(", "").replace(")", "") + aName = aBaseName + while aName in __entry2DumpName__.values(): + aName = aBaseName + "_" + str(aPrefix) + aPrefix = aPrefix + 1 + __entry2DumpName__[theID] = aName + return aName + + def GetShaperEntry(self, theShapeObj): + """ + Returns string in the python dump that generates the SHAPER entry: + it may be just entry string, or call for the SHAPER dump variable. + """ + global __entry2DumpName__ + anEntry = "s" + theShapeObj.GetEntry() + if anEntry in __entry2DumpName__: + 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. """ - return ("".encode(), 1) - - - - def CreateGroup( self, theMainShape, theShapeType ): - """ - Creates a new group which will store sub-shapes of theMainShape - """ - return GetIGroupOperations().CreateGroup( theMainShape, theShapeType ); - - def ExtractShapes( self, aShape, aType, isSorted = False ): - """ - Extract shapes (excluding the main shape) of given type. - - Parameters: - aShape The shape. - aType The shape type (see geompy.ShapeType) - isSorted Boolean flag to switch sorting on/off. - - Returns: - List of sub-shapes of type aType, contained in aShape. - """ - return [ SHAPERSTUDY_Object()._this() ] + global __entry2DumpName__ + # remove all non-SHAPER entries + aCopyMap = {} + for anEntry in __entry2DumpName__: + if anEntry.startswith("s"): + aCopyMap[anEntry] = __entry2DumpName__[anEntry] + __entry2DumpName__ = aCopyMap + + anArchiveNum = 1 + # collect all shape-objects in the SHAPERSTUDY tree + aShapeObjects = [] + aStudy = getStudy() + aRoots = aStudy.NewChildIterator(findOrCreateComponent()) + while aRoots.More(): + aSO = aRoots.Value() + anIOR = aSO.GetIOR() + if len(anIOR): + anObj = salome.orb.string_to_object(anIOR) + if anObj and type(anObj) == SHAPERSTUDY_ORB._objref_SHAPER_Object: + aShapeObjects.append(anObj) + aRoots.Next() + script = [] + if len(aShapeObjects): + 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 = [] + 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 + ", " + 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 + if aRes: + aDeads = aStudy.NewChildIterator(aHistSO) + while aDeads.More(): + aDSO = aDeads.Value() + aDIOR = aDSO.GetIOR() + if len(aDIOR): + aDeadShape = salome.orb.string_to_object(aDIOR) + if aDeadShape and type(aDeadShape) == SHAPERSTUDY_ORB._objref_SHAPER_Object: + aDeadString = "" + aXAO = StudyData_Swig.StudyData_XAO() + aXAO.SetShape(aDeadShape.getShape()) + anArchiveName = "archive_" + str(anArchiveNum) + ".xao" + if len(aStudy.GetDumpPath()): + anArchiveName = aStudy.GetDumpPath() + "/" + anArchiveName + anArchiveNum += 1 + aDeadVarName = self.UniqueDumpName(aDeadShape.GetName(), aDSO.GetID()) + aDeadString += aDeadVarName + ", " + + 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) + aDeads.Next() + pass + + script.append("") # to have an end-line in the end + result_str = "\n".join(script) + encoded_str = result_str.encode() + b'\0' # to avoid garbage symbols in the end + return (encoded_str, 1) - def GetSubShape( self, aShape, ListOfID ): + def GetAllDumpNames( self ): """ - Obtain a composite sub-shape of aShape, composed from sub-shapes - of aShape, selected by their unique IDs inside aShape - - Parameters: - aShape Shape to get sub-shape of. - ListOfID List of sub-shapes indices. + Returns all names with which Object's was dumped + into python script to avoid the same names in SMESH script """ - return SHAPERSTUDY_Object()._this() + global __entry2DumpName__ + aResultList = [] + for anEntry in __entry2DumpName__: + aResultList.append(__entry2DumpName__[anEntry]) + return aResultList - def GetSubShapeID( self, aShape, aSubShape ): + def GetDumpName( self, theStudyEntry ): """ - Obtain unique ID of sub-shape aSubShape inside aShape - of aShape, selected by their unique IDs inside aShape + Returns a name with which a GEOM_Object was dumped into python script Parameters: - aShape Shape to get sub-shape of. - aSubShape Sub-shapes of aShape. - """ - return 1 - - def MinDistance( self, theShape1, theShape2 ): - """ - Get minimal distance between the given shapes. - """ - return 0. - - def NumberOfEdges( self, theShape ): - """ - Gives quantity of edges in the given shape. - """ - return 0 - - def NumberOfFaces( self, ): - """ - Gives quantity of faces in the given shape. - """ - return 0 - - def PointCoordinates( self, theVertex ): - """ - Get point coordinates - """ - return 0,0,0 - - def SubShapeAll( self, aShape, aType ): - """ - Explode a shape on sub-shapes of a given type. - If the shape itself matches the type, it is also returned. - """ - return [ SHAPERSTUDY_Object()._this() ] - - def SubShapeName( self, aSubObj, aMainObj ): - """ - Get name for sub-shape aSubObj of shape aMainObj + theStudyEntry is an entry of the Object in the study """ + global __entry2DumpName__ + if theStudyEntry in __entry2DumpName__: + return __entry2DumpName__[theStudyEntry] return "" - def SubShapes( self, aShape, anIDs ): - """ - Get a set of sub-shapes defined by their unique IDs inside theMainShape - """ - return [ SHAPERSTUDY_Object()._this() ] - - def Tolerance( self, theShape ): - """ - Get min and max tolerances of sub-shapes of theShape - - Returns: - [FaceMin,FaceMax, EdgeMin,EdgeMax, VertMin,VertMax] - """ - return [0,0, 0,0, 0,0] - - def UnionList( self, theGroup, theSubShapes ): - """ - Adds to the group all the given shapes. No errors, if some shapes are already included. - """ - return GetIGroupOperations().UnionList( theGroup, theSubShapes ) - - 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 @@ -423,7 +559,7 @@ class SHAPERSTUDY(SHAPERSTUDY_ORB__POA.Gen, return aRes, aSSO = aSO.ReferencedObject() if not aRes: - return # only SObjects referenced to the SHAPEr STUDY objects are allowed + return # only SObjects referenced to the SHAPER STUDY objects are allowed anIOR = aSSO.GetIOR() if not anIOR: return # must be referenced to the SHAPER STUDY shape @@ -434,59 +570,201 @@ class SHAPERSTUDY(SHAPERSTUDY_ORB__POA.Gen, return # do nothing for reference to already dead shape aDeadShape = anObj.MakeDead() - # Replace shape object in the parent mesh aMeshSObject = aSO.GetFather() aMeshObject = aMeshSObject.GetObject() - aMeshObject.ReplaceShape(aDeadShape) - + aBuilder = aStudy.NewBuilder() aBuilder.RemoveReference(aSO) # reset reference to the dead shape 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) + +def shape(theEntry): + """ + Searches a shape object by the SHAPER entry. Used in the python dump script + """ + aStudy = getStudy() + aRoots = aStudy.NewChildIterator(findOrCreateComponent()) + while aRoots.More(): + aSO = aRoots.Value() + anIOR = aSO.GetIOR() + if len(anIOR): + anObj = salome.orb.string_to_object(anIOR) + if anObj and type(anObj) == SHAPERSTUDY_ORB._objref_SHAPER_Object and anObj.GetEntry() == theEntry: + aRes = (anObj,) + # add groups and fields to the result + aSOIter = aStudy.NewChildIterator(aSO) + 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): + aRes = aRes + (aGroup,) + aSOIter.Next() + return aRes + aRoots.Next() + return None # not found + +def archive(theShape, theXAOFile): + """ + Creates a dead shapes under the theShape and restores these dead objects state basing on theXAOFile + """ + theShape.MakeDead() + aStudy = getStudy() + # searching for the last dead + aDeads = aStudy.NewChildIterator(theShape.GetSO().FindSubObject(10000)[1]) + aLastDeadSO = aDeads.Value() + while aDeads.More(): + aLastDeadSO = aDeads.Value() + aDeads.Next() + + aDShape = aLastDeadSO.GetObject() + if aDShape: + aXAO = StudyData_Swig.StudyData_XAO() + anError = aXAO.Import(theXAOFile) + if (len(anError)): + print("Error of XAO file import: " + anError) + return None + aDShape.SetShapeByPointer(aXAO.GetShape()) + aRes = (aDShape,) + # add groups and fields to the result + aGroupIndex = 0 + aFieldIndex = 0 + aSOIter = aStudy.NewChildIterator(aLastDeadSO) + 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): + aRes += (aGroup,) + aGroup.SetSelectionType(aXAO.GetGroupDimension(aGroupIndex)) + aSelection = [] + for aSel in aXAO.GetGroupSelection(aGroupIndex): + aSelection.append(aSel) + aGroup.SetSelection(aSelection) + aGroupIndex += 1 + elif isinstance(aGroup, SHAPERSTUDY_ORB._objref_SHAPER_Field): + aField = aGroup + aRes += (aField,) + aValType = aXAO.GetValuesType(aFieldIndex) + aField.SetValuesType(aValType) + aField.SetSelectionType(aXAO.GetSelectionType(aFieldIndex)) + aCompNames = [] + for aCompName in aXAO.GetComponents(aFieldIndex): + aCompNames.append(aCompName) + aField.SetComponents(aCompNames) + aField.ClearFieldSteps() + aXAO.BeginSteps(aFieldIndex) + while aXAO.More(aFieldIndex): + aValsList = [] + for aVal in aXAO.GetValues(): + if aValType == 0: # boolean + aValsList.append(int(aVal)) + elif aValType == 1: # int + aValsList.append(int(aVal)) + elif aValType == 2: # double + aValsList.append(float(aVal)) + aField.AddFieldStep(aXAO.GetStamp(), aXAO.GetStepIndex(), aValsList) + aXAO.Next() + aFieldIndex += 1 + 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