Salome HOME
Implementation of Open/Save and Break-Link functionality on SHAPER shapes
[modules/shaper_study.git] / src / PY / SHAPERSTUDY.py
index 6730fb26d813267a0ac46da5acd2a01db8baf8fd..bc0df39a20b7b553a3381a83b13cb6362c4cb745 100644 (file)
 #
 
 import SHAPERSTUDY_ORB__POA
+import SHAPERSTUDY_ORB
 import SALOME_ComponentPy
 import SALOME_DriverPy
 import SALOMEDS
 from SHAPERSTUDY_utils import findOrCreateComponent, moduleName, getStudy, getORB
+import salome
+import SHAPERSTUDY_Object
+import GEOM
 
 __entry2IOR__ = {}
 
+
 class SHAPERSTUDY(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"}
 
     def __init__ ( self, orb, poa, contID, containerName, instanceName, interfaceName ):
         """
@@ -51,11 +67,25 @@ class SHAPERSTUDY(SHAPERSTUDY_ORB__POA.Gen,
         #
         pass
 
-    def publish( self, theShaperObj ):
+    def FindOrCreateShape( self, theInternalEntry ):
         """
-        Publish GEOM_Object corresponding to a given SHAPER object
+        Searches existing or creates a new SHAPERSTUDY_Object to interact with SHAPER
         """
-        return SHAPERSTUDY_Object()
+        # Searching in the study tree
+        aComponent = findOrCreateComponent()
+        aSOIter = getStudy().NewChildIterator(aComponent)
+        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
+          aSOIter.Next()
+
+        aShapeObj = SHAPERSTUDY_Object.SHAPERSTUDY_Object()
+        aShapeObj.SetEntry(theInternalEntry)
+        return aShapeObj._this()
 
     def AddInStudy( self, theObject, theName, theFather ):
         """
@@ -63,8 +93,29 @@ 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
         """
-        so = SALOMEDS.SALOMEDS_SObject()
-        return so
+        aStudy = getStudy()
+        aBuilder = aStudy.NewBuilder()
+        if not theFather:
+          theFather = findOrCreateComponent()
+        aResultSO = aBuilder.NewObject(theFather);
+        aResultSO.SetAttrString("AttributeName", theName)
+        
+        
+        if theObject is not None:
+            anIOR = salome.orb.object_to_string(theObject)
+            aResultSO.SetAttrString("AttributeIOR", anIOR)
+            theObject.SetSO(aResultSO)
+          
+            aType = theObject.GetShapeType()
+            aAttr = aBuilder.FindOrCreateAttribute(aResultSO, "AttributePixMap")
+            aPixmap = aAttr._narrow(salome.SALOMEDS.AttributePixMap)
+            aPixmap.SetPixMap(SHAPERSTUDY.ShaperIcons[aType])
+            
+        # add a red-reference that means that this is an active reference to SHAPER result
+        aSub = aBuilder.NewObject(aResultSO)
+        aBuilder.Addreference(aSub, aResultSO)
+
+        return aResultSO
 
     def AddSubShape( theMainShape, theIndices ):
         """
@@ -74,6 +125,7 @@ class SHAPERSTUDY(SHAPERSTUDY_ORB__POA.Gen,
         go = SHAPERSTUDY_Object()._this()
         return go
 
+    # For now it is impossible to remove anything from the SHAPER-STUDY
     def RemoveObject( self, theObject ):
         """
         Removes the object from the component
@@ -124,16 +176,37 @@ class SHAPERSTUDY(SHAPERSTUDY_ORB__POA.Gen,
         Parameters:
             theStudyEntry is an entry of the Object in the study
         """
-        return ""
-
+        return "test"
 
     def Save( self, component, URL, isMultiFile ):
         """
-        Saves data.
-        Nothing to do here because in our case all data
-        are stored in the SALOMEDS attributes.
-        """
-        return ""
+        Saves data: all objects into one file
+        """
+        aResult = "" # string-pairs of internal entries and shape streams
+        aStudy = getStudy()
+        aSOIter = aStudy.NewChildIterator(findOrCreateComponent())
+        while aSOIter.More():
+          aSOVal = aSOIter.Value()
+          aSOList = [aSOVal]
+          # collect also the history shape objects
+          aRes, aHistSO = aSOVal.FindSubObject(2)
+          if aRes:
+            aSOIter2 = aStudy.NewChildIterator(aHistSO)
+            while aSOIter2.More():
+              aSOList.append(aSOIter2.Value())
+              aSOIter2.Next()
+          # for each sobject export shapes stream if exists
+          for aSO in aSOList:
+            anIOR = aSO.GetIOR()
+            anObj = salome.orb.string_to_object(anIOR)
+            if isinstance(anObj, SHAPERSTUDY_ORB._objref_SHAPER_Object):
+              if len(aResult):
+                aResult = aResult + '|'
+              aResult = aResult + anObj.GetEntry() + "|" + anObj.GetShapeStream().decode()
+              aResult = aResult + "|" + anObj.GetOldShapeStream().decode()
+
+          aSOIter.Next()
+        return aResult.encode()
 
     def Load( self, component, stream, URL, isMultiFile ):
         """
@@ -141,21 +214,48 @@ class SHAPERSTUDY(SHAPERSTUDY_ORB__POA.Gen,
         """
         global __entry2IOR__
         __entry2IOR__.clear()
-        #
+        
+        aList=stream.decode().split('|')
+        aSubNum = 1
+        anId = ""
+        aNewShapeStream = ""
+        for aSub in aList:
+          if aSubNum == 1:
+            anId = aSub
+            aSubNum = 2
+          elif aSubNum == 2:
+            aNewShapeStream = aSub
+            aSubNum = 3
+          else: # create shapes by BRep in the stream: set old first then new
+            aShapeObj = SHAPERSTUDY_Object.SHAPERSTUDY_Object()
+            if len(aSub):
+              aShapeObj.SetShapeByStream(aSub)
+            aShapeObj.SetShapeByStream(aNewShapeStream)
+            aShapeObj.SetEntry(anId)
+            anIOR = salome.orb.object_to_string(aShapeObj._this())
+            __entry2IOR__[anId] = anIOR
+            aSubNum = 1
+
         return 1
         
     def IORToLocalPersistentID(self, sobject, IOR, isMultiFile, isASCII):
         """
         Gets persistent ID for the CORBA object.
-        It's enough to use study entry.
+        The internal entry of the Object is returned.
         """
-        return sobject.GetID()
+        anObj = salome.orb.string_to_object(IOR)
+        if anObj and isinstance(anObj, SHAPERSTUDY_ORB._objref_SHAPER_Object):
+          return anObj.GetEntry()
+        return ""
 
     def LocalPersistentIDToIOR(self, sobject, persistentID, isMultiFile, isASCII):
         "Converts persistent ID of the object to its IOR."
         global __entry2IOR__
         if persistentID in __entry2IOR__:
-            return __entry2IOR__[persistentID]
+          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()))
+          return aRes
         return ""
 
     def DumpPython( self, isPublished, isMultiFile ):
@@ -266,26 +366,26 @@ class SHAPERSTUDY(SHAPERSTUDY_ORB__POA.Gen,
         """
         return GetIGroupOperations().UnionList( theGroup, theSubShapes )
 
-    def addToStudy( self, aShape, aName ):
-        """
-        Publish in study aShape with name aName
-        """
-        try:
-            so = self.AddInStudy(aShape, aName, None )
-            if so and aName: so.SetAttrString("AttributeName", aName)
-        except:
-            print("addToStudyInFather() failed")
-            return ""
-        return so.GetStudyEntry()
-
-    def addToStudyInFather(self, aFather, aShape, aName):
-        """
-        Publish in study aShape with name aName as sub-object of previously published aFather
-        """
-        try:
-            so = self.AddInStudy(aShape, aName, aFather )
-            if so and aName: so.SetAttrString("AttributeName", aName)
-        except:
-            print("addToStudyInFather() failed")
-            return ""
-        return so.GetStudyEntry()
+    def BreakLink(self, theEntry):
+        """
+        Breaks links to not-dead shape, make the shape as dead
+        """
+        aStudy = getStudy()
+        aSO = aStudy.FindObjectID(theEntry)
+        if not aSO:
+          return
+        aRes, aSSO = aSO.ReferencedObject()
+        if not aRes:
+          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
+        anObj = salome.orb.string_to_object(anIOR)
+        if not anObj or not isinstance(anObj, SHAPERSTUDY_ORB._objref_SHAPER_Object):
+          return
+        if anObj.IsDead():
+          return # do nothing for reference to already dead shape
+        aDeadShape = anObj.MakeDead()
+        aBuilder = aStudy.NewBuilder()
+        aBuilder.RemoveReference(aSO) # reset reference to the dead shape
+        aBuilder.Addreference(aSO, aDeadShape.GetSO())