1 # Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE
3 # Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 # This library is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU Lesser General Public
8 # License as published by the Free Software Foundation; either
9 # version 2.1 of the License, or (at your option) any later version.
11 # This library is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 # Lesser General Public License for more details.
16 # You should have received a copy of the GNU Lesser General Public
17 # License along with this library; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 # Author : Adrien Bruneton (CEA)
25 import PARAVIS_ORB__POA
26 import SALOME_ComponentPy
27 import SALOME_DriverPy
30 import subprocess as subp
31 from time import sleep
33 from SALOME_utilities import MESSAGE
36 """ The core implementation (non CORBA, or Study related).
37 See the IDL for the documentation.
39 MAX_PVSERVER_PORT_TRIES = 10
42 self.pvserverPort = -1
43 self.pvserverPop = None # Popen object from subprocess module
44 self.liveConnection = None
48 Private. Keeps a connection to the PVServer to prevent
49 it from stopping because all connections from GUI or scripts have been closed.
51 def __startKeepAlive(self, host, port):
52 print "[PARAVIS] 0 __startKeepAlive", host, port
53 from paraview import simple as pvs
54 self.liveConnection = pvs.Connect(host, port)
55 print "[PARAVIS] 1 __startKeepAlive", self.liveConnection
57 def FindOrStartPVServer( self, port ):
58 print "[PARAVIS] FindOrStartPVServer"
59 MESSAGE("[PARAVIS] FindOrStartPVServer")
62 if self.pvserverPop is None:
65 # Poll active server to check if still alive
66 self.pvserverPop.poll()
67 if not self.pvserverPop.returncode is None: # server terminated
71 return "cs://%s:%d" % (host, self.pvserverPort)
73 # (else) Server not alive, start it:
74 pvRootDir = os.getenv("PARAVIEW_ROOT_DIR")
75 pvServerPath = os.path.join(pvRootDir, 'bin', 'pvserver')
81 while not success and (currPort - port) < self.MAX_PVSERVER_PORT_TRIES:
82 self.pvserverPop = subp.Popen([pvServerPath, "--multi-clients", "--server-port=%d" % currPort])
84 # Is PID still alive? If yes, consider that the launch was successful
85 self.pvserverPop.poll()
86 if self.pvserverPop.returncode is None:
88 self.pvserverPort = currPort
89 MESSAGE("[PARAVIS] pvserver successfully launched on port %d" % currPort)
91 if (currPort - port) == self.MAX_PVSERVER_PORT_TRIES:
92 self.pvserverPop = None
93 raise SalomeException("Unable to start PVServer after %d tries!" % self.MAX_PVSERVER_PORT_TRIES)
94 # self.__startKeepAlive(host, self.pvserverPort)
95 return "cs://%s:%d" % (host, self.pvserverPort)
97 def StopPVServer( self ):
98 MESSAGE("[PARAVIS] Trying to stop PVServer (sending KILL) ...")
99 if not self.pvserverPop is None:
100 self.pvserverPop.poll()
101 if not self.pvserverPop.returncode is None:
102 # Send KILL if still running:
103 self.pvserverPop.kill()
104 self.liveConnection = None
106 def PutPythonTraceStringToEngine( self, t ):
109 def GetPythonTraceString (self):
110 return self.lastTrace
112 class PARAVIS(PARAVIS_ORB__POA.PARAVIS_Gen,
113 SALOME_ComponentPy.SALOME_ComponentPy_i,
114 SALOME_DriverPy.SALOME_DriverPy_i,
118 Construct an instance of PARAVIS module engine.
119 The class PARAVIS implements CORBA interface PARAVIS_Gen (see PARAVIS_Gen.idl).
120 It is inherited from the classes SALOME_ComponentPy_i (implementation of
121 Engines::EngineComponent CORBA interface - SALOME component) and SALOME_DriverPy_i
122 (implementation of SALOMEDS::Driver CORBA interface - SALOME module's engine).
124 def __init__ ( self, orb, poa, contID, containerName, instanceName,
126 SALOME_ComponentPy.SALOME_ComponentPy_i.__init__(self, orb, poa,
127 contID, containerName, instanceName, interfaceName, 0)
128 SALOME_DriverPy.SALOME_DriverPy_i.__init__(self, interfaceName)
129 PARAVIS_Impl.__init__(self)
131 self._naming_service = SALOME_ComponentPy.SALOME_NamingServicePy_i( self._orb )
134 """ Override base class destroy to make sure we try to kill the pvserver
140 SALOME_ComponentPy.destroy(self)
143 Get version information.
145 def getVersion( self ):
146 import salome_version
147 return salome_version.getVersion("PARAVIS", True)
150 return PARAVIS_utils.getEngineIOR()
155 def createObject( self, study, name ):
156 self._createdNew = True # used for getModifiedData method
157 builder = study.NewBuilder()
158 father = findOrCreateComponent( study )
159 object = builder.NewObject( father )
160 attr = builder.FindOrCreateAttribute( object, "AttributeName" )
161 attr.SetValue( name )
162 attr = builder.FindOrCreateAttribute( object, "AttributeLocalID" )
163 attr.SetValue( objectID() )
167 Dump module data to the Python script.
169 def DumpPython( self, study, isPublished ):
170 print "@@@@ DumpPython"
172 abuffer.append( "def RebuildData( theStudy ):" )
174 father = study.FindComponent( moduleName() )
176 iter = study.NewChildIterator( father )
178 name = iter.Value().GetName()
179 if name: names.append( name )
184 abuffer += [ " from batchmode_salome import lcc" ]
185 abuffer += [ " import PARAVIS_ORB" ]
187 abuffer += [ " pyhello = lcc.FindOrLoadComponent( 'FactoryServerPy', '%s' )" % moduleName() ]
189 abuffer += [ " pyhello.createObject( theStudy, '%s' )" % name for name in names ]
192 abuffer.append( " pass" )
193 abuffer.append( "\0" )
194 return ("\n".join( abuffer ), 1)
197 Import file to restore module data
199 def importData(self, studyId, dataContainer, options):
200 print "@@@@ ImportData"
202 obj = self._naming_service.Resolve("myStudyManager")
203 myStudyManager = obj._narrow(SALOMEDS.StudyManager)
204 study = myStudyManager.GetStudyByID(studyId)
205 # create all objects from the imported stream
206 stream = dataContainer.get()
207 for objname in stream.split("\n"):
208 if len(objname) != 0:
209 self.createObject(study, objname)
210 self._createdNew = False # to store the modification of the study information later
211 return ["objects"] # identifier what is in this file
213 def getModifiedData(self, studyId):
214 print "@@@@ GetModifiedData"
217 obj = self._naming_service.Resolve("myStudyManager")
218 myStudyManager = obj._narrow(SALOMEDS.StudyManager)
219 study = myStudyManager.GetStudyByID(studyId)
220 # iterate all objects to get their names and store this information in stream
222 father = study.FindComponent( moduleName() )
224 iter = study.NewChildIterator( father )
226 name = iter.Value().GetName()
227 stream += name + "\n"
229 # store stream to the temporary file to send it in DataContainer
230 dataContainer = SALOME_DataContainerPy_i(stream, "", "objects", False, True)
231 aVar = dataContainer._this()