From fff7db94f5362314f29b8b570566187e957620ee Mon Sep 17 00:00:00 2001 From: abn Date: Fri, 29 Aug 2014 16:36:15 +0200 Subject: [PATCH] Re-wrote PARAVIS CORBA engine Engine now deals with the startup of the pvserver. Python trace working. To be fixed: Save study/Dump study broken. To be fixed: ugly SIGSEV at SALOME's exit. --- CMakeLists.txt | 2 +- idl/CMakeLists.txt | 29 +- idl/PARAVIS_Gen.idl | 2 - idl/no_wrap/PARAVIS_Gen.idl | 73 + src/ENGINE/CMakeLists.txt | 43 +- src/ENGINE/no_wrap/PARAVIS.py | 233 ++ src/ENGINE/no_wrap/PARAVIS_utils.py | 199 ++ src/PVGUI/CMakeLists.txt | 9 +- src/PVGUI/PARAVIS_Gen_i.hh | 2 +- src/PVGUI/PVGUI_Module.cxx | 397 ++- src/PVGUI/PVGUI_Module.h | 19 +- src/PVGUI/PVGUI_Module_widgets.cxx | 38 +- src/PVGUI/PVGUI_Tools.cxx | 2 + src/PVGUI/PVGUI_Tools.h | 9 +- .../PVGUI_MatplotlibMathTextUtilities.cxx | 0 .../PVGUI_MatplotlibMathTextUtilities.h | 0 src/PVGUI/{ => deprecated}/PV_Tools.cxx | 0 src/PVGUI/{ => deprecated}/PV_Tools.h | 0 src/PV_SWIG/CMakeLists.txt | 16 +- src/PV_SWIG/VTKWrapping/paravis.py | 97 - src/PV_SWIG/VTKWrapping/paravisSM.py | 3014 ----------------- src/PV_SWIG/VTKWrapping/pvsimple.py | 1173 ------- src/PV_SWIG/no_wrap/paravis.py | 54 + src/PV_SWIG/no_wrap/paravisSM.py | 30 + .../{VTKWrapping => no_wrap}/presentations.py | 484 ++- src/PV_SWIG/no_wrap/pvsimple.py | 50 + src/PV_SWIG/paravis.py | 71 +- src/PV_SWIG/paravisSM.py | 3000 +++++++++++++++- src/PV_SWIG/presentations.py | 484 +-- src/PV_SWIG/pvsimple.py | 1174 ++++++- .../{VTKWrapping => }/servermanager.diff | 0 src/PV_SWIG/{VTKWrapping => }/simple.diff | 0 32 files changed, 5629 insertions(+), 5075 deletions(-) create mode 100644 idl/no_wrap/PARAVIS_Gen.idl create mode 100644 src/ENGINE/no_wrap/PARAVIS.py create mode 100644 src/ENGINE/no_wrap/PARAVIS_utils.py rename src/PVGUI/{ => deprecated}/PVGUI_MatplotlibMathTextUtilities.cxx (100%) rename src/PVGUI/{ => deprecated}/PVGUI_MatplotlibMathTextUtilities.h (100%) rename src/PVGUI/{ => deprecated}/PV_Tools.cxx (100%) rename src/PVGUI/{ => deprecated}/PV_Tools.h (100%) delete mode 100644 src/PV_SWIG/VTKWrapping/paravis.py delete mode 100644 src/PV_SWIG/VTKWrapping/paravisSM.py delete mode 100644 src/PV_SWIG/VTKWrapping/pvsimple.py create mode 100644 src/PV_SWIG/no_wrap/paravis.py create mode 100644 src/PV_SWIG/no_wrap/paravisSM.py rename src/PV_SWIG/{VTKWrapping => no_wrap}/presentations.py (89%) create mode 100644 src/PV_SWIG/no_wrap/pvsimple.py rename src/PV_SWIG/{VTKWrapping => }/servermanager.diff (100%) rename src/PV_SWIG/{VTKWrapping => }/simple.diff (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 29d7f3f4..172b7185 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -251,7 +251,7 @@ INCLUDE(CMakePackageConfigHelpers) # List of targets in this project we want to make visible to the rest of the world. # They all have to be INSTALL'd with the option "EXPORT ${PROJECT_NAME}TargetGroup" IF(NOT SALOME_LIGHT_ONLY) - SET(_${PROJECT_NAME}_exposed_targets SalomeIDLPARAVIS PARAVISEngine PARAVIS) + SET(_${PROJECT_NAME}_exposed_targets SalomeIDLPARAVIS PARAVIS) # Add all targets to the build-tree export set EXPORT(TARGETS ${_${PROJECT_NAME}_exposed_targets} diff --git a/idl/CMakeLists.txt b/idl/CMakeLists.txt index 06019928..7300916e 100644 --- a/idl/CMakeLists.txt +++ b/idl/CMakeLists.txt @@ -33,18 +33,27 @@ IF(NOT SALOME_PARAVIS_MINIMAL_CORBA) # (again, this shouldn't last for long ...) SET(OMNIORB_IDLCXXFLAGS "${OMNIORB_IDLCXXFLAGS};-DPARAVIS_WITH_FULL_CORBA") SET(OMNIORB_IDLPYFLAGS "${OMNIORB_IDLPYFLAGS};-DPARAVIS_WITH_FULL_CORBA") -ENDIF() - ADD_DEFINITIONS(${OMNIORB_DEFINITIONS}) -SET(SalomeIDLPARAVIS_IDLSOURCES - PARAVIS_Gen.idl - PARAVIS_Gen_Types.idl - ${WRAP_IDL} + + SET(SalomeIDLPARAVIS_IDLSOURCES + PARAVIS_Gen.idl + PARAVIS_Gen_Types.idl + ${WRAP_IDL} + ) + SET(_idl_include_dirs + ${CMAKE_CURRENT_SOURCE_DIR} + ${KERNEL_ROOT_DIR}/idl/salome + ) +ELSE() + SET(SalomeIDLPARAVIS_IDLSOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/no_wrap/PARAVIS_Gen.idl ) + SET(_idl_include_dirs + ${CMAKE_CURRENT_SOURCE_DIR}/no_wrap + ${KERNEL_ROOT_DIR}/idl/salome + ) +ENDIF() -SET(_idl_include_dirs - ${CMAKE_CURRENT_SOURCE_DIR} - ${KERNEL_ROOT_DIR}/idl/salome -) +ADD_DEFINITIONS(${OMNIORB_DEFINITIONS}) SET(_idl_link_flags ${KERNEL_SalomeIDLKernel} diff --git a/idl/PARAVIS_Gen.idl b/idl/PARAVIS_Gen.idl index 9a5e1898..8b7e19c0 100644 --- a/idl/PARAVIS_Gen.idl +++ b/idl/PARAVIS_Gen.idl @@ -82,7 +82,6 @@ module PARAVIS { */ void SaveTrace(in string theFileName); -#ifdef PARAVIS_WITH_FULL_CORBA /*! * \brief Returns list of names of extracted Paraview and VTK classes */ @@ -92,7 +91,6 @@ module PARAVIS { * \brief Returns container class for the requested Paraview class */ PARAVIS_Base CreateClass(in string theClassName); -#endif /*! * Returns parameters of current (usually built-in) connection which is active in GUI (Paraview client). diff --git a/idl/no_wrap/PARAVIS_Gen.idl b/idl/no_wrap/PARAVIS_Gen.idl new file mode 100644 index 00000000..11f68e87 --- /dev/null +++ b/idl/no_wrap/PARAVIS_Gen.idl @@ -0,0 +1,73 @@ +// Copyright (C) 2010-2014 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 +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +// Author : Adrien Bruneton (CEA) + + +#ifndef __PARAVIS_GEN__ +#define __PARAVIS_GEN__ + +#include "SALOME_Exception.idl" +#include "SALOME_Component.idl" +#include "SALOMEDS.idl" +#include "SALOME_Exception.idl" + +/*! + The main package of interfaces of the module %PARAVIS. +*/ +module PARAVIS_ORB { + + /*! + * \brief The main interface class for PARAVIS server. + * Instantiation of this class has to be done before access to any other PARAVIS interfaces + */ + interface PARAVIS_Gen : Engines::EngineComponent, SALOMEDS::Driver + { + + /*! + * \brief Returns IOR of the current object. + */ + string GetIOR(); + + /*! If a pvserver is already started, returns its current URL, regardless of the provided + * parameters. + * If not, start a pvserver on the machine hosting the PARAVIS engine and on the given port. + * If port <= 0, a free port is automatically detected, starting from the usual 11111 pvserver port. + */ + string FindOrStartPVServer(in long port); + + /*! Tries to stop the PVserver currently running (send KILL). + * @return false if no server was running, true otherwise. + */ + boolean StopPVServer(); + + /*! Gets the last trace string pushed by the GUI onto the engine. + */ + string GetPythonTraceString(); + + /*! HACK!! For now ParaView's trace mechanism is implemented in such away that asking the trace + * outside the GUI provides an incomplete script. Hence the GUI regularly pushes to the engine + * the latest status of the trace which is then returned by GetPythonTraceString(). + */ + void PutPythonTraceStringToEngine(in string trace); + + }; + +}; + +#endif \ No newline at end of file diff --git a/src/ENGINE/CMakeLists.txt b/src/ENGINE/CMakeLists.txt index 6f0bb0f4..3bca3aac 100644 --- a/src/ENGINE/CMakeLists.txt +++ b/src/ENGINE/CMakeLists.txt @@ -17,20 +17,31 @@ # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # -INCLUDE_DIRECTORIES( - ${OMNIORB_INCLUDE_DIR} - ${KERNEL_INCLUDE_DIRS} - ${PROJECT_BINARY_DIR}/idl) +IF(NOT SALOME_PARAVIS_MINIMAL_CORBA) + INCLUDE_DIRECTORIES( + ${OMNIORB_INCLUDE_DIR} + ${KERNEL_INCLUDE_DIRS} + ${PROJECT_BINARY_DIR}/idl) + + ADD_DEFINITIONS(${KERNEL_DEFINITIONS}) + ADD_DEFINITIONS(${OMNIORB_DEFINITIONS}) + + ADD_LIBRARY(PARAVISEngine PARAVIS_Engine_i.cc) + + TARGET_LINK_LIBRARIES(PARAVISEngine + ${KERNEL_SalomeIDLKernel} ${KERNEL_SalomeNS} ${KERNEL_SalomeContainer} ${KERNEL_SALOMELocalTrace} + ${OMNIORB_LIBRARIES} + SalomeIDLPARAVIS) + INSTALL(TARGETS PARAVISEngine) # doesn't need to be exported + + INSTALL(FILES PARAVIS_Engine_i.hh DESTINATION ${SALOME_INSTALL_HEADERS}) +ELSE() + SET(_bin_SCRIPTS + no_wrap/PARAVIS.py + no_wrap/PARAVIS_utils.py + ) -ADD_DEFINITIONS(${KERNEL_DEFINITIONS}) -ADD_DEFINITIONS(${OMNIORB_DEFINITIONS}) - -ADD_LIBRARY(PARAVISEngine PARAVIS_Engine_i.cc) - -TARGET_LINK_LIBRARIES(PARAVISEngine - ${KERNEL_SalomeIDLKernel} ${KERNEL_SalomeNS} ${KERNEL_SalomeContainer} ${KERNEL_SALOMELocalTrace} - ${OMNIORB_LIBRARIES} - SalomeIDLPARAVIS) -INSTALL(TARGETS PARAVISEngine EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${SALOME_INSTALL_LIBS}) - -INSTALL(FILES PARAVIS_Engine_i.hh DESTINATION ${SALOME_INSTALL_HEADERS}) + # --- rules --- + SALOME_INSTALL_SCRIPTS("${_bin_SCRIPTS}" ${SALOME_INSTALL_SCRIPT_PYTHON}) +ENDIF() + \ No newline at end of file diff --git a/src/ENGINE/no_wrap/PARAVIS.py b/src/ENGINE/no_wrap/PARAVIS.py new file mode 100644 index 00000000..c7f8a3d1 --- /dev/null +++ b/src/ENGINE/no_wrap/PARAVIS.py @@ -0,0 +1,233 @@ +# Copyright (C) 2007-2014 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 +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# +# Author : Adrien Bruneton (CEA) +# + +import PARAVIS_ORB__POA +import SALOME_ComponentPy +import SALOME_DriverPy +import SALOMEDS +import PARAVIS_utils +import subprocess as subp +from time import sleep +import os +from SALOME_utilities import MESSAGE + +class PARAVIS_Impl: + """ The core implementation (non CORBA, or Study related). + See the IDL for the documentation. + """ + MAX_PVSERVER_PORT_TRIES = 10 + + def __init__(self): + self.pvserverPort = -1 + self.pvserverPop = None # Popen object from subprocess module + self.liveConnection = None + self.lastTrace = "" + + """ + Private. Keeps a connection to the PVServer to prevent + it from stopping because all connections from GUI or scripts have been closed. + """ + def __startKeepAlive(self, host, port): + print "[PARAVIS] 0 __startKeepAlive", host, port + from paraview import simple as pvs + self.liveConnection = pvs.Connect(host, port) + print "[PARAVIS] 1 __startKeepAlive", self.liveConnection + + def FindOrStartPVServer( self, port ): + print "[PARAVIS] FindOrStartPVServer" + MESSAGE("[PARAVIS] FindOrStartPVServer") + host = "localhost" + alive = True + if self.pvserverPop is None: + alive = False + else: + # Poll active server to check if still alive + self.pvserverPop.poll() + if not self.pvserverPop.returncode is None: # server terminated + alive = False + + if alive: + return "cs://%s:%d" % (host, self.pvserverPort) + + # (else) Server not alive, start it: + pvRootDir = os.getenv("PARAVIEW_ROOT_DIR") + pvServerPath = os.path.join(pvRootDir, 'bin', 'pvserver') + opt = [] + if port <= 0: + port = 11111 + currPort = port + success = False + while not success and (currPort - port) < self.MAX_PVSERVER_PORT_TRIES: + self.pvserverPop = subp.Popen([pvServerPath, "--multi-clients", "--server-port=%d" % currPort]) + sleep(2) + # Is PID still alive? If yes, consider that the launch was successful + self.pvserverPop.poll() + if self.pvserverPop.returncode is None: + success = True + self.pvserverPort = currPort + MESSAGE("[PARAVIS] pvserver successfully launched on port %d" % currPort) + currPort += 1 + if (currPort - port) == self.MAX_PVSERVER_PORT_TRIES: + self.pvserverPop = None + raise SalomeException("Unable to start PVServer after %d tries!" % self.MAX_PVSERVER_PORT_TRIES) +# self.__startKeepAlive(host, self.pvserverPort) + return "cs://%s:%d" % (host, self.pvserverPort) + + def StopPVServer( self ): + MESSAGE("[PARAVIS] Trying to stop PVServer (sending KILL) ...") + if not self.pvserverPop is None: + self.pvserverPop.poll() + if not self.pvserverPop.returncode is None: + # Send KILL if still running: + self.pvserverPop.kill() + self.liveConnection = None + + def PutPythonTraceStringToEngine( self, t ): + self.lastTrace = t + + def GetPythonTraceString (self): + return self.lastTrace + +class PARAVIS(PARAVIS_ORB__POA.PARAVIS_Gen, + SALOME_ComponentPy.SALOME_ComponentPy_i, + SALOME_DriverPy.SALOME_DriverPy_i, + PARAVIS_Impl): + + """ + Construct an instance of PARAVIS module engine. + The class PARAVIS implements CORBA interface PARAVIS_Gen (see PARAVIS_Gen.idl). + It is inherited 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). + """ + def __init__ ( self, orb, poa, contID, containerName, instanceName, + interfaceName ): + SALOME_ComponentPy.SALOME_ComponentPy_i.__init__(self, orb, poa, + contID, containerName, instanceName, interfaceName, 0) + SALOME_DriverPy.SALOME_DriverPy_i.__init__(self, interfaceName) + PARAVIS_Impl.__init__(self) + # + self._naming_service = SALOME_ComponentPy.SALOME_NamingServicePy_i( self._orb ) + # + + """ Override base class destroy to make sure we try to kill the pvserver + before leaving. + """ + def destroy(self): + self.StopPVServer() + # Invokes super(): + SALOME_ComponentPy.destroy(self) + + """ + Get version information. + """ + def getVersion( self ): + import salome_version + return salome_version.getVersion("PARAVIS", True) + + def GetIOR(self): + return PARAVIS_utils.getEngineIOR() + + """ + Create object. + """ + def createObject( self, study, name ): + self._createdNew = True # used for getModifiedData method + builder = study.NewBuilder() + father = findOrCreateComponent( study ) + object = builder.NewObject( father ) + attr = builder.FindOrCreateAttribute( object, "AttributeName" ) + attr.SetValue( name ) + attr = builder.FindOrCreateAttribute( object, "AttributeLocalID" ) + attr.SetValue( objectID() ) + pass + + """ + Dump module data to the Python script. + """ + def DumpPython( self, study, isPublished ): + print "@@@@ DumpPython" + abuffer = [] + abuffer.append( "def RebuildData( theStudy ):" ) + names = [] + father = study.FindComponent( moduleName() ) + if father: + iter = study.NewChildIterator( father ) + while iter.More(): + name = iter.Value().GetName() + if name: names.append( name ) + iter.Next() + pass + pass + if names: + abuffer += [ " from batchmode_salome import lcc" ] + abuffer += [ " import PARAVIS_ORB" ] + abuffer += [ " " ] + abuffer += [ " pyhello = lcc.FindOrLoadComponent( 'FactoryServerPy', '%s' )" % moduleName() ] + abuffer += [ " " ] + abuffer += [ " pyhello.createObject( theStudy, '%s' )" % name for name in names ] + pass + abuffer += [ " " ] + abuffer.append( " pass" ) + abuffer.append( "\0" ) + return ("\n".join( abuffer ), 1) + + """ + Import file to restore module data + """ + def importData(self, studyId, dataContainer, options): + print "@@@@ ImportData" + # get study by Id + obj = self._naming_service.Resolve("myStudyManager") + myStudyManager = obj._narrow(SALOMEDS.StudyManager) + study = myStudyManager.GetStudyByID(studyId) + # create all objects from the imported stream + stream = dataContainer.get() + for objname in stream.split("\n"): + if len(objname) != 0: + self.createObject(study, objname) + self._createdNew = False # to store the modification of the study information later + return ["objects"] # identifier what is in this file + + def getModifiedData(self, studyId): + print "@@@@ GetModifiedData" + if self._createdNew: + # get study by Id + obj = self._naming_service.Resolve("myStudyManager") + myStudyManager = obj._narrow(SALOMEDS.StudyManager) + study = myStudyManager.GetStudyByID(studyId) + # iterate all objects to get their names and store this information in stream + stream="" + father = study.FindComponent( moduleName() ) + if father: + iter = study.NewChildIterator( father ) + while iter.More(): + name = iter.Value().GetName() + stream += name + "\n" + iter.Next() + # store stream to the temporary file to send it in DataContainer + dataContainer = SALOME_DataContainerPy_i(stream, "", "objects", False, True) + aVar = dataContainer._this() + return [aVar] + return [] diff --git a/src/ENGINE/no_wrap/PARAVIS_utils.py b/src/ENGINE/no_wrap/PARAVIS_utils.py new file mode 100644 index 00000000..5a6d122e --- /dev/null +++ b/src/ENGINE/no_wrap/PARAVIS_utils.py @@ -0,0 +1,199 @@ +# Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +# --- +# File : PARAVIS_utils.py +# Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) +# --- +# +__all__ = [ + "moduleID", + "objectID", + "unknownID", + "moduleName", + "modulePixmap", + "verbose", + "getORB", + "getNS", + "getLCC", + "getStudyManager", + "getEngine", + "getEngineIOR", + "findOrCreateComponent", + "getObjectID", + ] + +from omniORB import CORBA +from SALOME_NamingServicePy import SALOME_NamingServicePy_i +from LifeCycleCORBA import LifeCycleCORBA +import SALOMEDS +import SALOMEDS_Attributes_idl +import PARAVIS_ORB +import os + +### +# Get PARAVIS module's ID +### +def moduleID(): + MODULE_ID = 1000 + return MODULE_ID + +### +# Get PARAVIS object's ID +### +def objectID(): + OBJECT_ID = 1010 + return OBJECT_ID + +### +# Get unknown ID +### +def unknownID(): + FOREIGN_ID = -1 + return FOREIGN_ID + +### +# Get PARAVIS module's name +### +def moduleName(): + return "PARAVIS" + +### +# Get module's pixmap name +### +def modulePixmap(): + return "PARAVIS_small.png" + +### +# Get verbose level +### +__verbose__ = None +def verbose(): + global __verbose__ + if __verbose__ is None: + try: + __verbose__ = int( os.getenv( 'SALOME_VERBOSE', 0 ) ) + except: + __verbose__ = 0 + pass + pass + return __verbose__ + +### +# Get ORB reference +### +__orb__ = None +def getORB(): + global __orb__ + if __orb__ is None: + __orb__ = CORBA.ORB_init( [''], CORBA.ORB_ID ) + pass + return __orb__ + +### +# Get naming service instance +### +__naming_service__ = None +def getNS(): + global __naming_service__ + if __naming_service__ is None: + __naming_service__ = SALOME_NamingServicePy_i( getORB() ) + pass + return __naming_service__ + +## +# Get life cycle CORBA instance +## +__lcc__ = None +def getLCC(): + global __lcc__ + if __lcc__ is None: + __lcc__ = LifeCycleCORBA( getORB() ) + pass + return __lcc__ + +## +# Get study manager +### +__study_manager__ = None +def getStudyManager(): + global __study_manager__ + if __study_manager__ is None: + obj = getNS().Resolve( '/myStudyManager' ) + __study_manager__ = obj._narrow( SALOMEDS.StudyManager ) + pass + return __study_manager__ + +### +# Get PARAVIS engine +### +__engine__ = None +def getEngine(): + global __engine__ + if __engine__ is None: + __engine__ = getLCC().FindOrLoadComponent( "FactoryServer", moduleName() ) + pass + return __engine__ + +### +# Get PARAVIS engine IOR +### +def getEngineIOR(): + IOR = "" + if getORB() and getEngine(): + IOR = getORB().object_to_string( getEngine() ) + pass + return IOR + +### +# Find or create PARAVIS component object in a study +### +def findOrCreateComponent( study ): + father = study.FindComponent( moduleName() ) + if father is None: + builder = study.NewBuilder() + father = builder.NewComponent( moduleName() ) + attr = builder.FindOrCreateAttribute( father, "AttributeName" ) + attr.SetValue( moduleName() ) + attr = builder.FindOrCreateAttribute( father, "AttributePixMap" ) + attr.SetPixMap( modulePixmap() ) + attr = builder.FindOrCreateAttribute( father, "AttributeLocalID" ) + attr.SetValue( moduleID() ) + try: + builder.DefineComponentInstance( father, getEngine() ) + pass + except: + pass + pass + return father + +### +# Get object's ID +### +def getObjectID( study, entry ): + ID = unknownID() + if study and entry: + sobj = study.FindObjectID( entry ) + if sobj is not None: + test, anAttr = sobj.FindAttribute( "AttributeLocalID" ) + if test: ID = anAttr._narrow( SALOMEDS.AttributeLocalID ).Value() + pass + pass + return ID + diff --git a/src/PVGUI/CMakeLists.txt b/src/PVGUI/CMakeLists.txt index fc2bcaba..13ee65b6 100644 --- a/src/PVGUI/CMakeLists.txt +++ b/src/PVGUI/CMakeLists.txt @@ -75,9 +75,12 @@ SET(_other_HEADERS PV_I.h PARAVIS_Gen_i.hh PV_Events.h - PV_Tools.h ) +IF(NOT SALOME_PARAVIS_MINIMAL_CORBA) + LIST(APPEND _other_HEADERS PV_Tools.h) +ENDIF() + # header files / to install SET(PVGUI_HEADERS ${_moc_HEADERS} ${_other_HEADERS}) @@ -138,8 +141,7 @@ SET(_other_SOURCES PVGUI_Tools.cxx PVGUI_ParaViewSettingsPane.cxx #PVGUI_MatplotlibMathTextUtilities.cxx - PARAVIS_Gen_i.cc - PV_Tools.cxx + #PV_Tools.cxx ) IF(NOT SALOME_PARAVIS_MINIMAL_CORBA) @@ -155,6 +157,7 @@ IF(NOT SALOME_PARAVIS_MINIMAL_CORBA) SET(WRAP_IDL_I_CC "${WRAP_IDL_I_CC}" PARENT_SCOPE) SET(_VTK_wrap_SOURCES + PARAVIS_Gen_i.cc PARAVIS_CreateClass.cxx ${WRAP_IDL_I_CC} ) diff --git a/src/PVGUI/PARAVIS_Gen_i.hh b/src/PVGUI/PARAVIS_Gen_i.hh index a507feb1..d97c5489 100644 --- a/src/PVGUI/PARAVIS_Gen_i.hh +++ b/src/PVGUI/PARAVIS_Gen_i.hh @@ -46,7 +46,7 @@ class SalomeApp_Application; class PVGUI_Module; class vtkObjectBase; -#define PVSTATEID 15555 +//#define PVSTATEID 15555 // now in PVGUI_Tools.h namespace PARAVIS { diff --git a/src/PVGUI/PVGUI_Module.cxx b/src/PVGUI/PVGUI_Module.cxx index 8fb20ea2..f7f179e7 100644 --- a/src/PVGUI/PVGUI_Module.cxx +++ b/src/PVGUI/PVGUI_Module.cxx @@ -28,16 +28,11 @@ #include // Python first #include "PVGUI_Module.h" -#include "SALOMEconfig.h" -#ifdef WITH_VISU -#include CORBA_CLIENT_HEADER(VISU_Gen) +#ifdef PARAVIS_WITH_FULL_CORBA +# include "PARAVIS_Gen_i.hh" #endif -#include CORBA_SERVER_HEADER(SALOMEDS) - -#include "PARAVIS_Gen_i.hh" - -#include "PV_Tools.h" +//#include "PV_Tools.h" #include "PVGUI_ViewModel.h" #include "PVGUI_ViewManager.h" @@ -69,6 +64,8 @@ #include #include +#include + #include #include @@ -130,6 +127,7 @@ #include #include #include +#include #include @@ -169,6 +167,8 @@ pqPVApplicationCore* PVGUI_Module::MyCoreApp = 0; PVGUI_Module* ParavisModule = 0; +PARAVIS_ORB::PARAVIS_Gen_var PVGUI_Module::myEngine; + /*! \mainpage @@ -269,7 +269,9 @@ void vtkEDFHelperInit() { aStudyBuilder->FindOrCreateAttribute(aSComponent, "AttributeName"); _PTR(AttributeName) aName (anAttr); - CORBA::ORB_var anORB = PARAVIS::PARAVIS_Gen_i::GetORB(); + //CORBA::ORB_var anORB = PARAVIS::PARAVIS_Gen_i::GetORB(); + int dnu; + CORBA::ORB_var anORB = CORBA::ORB_init(dnu, 0); // suppose ORB was already initialized SALOME_NamingService *NamingService = new SALOME_NamingService( anORB ); CORBA::Object_var objVarN = NamingService->Resolve("/Kernel/ModulCatalog"); SALOME_ModuleCatalog::ModuleCatalog_var Catalogue = @@ -286,10 +288,7 @@ void vtkEDFHelperInit() { // Create Attribute parameters for future using anAttr = aStudyBuilder->FindOrCreateAttribute(aSComponent, "AttributeParameter"); - - PARAVIS::PARAVIS_Gen_var aPARAVIS = PARAVIS::PARAVIS_Gen_i::GetParavisGenImpl()->_this(); - - aStudyBuilder->DefineComponentInstance(aSComponent, aPARAVIS->GetIOR()); + aStudyBuilder->DefineComponentInstance(aSComponent, PVGUI_Module::GetEngine()->GetIOR()); if (aLocked) theStudyDocument->GetProperties()->SetLocked(true); aStudyBuilder->CommitCommand(); } @@ -322,7 +321,8 @@ PVGUI_Module::PVGUI_Module() myRecentMenuId(-1), myOldMsgHandler(0), myTraceWindow(0), - myStateCounter(0) + myStateCounter(0), + myPushTraceTimer(0) { #ifdef HAS_PV_DOC Q_INIT_RESOURCE( PVGUI ); @@ -349,6 +349,23 @@ PVGUI_Module::PVGUI_Module() */ PVGUI_Module::~PVGUI_Module() { + if (myPushTraceTimer) + delete myPushTraceTimer; + //MyCoreApp->prepareForQuit(); + // even if it is static: +// if (MyCoreApp) +// delete MyCoreApp; +} + +PARAVIS_ORB::PARAVIS_Gen_var PVGUI_Module::GetEngine() +{ + // initialize PARAVIS module engine (load, if necessary) + if ( CORBA::is_nil( myEngine ) ) { + Engines::EngineComponent_var comp = + SalomeApp_Application::lcc()->FindOrLoad_Component( "FactoryServer", "PARAVIS" ); + myEngine = PARAVIS_ORB::PARAVIS_Gen::_narrow( comp ); + } + return myEngine; } /*! @@ -380,117 +397,113 @@ void PVGUI_Module::initialize( CAM_Application* app ) pvInit(); // Create GUI elements (menus, toolbars, dock widgets) - //if ( !Implementation ){ - SalomeApp_Application* anApp = getApp(); - SUIT_Desktop* aDesktop = anApp->desktop(); - - // connect(aDesktop, SIGNAL() - - // Remember current state of desktop toolbars - QList foreignToolbars = aDesktop->findChildren(); - - // Simulate ParaView client main window - //Implementation = new pqImplementation( aDesktop ); - - setupDockWidgets(); - - pvCreateActions(); - pvCreateToolBars(); - pvCreateMenus(); - - QList activeDocks = aDesktop->findChildren(); - QList activeMenus = aDesktop->findChildren(); - - // new pqParaViewBehaviors(anApp->desktop(), this); - // Has to be replaced in order to exclude using of pqQtMessageHandlerBehaviour - // Start pqParaViewBehaviors - // Register ParaView interfaces. - //pqPluginManager* pgm = pqApplicationCore::instance()->getPluginManager(); - pqInterfaceTracker* pgm = pqApplicationCore::instance()->interfaceTracker(); - - // * adds support for standard paraview views. - pgm->addInterface(new pqStandardViewModules(pgm)); - //pgm->addInterface(new pqStandardSummaryPanelImplementation(pgm)); - pgm->addInterface(new pqStandardPropertyWidgetInterface(pgm)); - - // Load plugins distributed with application. - pqApplicationCore::instance()->loadDistributedPlugins(); - - // Define application behaviors. - //new pqQtMessageHandlerBehavior(this); - new pqDataTimeStepBehavior(this); - new pqViewFrameActionsBehavior(this); - new pqSpreadSheetVisibilityBehavior(this); - new pqPipelineContextMenuBehavior(this); - new pqObjectPickingBehavior(this); // NEW in 4.1 - new pqDefaultViewBehavior(this); - new pqAlwaysConnectedBehavior(this); - new pqPVNewSourceBehavior(this); - new pqDeleteBehavior(this); - new pqUndoRedoBehavior(this); - new pqCrashRecoveryBehavior(this); - new pqAutoLoadPluginXMLBehavior(this); - new pqPluginDockWidgetsBehavior(aDesktop); - //new pqVerifyRequiredPluginBehavior(this); - new pqPluginActionGroupBehavior(aDesktop); - //new pqFixPathsInStateFilesBehavior(this); - new pqCommandLineOptionsBehavior(this); - new pqPersistentMainWindowStateBehavior(aDesktop); - new pqObjectPickingBehavior(aDesktop); - new pqCollaborationBehavior(this); - //new pqMultiServerBehavior(this); - new pqViewStreamingBehavior(this); - - // Setup quick-launch shortcuts. - QShortcut *ctrlSpace = new QShortcut(Qt::CTRL + Qt::Key_Space, aDesktop); - QObject::connect(ctrlSpace, SIGNAL(activated()), - pqApplicationCore::instance(), SLOT(quickLaunch())); - - // Find Plugin Dock Widgets - QList currentDocks = aDesktop->findChildren(); - QList::iterator i; - for (i = currentDocks.begin(); i != currentDocks.end(); ++i) { - if(!activeDocks.contains(*i)) { - myDockWidgets[*i] = false; // hidden by default - (*i)->hide(); - } + SalomeApp_Application* anApp = getApp(); + SUIT_Desktop* aDesktop = anApp->desktop(); + + // Remember current state of desktop toolbars + QList foreignToolbars = aDesktop->findChildren(); + + // Simulate ParaView client main window + //Implementation = new pqImplementation( aDesktop ); + + setupDockWidgets(); + + pvCreateActions(); + pvCreateToolBars(); + pvCreateMenus(); + + QList activeDocks = aDesktop->findChildren(); + QList activeMenus = aDesktop->findChildren(); + + // new pqParaViewBehaviors(anApp->desktop(), this); + // Has to be replaced in order to exclude using of pqQtMessageHandlerBehaviour + // Start pqParaViewBehaviors + // Register ParaView interfaces. + //pqPluginManager* pgm = pqApplicationCore::instance()->getPluginManager(); + pqInterfaceTracker* pgm = pqApplicationCore::instance()->interfaceTracker(); + + // * adds support for standard paraview views. + pgm->addInterface(new pqStandardViewModules(pgm)); + //pgm->addInterface(new pqStandardSummaryPanelImplementation(pgm)); + pgm->addInterface(new pqStandardPropertyWidgetInterface(pgm)); + + // Load plugins distributed with application. + pqApplicationCore::instance()->loadDistributedPlugins(); + + // Define application behaviors. + //new pqQtMessageHandlerBehavior(this); + new pqDataTimeStepBehavior(this); + new pqViewFrameActionsBehavior(this); + new pqSpreadSheetVisibilityBehavior(this); + new pqPipelineContextMenuBehavior(this); + new pqObjectPickingBehavior(this); // NEW in 4.1 + new pqDefaultViewBehavior(this); + new pqAlwaysConnectedBehavior(this); + new pqPVNewSourceBehavior(this); + new pqDeleteBehavior(this); + new pqUndoRedoBehavior(this); + new pqCrashRecoveryBehavior(this); + new pqAutoLoadPluginXMLBehavior(this); + new pqPluginDockWidgetsBehavior(aDesktop); + //new pqVerifyRequiredPluginBehavior(this); + new pqPluginActionGroupBehavior(aDesktop); + //new pqFixPathsInStateFilesBehavior(this); + new pqCommandLineOptionsBehavior(this); + new pqPersistentMainWindowStateBehavior(aDesktop); + new pqObjectPickingBehavior(aDesktop); + new pqCollaborationBehavior(this); + //new pqMultiServerBehavior(this); + new pqViewStreamingBehavior(this); + + // Setup quick-launch shortcuts. + QShortcut *ctrlSpace = new QShortcut(Qt::CTRL + Qt::Key_Space, aDesktop); + QObject::connect(ctrlSpace, SIGNAL(activated()), + pqApplicationCore::instance(), SLOT(quickLaunch())); + + // Find Plugin Dock Widgets + QList currentDocks = aDesktop->findChildren(); + QList::iterator i; + for (i = currentDocks.begin(); i != currentDocks.end(); ++i) { + if(!activeDocks.contains(*i)) { + myDockWidgets[*i] = false; // hidden by default + (*i)->hide(); } + } - // Find Plugin Menus - QList currentMenus = aDesktop->findChildren(); - QList::iterator im; - for (im = currentMenus.begin(); im != currentMenus.end(); ++im) { - if(!activeMenus.contains(*im)) { - myMenus.append(*im); - } + // Find Plugin Menus + QList currentMenus = aDesktop->findChildren(); + QList::iterator im; + for (im = currentMenus.begin(); im != currentMenus.end(); ++im) { + if(!activeMenus.contains(*im)) { + myMenus.append(*im); } + } - SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); - QString aPath = resMgr->stringValue("resources", "PARAVIS", QString()); - if (!aPath.isNull()) { - MyCoreApp->loadConfiguration(aPath + QDir::separator() + "ParaViewFilters.xml"); - MyCoreApp->loadConfiguration(aPath + QDir::separator() + "ParaViewReaders.xml"); - MyCoreApp->loadConfiguration(aPath + QDir::separator() + "ParaViewSources.xml"); - MyCoreApp->loadConfiguration(aPath + QDir::separator() + "ParaViewWriters.xml"); - } - - // Force creation of engine - PARAVIS::GetParavisGen(this); - updateObjBrowser(); + SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); + QString aPath = resMgr->stringValue("resources", "PARAVIS", QString()); + if (!aPath.isNull()) { + MyCoreApp->loadConfiguration(aPath + QDir::separator() + "ParaViewFilters.xml"); + MyCoreApp->loadConfiguration(aPath + QDir::separator() + "ParaViewReaders.xml"); + MyCoreApp->loadConfiguration(aPath + QDir::separator() + "ParaViewSources.xml"); + MyCoreApp->loadConfiguration(aPath + QDir::separator() + "ParaViewWriters.xml"); + } - // Find created toolbars - QCoreApplication::processEvents(); + // Force creation of the PARAVIS engine + GetEngine(); + updateObjBrowser(); - QList allToolbars = aDesktop->findChildren(); - foreach(QToolBar* aBar, allToolbars) { - if (!foreignToolbars.contains(aBar)) { - myToolbars[aBar] = true; - myToolbarBreaks[aBar] = false; - aBar->setVisible(false); - aBar->toggleViewAction()->setVisible(false); - } + // Find created toolbars + QCoreApplication::processEvents(); + + QList allToolbars = aDesktop->findChildren(); + foreach(QToolBar* aBar, allToolbars) { + if (!foreignToolbars.contains(aBar)) { + myToolbars[aBar] = true; + myToolbarBreaks[aBar] = false; + aBar->setVisible(false); + aBar->toggleViewAction()->setVisible(false); } - //} + } updateMacros(); @@ -501,12 +514,17 @@ void PVGUI_Module::initialize( CAM_Application* app ) connect(pqApplicationCore::instance()->getObjectBuilder(), SIGNAL(dataRepresentationCreated(pqDataRepresentation*)), this, SLOT(onDataRepresentationCreated(pqDataRepresentation*))); - SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr(); bool isStop = aResourceMgr->booleanValue( "PARAVIS", "stop_trace", false ); // start a timer to schedule the trace start asap: if(!isStop) - startTimer( 0 ); + { + startTimer( 0 ); + myPushTraceTimer = new QTimer(aDesktop); + QObject::connect(myPushTraceTimer, SIGNAL(timeout()), this, SLOT(onPushTraceTimer()) ); + myPushTraceTimer->setSingleShot(false); + myPushTraceTimer->start(500); + } this->VTKConnect = vtkEventQtSlotConnect::New(); @@ -528,21 +546,51 @@ void PVGUI_Module::initialize( CAM_Application* app ) SIGNAL(representationChanged(pqRepresentation*)), this, SLOT(onRepresentationChanged(pqRepresentation*))); - // Try to connect to the external PVServer +#ifndef PARAVIS_WITH_FULL_CORBA + connectToExternalPVServer(); +#endif +} + +bool PVGUI_Module::connectToExternalPVServer() +{ + pqServer* server = pqActiveObjects::instance().activeServer(); + if (server && server->isRemote()) + { + // Already connected to an external server, do nothing + MESSAGE("connectToExternalPVServer(): Already connected to an external PVServer, won't reconnect."); + return false; + } + + std::stringstream msg; + + // Try to connect to the external PVServer - gives priority to an externally specified URL: QString serverUrlEnv = getenv("PARAVIS_PVSERVER_URL"); - const char * serverUrl = "cs://localhost"; + std::string serverUrl; if (!serverUrlEnv.isEmpty()) - serverUrl = serverUrlEnv.toStdString().c_str(); - std::cout << "** Trying to connect to the external PVServer '" << serverUrl << "' ..." << std::endl; + serverUrl = serverUrlEnv.toStdString(); + else + { + // Get the URL from the engine (possibly starting the pvserver) + CORBA::String_var url = GetEngine()->FindOrStartPVServer(0); // take the first free port + serverUrl = (char *)url; + } + + msg << "connectToExternalPVServer(): Trying to connect to the external PVServer '" << serverUrl << "' ..."; + MESSAGE(msg.str()); - if (!pqServerConnectReaction::connectToServer(pqServerResource(serverUrl))) + if (!pqServerConnectReaction::connectToServer(pqServerResource(serverUrl.c_str()))) { - std::cerr << "** Could not connect to the requested server \"" - << serverUrl << "\". Creating default builtin connection.\n" << std::endl; + std::stringstream msg2; + msg2 << "Error while connecting to the requested pvserver '" << serverUrl; + msg2 << "'. Might use default built-in connection instead!" << std::endl; + qWarning(msg2.str().c_str()); // will go to the ParaView console (see ParavisMessageOutput below) + SUIT_MessageBox::warning( getApp()->desktop(), + QString("Error connecting to PVServer"), QString(msg2.str().c_str())); + return false; } else - std::cout << "** Connected!" << std::endl; - + MESSAGE("connectToExternalPVServer(): Connected!"); + return true; } void PVGUI_Module::onStartProgress() @@ -665,6 +713,8 @@ void PVGUI_Module::execPythonCommand(const QString& cmd, bool inSalomeConsole) */ void PVGUI_Module::timerEvent(QTimerEvent* te ) { +// connectToExternalPVServer(); + #ifndef WNT if ( PyInterp_Dispatcher::Get()->IsBusy() ) { @@ -942,6 +992,10 @@ bool PVGUI_Module::activateModule( SUIT_Study* study ) */ bool PVGUI_Module::deactivateModule( SUIT_Study* study ) { + // Stop Python trace + MESSAGE("Stopping Python trace ...") + execPythonCommand("from paraview import smtrace;smtrace.stop_trace()", false); + QMenu* aMenu = menuMgr()->findMenu( myRecentMenuId ); if(aMenu) { QList anActns = aMenu->actions(); @@ -978,7 +1032,6 @@ bool PVGUI_Module::deactivateModule( SUIT_Study* study ) setMenuShown( false ); setToolShown( false ); - saveDockWidgetsState(); SUIT_ExceptionHandler::removeCleanUpRoutine( paravisCleanUp ); @@ -1037,7 +1090,7 @@ void PVGUI_Module::onModelOpened() } _PTR(SComponent) paravisComp = - studyDS->FindComponent(PARAVIS::GetParavisGen(this)->ComponentDataType()); + studyDS->FindComponent(GetEngine()->ComponentDataType()); if(!paravisComp) { return; } @@ -1061,7 +1114,7 @@ void PVGUI_Module::onModelOpened() */ QString PVGUI_Module::engineIOR() const { - CORBA::String_var anIOR = PARAVIS::GetParavisGen(this)->GetIOR(); + CORBA::String_var anIOR = GetEngine()->GetIOR(); return QString(anIOR.in()); } @@ -1198,65 +1251,6 @@ void PVGUI_Module::loadParaviewState(const char* theFileName) pqApplicationCore::instance()->loadState(theFileName, getActiveServer()); } -/*! - \brief Imports MED data from VISU module by data entry -*/ -void PVGUI_Module::onImportFromVisu(QString theEntry) -{ -#ifdef WITH_VISU - SUIT_OverrideCursor aWaitCursor; - - // get active study - SalomeApp_Study* activeStudy = dynamic_cast(application()->activeStudy()); - if(!activeStudy) return; - - // get SALOMEDS client study - _PTR(Study) aStudy = activeStudy->studyDS(); - if(!aStudy) return; - - // find VISU component in a study - _PTR(SComponent) aVisuComp = aStudy->FindComponent( "VISU" ); - if(!aVisuComp) return; - - // get SObject client by entry - _PTR(SObject) aSObj = aStudy->FindObjectID(qPrintable(theEntry)); - if (!aSObj) return; - - // get CORBA SObject - SALOMEDS_SObject* aSObject = _CAST(SObject, aSObj); - if ( !aSObject ) return; - - // load VISU engine - SALOME_NamingService* aNamingService = SalomeApp_Application::namingService(); - SALOME_LifeCycleCORBA aLCC(aNamingService); - - Engines::EngineComponent_var aComponent = aLCC.FindOrLoad_Component("FactoryServer","VISU"); - VISU::VISU_Gen_var aVISU = VISU::VISU_Gen::_narrow(aComponent); - if(CORBA::is_nil(aVISU)) return; - - _PTR(StudyBuilder) aStudyBuilder = aStudy->NewBuilder(); - aStudyBuilder->LoadWith( aVisuComp, SalomeApp_Application::orb()->object_to_string(aVISU) ); - - // get VISU result object - CORBA::Object_var aResultObject = aSObject->GetObject(); - if (CORBA::is_nil(aResultObject)) return; - VISU::Result_var aResult = VISU::Result::_narrow( aResultObject ); - if (CORBA::is_nil(aResult)) return; - - // export VISU result to the MED file - std::string aTmpDir = SALOMEDS_Tool::GetTmpDir(); - std::string aFileName = aSObject->GetName(); - std::string aFilePath = aTmpDir + aFileName; - - if (aResult->ExportMED(aFilePath.c_str())) { - openFile(aFilePath.c_str()); - myTemporaryFiles.append(QString(aFilePath.c_str())); - } -#else - MESSAGE("Visu module is not found."); -#endif -} - /*! \brief Deletes temporary files created during import operation from VISU */ @@ -1344,7 +1338,7 @@ void PVGUI_Module::contextMenuPopup(const QString& theClient, QMenu* theMenu, QS return; } - QString paravisDataType(PARAVIS::GetParavisGen(this)->ComponentDataType()); + QString paravisDataType(GetEngine()->ComponentDataType()); if(activeStudy && activeStudy->isComponent(entry) && activeStudy->componentDataType(entry) == paravisDataType) { // ParaViS module object @@ -1428,7 +1422,7 @@ void PVGUI_Module::onSaveMultiState() } _PTR(SComponent) paravisComp = - studyDS->FindComponent(PARAVIS::GetParavisGen(this)->ComponentDataType()); + studyDS->FindComponent(GetEngine()->ComponentDataType()); if(!paravisComp) { return; } @@ -1463,8 +1457,7 @@ void PVGUI_Module::onSaveMultiState() // File name for state saving QString tmpDir = QString::fromStdString(SALOMEDS_Tool::GetTmpDir()); - QString fileName = QString("%1_paravisstate:%2").arg(tmpDir, - stateEntry); + QString fileName = QString("%1_paravisstate:%2").arg(tmpDir, stateEntry); anAttr = studyBuilder->FindOrCreateAttribute(newSObj, "AttributeString"); _PTR(AttributeString) stringAttr(anAttr); @@ -1536,10 +1529,10 @@ void PVGUI_Module::onRename() if (stateSObj->FindAttribute(anAttr, "AttributeName")) { _PTR(AttributeName) nameAttr (anAttr); QString newName = - LightApp_NameDlg::getName(getApp()->desktop(), nameAttr->Value().c_str()); + LightApp_NameDlg::getName(getApp()->desktop(), nameAttr->Value().c_str()); if (!newName.isEmpty()) { - nameAttr->SetValue(newName.toLatin1().constData()); - aListIO.First()->setName(newName.toLatin1().constData()); + nameAttr->SetValue(newName.toLatin1().constData()); + aListIO.First()->setName(newName.toLatin1().constData()); } } @@ -1593,6 +1586,12 @@ void PVGUI_Module::onDelete() } } +void PVGUI_Module::onPushTraceTimer() +{ + //MESSAGE("Pushing trace ..."); + GetEngine()->PutPythonTraceStringToEngine(getTraceString().toStdString().c_str()); +} + /*! \brief Discover help project files from the resources. \return name of the help file. @@ -1649,7 +1648,7 @@ void PVGUI_Module::loadSelectedState(bool toClear) QString stringValue(aStringAttr->Value().c_str()); if (QFile::exists(stringValue)) { - fileName = stringValue; + fileName = stringValue; } } } diff --git a/src/PVGUI/PVGUI_Module.h b/src/PVGUI/PVGUI_Module.h index 0b30e767..650872b9 100644 --- a/src/PVGUI/PVGUI_Module.h +++ b/src/PVGUI/PVGUI_Module.h @@ -27,9 +27,15 @@ #define PVGUI_Module_H #include +#include "SALOMEconfig.h" +#include CORBA_SERVER_HEADER(SALOMEDS) +#ifndef PARAVIS_WITH_FULL_CORBA +# include CORBA_SERVER_HEADER(PARAVIS_Gen) +#endif #include #include +#include #include @@ -140,6 +146,8 @@ public: PVGUI_Module(); ~PVGUI_Module(); + static PARAVIS_ORB::PARAVIS_Gen_var GetEngine(); + virtual void initialize( CAM_Application* ); virtual void windows( QMap& ) const; @@ -163,7 +171,7 @@ public: virtual void contextMenuPopup(const QString& theClient, QMenu* theMenu, QString& theTitle); public slots: - void onImportFromVisu(QString theEntry); + //void onImportFromVisu(QString theEntry); private: //! Initialize ParaView if not yet done (once per session) @@ -224,6 +232,10 @@ private: //! run Python command (either in SALOME's Python interpreter, or in ParaView's Python's interpreter) void execPythonCommand(const QString& cmd, bool inSalomeConsole=false); + //! Connect to the external PVServer, using the PARAVIS engine to launch it if it is not + //! already up. + bool connectToExternalPVServer(); + private slots: void showHelpForProxy( const QString&, const QString& ); @@ -265,6 +277,7 @@ public slots: protected slots: virtual void onModelOpened(); + virtual void onPushTraceTimer(); protected: void timerEvent(QTimerEvent *event); @@ -300,6 +313,10 @@ private: int myStateCounter; static pqPVApplicationCore* MyCoreApp; + + static PARAVIS_ORB::PARAVIS_Gen_var myEngine; + + QTimer * myPushTraceTimer; }; #endif // PVGUI_Module_H diff --git a/src/PVGUI/PVGUI_Module_widgets.cxx b/src/PVGUI/PVGUI_Module_widgets.cxx index 76624da9..e8aa2efb 100644 --- a/src/PVGUI/PVGUI_Module_widgets.cxx +++ b/src/PVGUI/PVGUI_Module_widgets.cxx @@ -377,14 +377,16 @@ void PVGUI_Module::restoreDockWidgetsState() dw->setVisible( it1.value() ); dw->toggleViewAction()->setVisible( true ); } - // restore toolbar breaks state - QMapIterator it2( myToolbarBreaks ); - while( it2.hasNext() ) { - it2.next(); - QToolBar* tb = qobject_cast( it2.key() ); - if ( myToolbarBreaks[tb] ) - desk->insertToolBarBreak( tb ); - } + + // restore toolbar breaks state + QMapIterator it2( myToolbarBreaks ); + while( it2.hasNext() ) { + it2.next(); + QToolBar* tb = qobject_cast( it2.key() ); + if ( myToolbarBreaks[tb] ) + desk->insertToolBarBreak( tb ); + } + // restore toolbar visibility state QMapIterator it3( myToolbars ); while( it3.hasNext() ) { @@ -425,15 +427,15 @@ void PVGUI_Module::storeCommonWindowsState() { QDockWidget* dock = 0; QWidget* w = wg->parentWidget(); while ( w && !dock ) { - dock = ::qobject_cast( w ); - w = w->parentWidget(); + dock = ::qobject_cast( w ); + w = w->parentWidget(); } if(dock){ - if(!myCommonMap.contains(i)){ - myCommonMap.insert(i,dock->isVisible()); - } else { - myCommonMap[i] = dock->isVisible(); - } + if(!myCommonMap.contains(i)){ + myCommonMap.insert(i,dock->isVisible()); + } else { + myCommonMap[i] = dock->isVisible(); + } } } } @@ -453,11 +455,11 @@ void PVGUI_Module::restoreCommonWindowsState() { QDockWidget* dock = 0; QWidget* w = wg->parentWidget(); while ( w && !dock ) { - dock = ::qobject_cast( w ); - w = w->parentWidget(); + dock = ::qobject_cast( w ); + w = w->parentWidget(); } if(dock) { - dock->setVisible(it.value()); + dock->setVisible(it.value()); } } } diff --git a/src/PVGUI/PVGUI_Tools.cxx b/src/PVGUI/PVGUI_Tools.cxx index 54f27cfb..0dc7fbd3 100644 --- a/src/PVGUI/PVGUI_Tools.cxx +++ b/src/PVGUI/PVGUI_Tools.cxx @@ -32,6 +32,7 @@ using namespace std; //============================================================================= namespace PARAVIS { +#ifdef PARAVIS_WITH_FULL_CORBA //------------------------------------------------------------ PARAVIS_Gen_i* GetParavisGen(const CAM_Module* theModule) { @@ -48,6 +49,7 @@ namespace PARAVIS throw std::runtime_error("Can not create PARAVIS_Gen"); return aGen; } +#endif //------------------------------------------------------------ _PTR(Study) GetCStudy(const CAM_Module* theModule) diff --git a/src/PVGUI/PVGUI_Tools.h b/src/PVGUI/PVGUI_Tools.h index 84433ea3..c7346796 100644 --- a/src/PVGUI/PVGUI_Tools.h +++ b/src/PVGUI/PVGUI_Tools.h @@ -25,16 +25,21 @@ #ifndef PVGUI_Tools_H #define PVGUI_Tools_H -#include "PARAVIS_Gen_i.hh" +#ifdef PARAVIS_WITH_FULL_CORBA +# include "PARAVIS_Gen_i.hh" +#endif #include "SALOMEDSClient_Study.hxx" +#define PVSTATEID 15555 + class CAM_Module; namespace PARAVIS { - +#ifdef PARAVIS_WITH_FULL_CORBA PARAVIS_Gen_i* GetParavisGen(const CAM_Module* theModule); +#endif _PTR(Study) GetCStudy(const CAM_Module* theModule); }; diff --git a/src/PVGUI/PVGUI_MatplotlibMathTextUtilities.cxx b/src/PVGUI/deprecated/PVGUI_MatplotlibMathTextUtilities.cxx similarity index 100% rename from src/PVGUI/PVGUI_MatplotlibMathTextUtilities.cxx rename to src/PVGUI/deprecated/PVGUI_MatplotlibMathTextUtilities.cxx diff --git a/src/PVGUI/PVGUI_MatplotlibMathTextUtilities.h b/src/PVGUI/deprecated/PVGUI_MatplotlibMathTextUtilities.h similarity index 100% rename from src/PVGUI/PVGUI_MatplotlibMathTextUtilities.h rename to src/PVGUI/deprecated/PVGUI_MatplotlibMathTextUtilities.h diff --git a/src/PVGUI/PV_Tools.cxx b/src/PVGUI/deprecated/PV_Tools.cxx similarity index 100% rename from src/PVGUI/PV_Tools.cxx rename to src/PVGUI/deprecated/PV_Tools.cxx diff --git a/src/PVGUI/PV_Tools.h b/src/PVGUI/deprecated/PV_Tools.h similarity index 100% rename from src/PVGUI/PV_Tools.h rename to src/PVGUI/deprecated/PV_Tools.h diff --git a/src/PV_SWIG/CMakeLists.txt b/src/PV_SWIG/CMakeLists.txt index 64fe2f88..da9f7cb5 100644 --- a/src/PV_SWIG/CMakeLists.txt +++ b/src/PV_SWIG/CMakeLists.txt @@ -29,17 +29,17 @@ ELSE(SALOME_LIGHT_ONLY) # Use another set of Python files redirecting the API directly # to the original ParaView modules. LIST(APPEND _PYFILES_TO_INSTALL - paravis.py - pvsimple.py - presentations.py - paravisSM.py + no_wrap/paravis.py + no_wrap/pvsimple.py + no_wrap/presentations.py + no_wrap/paravisSM.py ) ELSE() LIST(APPEND _PYFILES_TO_INSTALL - VTKWrapping/paravis.py - VTKWrapping/paravisSM.py - VTKWrapping/pvsimple.py - VTKWrapping/presentations.py + paravis.py + paravisSM.py + pvsimple.py + presentations.py ) ENDIF() ENDIF(SALOME_LIGHT_ONLY) diff --git a/src/PV_SWIG/VTKWrapping/paravis.py b/src/PV_SWIG/VTKWrapping/paravis.py deleted file mode 100644 index da1119a1..00000000 --- a/src/PV_SWIG/VTKWrapping/paravis.py +++ /dev/null @@ -1,97 +0,0 @@ -# Copyright (C) 2010-2014 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 -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# -# File : paravis.py -# Module : PARAVIS -# - -import os, new - -import PARAVIS -import SALOME -import SALOME_Session_idl -import SALOMEDS -import SALOME_ModuleCatalog -from omniORB import CORBA -from time import sleep -from salome import * - -myORB = None -myNamingService = None -myLifeCycleCORBA = None -myNamingService = None -myLocalStudyManager = None -myLocalStudy = None -myLocalParavis = None -myDelay = None -mySession = None - -## Initialization of paravis server -def Initialize(theORB, theNamingService, theLifeCycleCORBA, theStudyManager, theStudy, theDelay) : - global myORB, myNamingService, myLifeCycleCORBA, myLocalStudyManager, myLocalStudy - global mySession, myDelay - myDelay = theDelay - myORB = theORB - myNamingService = theNamingService - myLifeCycleCORBA = theLifeCycleCORBA - myLocalStudyManager = theStudyManager - while mySession == None: - mySession = myNamingService.Resolve("/Kernel/Session") - mySession = mySession._narrow(SALOME.Session) - mySession.GetInterface() - myDelay = theDelay - sleep(myDelay) - myLocalParavis = myLifeCycleCORBA.FindOrLoadComponent("FactoryServer", "PARAVIS") - myLocalStudy = theStudy - myLocalParavis.SetCurrentStudy(myLocalStudy) - myLocalParavis.ActivateModule() - return myLocalParavis - - -def ImportFile(theFileName): - "Import a file of any format supported by ParaView" - myParavis.ImportFile(theFileName) - - -def createFunction(theName): - "Create function - constructor of Paravis object" - def MyFunction(): - return myParavis.CreateClass(theName) - return MyFunction - - -def createConstructors(): - "Create constructor functions according to list of extracted classes" - g = globals() - aClassNames = myParavis.GetClassesList(); - for aName in aClassNames: - g[aName] = createFunction(aName) - -## Initialize of a PARAVIS interface -myParavis = Initialize(orb, naming_service,lcc,myStudyManager,myStudy, 2) - -## Initialize constructor functions -createConstructors() - -## Initialize Paravis static objects -vtkSMObject = vtkSMObject() -vtkProcessModule = vtkProcessModule() -vtkPVPythonModule = vtkPVPythonModule() -vtkSMProxyManager = vtkSMProxyManager() - - diff --git a/src/PV_SWIG/VTKWrapping/paravisSM.py b/src/PV_SWIG/VTKWrapping/paravisSM.py deleted file mode 100644 index b82ee0f5..00000000 --- a/src/PV_SWIG/VTKWrapping/paravisSM.py +++ /dev/null @@ -1,3014 +0,0 @@ -# Copyright (C) 2010-2014 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 -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -r"""servermanager is a module for using paraview server manager in Python. -One can always use the server manager API directly. However, this module -provides an interface easier to use from Python by wrapping several VTK -classes around Python classes. - -Note that, upon load, this module will create several sub-modules: sources, -filters and rendering. These modules can be used to instantiate specific -proxy types. For a list, try "dir(servermanager.sources)" - -A simple example: - from paraview.servermanager import * - - # Creates a new built-in session and makes it the active session. - Connect() - - # Creates a new render view on the active session. - renModule = CreateRenderView() - - # Create a new sphere proxy on the active session and register it - # in the sources group. - sphere = sources.SphereSource(registrationGroup="sources", ThetaResolution=16, PhiResolution=32) - - # Create a representation for the sphere proxy and adds it to the render - # module. - display = CreateRepresentation(sphere, renModule) - - renModule.StillRender() -""" - - - -import re, os, new, sys -from paravis import * - -# VTN: Avoid paraview.* instructions in this file. -# It leads to problems during execution. - -def _wrap_property(proxy, smproperty): - """ Internal function. - Given a server manager property and its domains, returns the - appropriate python object. - """ - property = None - if smproperty.IsA("vtkSMStringVectorProperty"): - al = smproperty.GetDomain("array_list") - if al and al.IsA("vtkSMArraySelectionDomain") and \ - smproperty.GetRepeatable(): - property = ArrayListProperty(proxy, smproperty) - elif al and al.IsA("vtkSMArrayListDomain") and smproperty.GetNumberOfElements() == 5: - property = ArraySelectionProperty(proxy, smproperty) - else: - iter = smproperty.NewDomainIterator() - isFileName = False - while not iter.IsAtEnd(): - # Refer to BUG #9710 to see why optional domains need to be - # ignored. - if iter.GetDomain().IsA("vtkSMFileListDomain") and \ - iter.GetDomain().GetIsOptional() == 0 : - isFileName = True - break - iter.Next() - iter.UnRegister(None) - if isFileName: - property = FileNameProperty(proxy, smproperty) - elif _make_name_valid(smproperty.GetXMLLabel()) == 'ColorArrayName': - property = ColorArrayProperty(proxy, smproperty) - else: - property = VectorProperty(proxy, smproperty) - elif smproperty.IsA("vtkSMVectorProperty"): - if smproperty.IsA("vtkSMIntVectorProperty") and \ - smproperty.GetDomain("enum"): - property = EnumerationProperty(proxy, smproperty) - else: - property = VectorProperty(proxy, smproperty) - elif smproperty.IsA("vtkSMInputProperty"): - property = InputProperty(proxy, smproperty) - elif smproperty.IsA("vtkSMProxyProperty"): - property = ProxyProperty(proxy, smproperty) - else: - property = Property(proxy, smproperty) - return property - -class Proxy(object): - """Proxy for a server side object. A proxy manages the lifetime of - one or more server manager objects. It also provides an interface - to set and get the properties of the server side objects. These - properties are presented as Python properties. For example, - you can set a property Foo using the following: - proxy.Foo = (1,2) - or - proxy.Foo.SetData((1,2)) - or - proxy.Foo[0:2] = (1,2) - For more information, see the documentation of the property which - you can obtain with - help(proxy.Foo). - - This class also provides an iterator which can be used to iterate - over all properties. - eg: - proxy = Proxy(proxy=smproxy) - for property in proxy: - print property - - For advanced users: - This is a python class that wraps a vtkSMProxy.. Makes it easier to - set/get properties. - Instead of: - proxy.GetProperty("Foo").SetElement(0, 1) - proxy.GetProperty("Foo").SetElement(0, 2) - you can do: - proxy.Foo = (1,2) - or - proxy.Foo.SetData((1,2)) - or - proxy.Foo[0:2] = (1,2) - Instead of: - proxy.GetProperty("Foo").GetElement(0) - you can do: - proxy.Foo.GetData()[0] - or - proxy.Foo[0] - For proxy properties, you can use append: - proxy.GetProperty("Bar").AddProxy(foo) - you can do: - proxy.Bar.append(foo) - Properties support most of the list API. See VectorProperty and - ProxyProperty documentation for details. - - Please note that some of the methods accessible through the Proxy - class are not listed by help() because the Proxy objects forward - unresolved attributes to the underlying object. To get the full list, - see also dir(proxy.SMProxy). See also the doxygen based documentation - of the vtkSMProxy C++ class. - """ - - def __init__(self, **args): - """ Default constructor. It can be used to initialize properties - by passing keyword arguments where the key is the name of the - property. In addition registrationGroup and registrationName (optional) - can be specified (as keyword arguments) to automatically register - the proxy with the proxy manager. """ - self.add_attribute('Observed', None) - self.add_attribute('ObserverTag', -1) - self.add_attribute('_Proxy__Properties', {}) - self.add_attribute('_Proxy__LastAttrName', None) - self.add_attribute('SMProxy', None) - self.add_attribute('Port', 0) - - if 'port' in args: - self.Port = args['port'] - del args['port'] - - update = True - if 'no_update' in args: - if args['no_update']: - update = False - del args['no_update'] - - if 'proxy' in args: - self.InitializeFromProxy(args['proxy']) - del args['proxy'] - else: - self.Initialize(None, update) - if 'registrationGroup' in args: - registrationGroup = args['registrationGroup'] - del args['registrationGroup'] - registrationName = self.SMProxy.GetGlobalIDAsString() - if 'registrationName' in args: - registrationName = args['registrationName'] - del args['registrationName'] - pxm = ProxyManager() - pxm.RegisterProxy(registrationGroup, registrationName, self.SMProxy) - if update: - self.UpdateVTKObjects() - for key in args.keys(): - setattr(self, key, args[key]) - # Visit all properties so that they are created - for prop in self: - pass - - def __setattr__(self, name, value): - try: - setter = getattr(self.__class__, name) - setter = setter.__set__ - except AttributeError: - if not hasattr(self, name): - raise AttributeError("Attribute %s does not exist. " % name + - " This class does not allow addition of new attributes to avoid " + - "mistakes due to typos. Use add_attribute() if you really want " + - "to add this attribute.") - self.__dict__[name] = value - else: - setter(self, value) - - def add_attribute(self, name, value): - self.__dict__[name] = value - - def __del__(self): - """Destructor. Cleans up all observers as well as remove - the proxy from the _pyproxies dictionary""" - # Make sure that we remove observers we added - if self.Observed: - observed = self.Observed - tag = self.ObserverTag - self.Observed = None - self.ObserverTag = -1 - observed.RemoveObserver(tag) - if _pyproxies and self.SMProxy and (self.SMProxy, self.Port) in _pyproxies: - del _pyproxies[(self.SMProxy, self.Port)] - - def InitializeFromProxy(self, aProxy, update=True): - """Constructor. Assigns proxy to self.SMProxy, updates the server - object as well as register the proxy in _pyproxies dictionary.""" - import weakref - self.SMProxy = aProxy - if update: - self.SMProxy.UpdateVTKObjects() - _pyproxies[(self.SMProxy, self.Port)] = weakref.ref(self) - - def Initialize(self): - "Overridden by the subclass created automatically" - pass - - def __eq__(self, other): - "Returns true if the underlying SMProxies are the same." - if isinstance(other, Proxy): - try: - if self.Port != other.Port: - return False - except: - pass - ## VSV using IsSame instead == - return self.SMProxy.IsSame(other.SMProxy) - return self.SMProxy.IsSame(other) - - def __ne__(self, other): - "Returns false if the underlying SMProxies are the same." - return not self.__eq__(other) - - def __iter__(self): - "Creates an iterator for the properties." - return PropertyIterator(self) - - def SetPropertyWithName(self, pname, arg): - """Generic method for setting the value of a property.""" - prop = self.GetProperty(pname) - if prop is None: - raise RuntimeError, "Property %s does not exist. Please check the property name for typos." % pname - prop.SetData(arg) - - def GetPropertyValue(self, name): - """Returns a scalar for properties with 1 elements, the property - itself for vectors.""" - p = self.GetProperty(name) - if isinstance(p, VectorProperty): - if p.GetNumberOfElements() == 1 and not p.GetRepeatable(): - if p.SMProperty.IsA("vtkSMStringVectorProperty") or not p.GetArgumentIsArray(): - return p[0] - elif isinstance(p, InputProperty): - if not p.GetMultipleInput(): - if len(p) > 0: - return p[0] - else: - return None - elif isinstance(p, ProxyProperty): - if not p.GetRepeatable(): - if len(p) > 0: - return p[0] - else: - return None - return p - - def GetProperty(self, name): - """Given a property name, returns the property object.""" - if name in self.__Properties and self.__Properties[name](): - return self.__Properties[name]() - smproperty = self.SMProxy.GetProperty(name) - # Maybe they are looking by the label. Try to match that. - if not smproperty: - iter = PropertyIterator(self) - for prop in iter: - if name == _make_name_valid(iter.PropertyLabel): - smproperty = prop.SMProperty - break - if smproperty: - property = _wrap_property(self, smproperty) - if property is not None: - import weakref - self.__Properties[name] = weakref.ref(property) - return property - return None - - def ListProperties(self): - """Returns a list of all property names on this proxy.""" - property_list = [] - iter = self.__iter__() - for property in iter: - name = _make_name_valid(iter.PropertyLabel) - if name: - property_list.append(name) - return property_list - - def __ConvertArgumentsAndCall(self, *args): - """ Internal function. - Used to call a function on SMProxy. Converts input and - output values as appropriate. - """ - newArgs = [] - for arg in args: - if issubclass(type(arg), Proxy) or isinstance(arg, Proxy): - newArgs.append(arg.SMProxy) - else: - newArgs.append(arg) - func = getattr(self.SMProxy, self.__LastAttrName) - retVal = func(*newArgs) - if type(retVal) is type(self.SMProxy) and retVal.IsA("vtkSMProxy"): - return _getPyProxy(retVal) - elif type(retVal) is type(self.SMProxy) and retVal.IsA("vtkSMProperty"): - return _wrap_property(self, retVal) - else: - return retVal - - def __GetActiveCamera(self): - """ This method handles GetActiveCamera specially. It adds - an observer to the camera such that everytime it is modified - the render view updated""" - import weakref - c = self.SMProxy.GetActiveCamera() - # VSV: Observers are not supported -## if not c.HasObserver("ModifiedEvent"): -## self.ObserverTag =c.AddObserver("ModifiedEvent", _makeUpdateCameraMethod(weakref.ref(self))) -## self.Observed = c - return c - - def __getattr__(self, name): - """With the exception of a few overloaded methods, - returns the SMProxy method""" - if not self.SMProxy: - raise AttributeError("class %s has no attribute %s" % ("None", name)) - return None - # Handle GetActiveCamera specially. - if name == "GetActiveCamera" and \ - hasattr(self.SMProxy, "GetActiveCamera"): - return self.__GetActiveCamera - if name == "SaveDefinition" and hasattr(self.SMProxy, "SaveDefinition"): - return self.__SaveDefinition - # If not a property, see if SMProxy has the method - try: - proxyAttr = getattr(self.SMProxy, name) - self.__LastAttrName = name - return self.__ConvertArgumentsAndCall - except: - pass - return getattr(self.SMProxy, name) - -class SourceProxy(Proxy): - """Proxy for a source object. This class adds a few methods to Proxy - that are specific to sources. It also provides access to the output - ports. Output ports can be accessed by name or index: - > op = source[0] - or - > op = source['some name']. - """ - def UpdatePipeline(self, time=None): - """This method updates the server-side VTK pipeline and the associated - data information. Make sure to update a source to validate the output - meta-data.""" - if time != None: - self.SMProxy.UpdatePipeline(time) - else: - self.SMProxy.UpdatePipeline() - # This is here to cause a receive - # on the client side so that progress works properly. - if ActiveConnection and ActiveConnection.IsRemote(): - self.SMProxy.GetDataInformation() - - def FileNameChanged(self): - "Called when the filename of a source proxy is changed." - self.UpdatePipelineInformation() - - def UpdatePipelineInformation(self): - """This method updates the meta-data of the server-side VTK pipeline and - the associated information properties""" - self.SMProxy.UpdatePipelineInformation() - - def GetDataInformation(self, idx=None): - """This method returns a DataInformation wrapper around a - vtkPVDataInformation""" - if idx == None: - idx = self.Port - if self.SMProxy: - return DataInformation( \ - self.SMProxy.GetDataInformation(idx), \ - self.SMProxy, idx) - - def __getitem__(self, idx): - """Given a slice, int or string, returns the corresponding - output port""" - if isinstance(idx, slice): - indices = idx.indices(self.SMProxy.GetNumberOfOutputPorts()) - retVal = [] - for i in range(*indices): - retVal.append(OutputPort(self, i)) - return retVal - elif isinstance(idx, int): - if idx >= self.SMProxy.GetNumberOfOutputPorts() or idx < 0: - raise IndexError - return OutputPort(self, idx) - else: - return OutputPort(self, self.SMProxy.GetOutputPortIndex(idx)) - - def GetPointDataInformation(self): - """Returns the associated point data information.""" - self.UpdatePipeline() - return FieldDataInformation(self.SMProxy, self.Port, "PointData") - - def GetCellDataInformation(self): - """Returns the associated cell data information.""" - self.UpdatePipeline() - return FieldDataInformation(self.SMProxy, self.Port, "CellData") - - def GetFieldDataInformation(self): - """Returns the associated cell data information.""" - self.UpdatePipeline() - return FieldDataInformation(self.SMProxy, self.Port, "FieldData") - - PointData = property(GetPointDataInformation, None, None, "Returns point data information") - CellData = property(GetCellDataInformation, None, None, "Returns cell data information") - FieldData = property(GetFieldDataInformation, None, None, "Returns field data information") - - -class ExodusIIReaderProxy(SourceProxy): - """Special class to define convenience functions for array - selection.""" - - def FileNameChanged(self): - "Called when the filename changes. Selects all variables." - SourceProxy.FileNameChanged(self) - self.SelectAllVariables() - - def SelectAllVariables(self): - "Select all available variables for reading." - for prop in ('PointVariables', 'EdgeVariables', 'FaceVariables', - 'ElementVariables', 'GlobalVariables'): - f = getattr(self, prop) - f.SelectAll() - - def DeselectAllVariables(self): - "Deselects all variables." - for prop in ('PointVariables', 'EdgeVariables', 'FaceVariables', - 'ElementVariables', 'GlobalVariables'): - f = getattr(self, prop) - f.DeselectAll() - -class ViewLayoutProxy(Proxy): - """Special class to define convenience methods for View Layout""" - - def SplitViewHorizontal(self, view, fraction=0.5): - """Split the cell containing the specified view horizontally. - If no fraction is specified, the frame is split into equal parts. - On success returns a positve number that identifying the new cell - location that can be used to assign view to, or split further. - Return -1 on failure.""" - location = self.GetViewLocation(view) - if location == -1: - raise RuntimeError, "View is not present in this layout." - if fraction < 0.0 or fraction > 1.0: - raise RuntimeError, "'fraction' must be in the range [0.0, 1.0]" - return self.SMProxy.SplitHorizontal(location, fraction) - - def SplitViewVertical(self, view=None, fraction=0.5): - """Split the cell containing the specified view horizontally. - If no view is specified, active view is used. - If no fraction is specified, the frame is split into equal parts. - On success returns a positve number that identifying the new cell - location that can be used to assign view to, or split further. - Return -1 on failure.""" - location = self.GetViewLocation(view) - if location == -1: - raise RuntimeError, "View is not present in this layout." - if fraction < 0.0 or fraction > 1.0: - raise RuntimeError, "'fraction' must be in the range [0.0, 1.0]" - return self.SMProxy.SplitVertical(location, fraction) - - def AssignView(self, location, view): - """Assign a view at a particular location. Note that the view's position may - be changed by subsequent Split() calls. Returns true on success.""" - viewproxy = None - if isinstance(view, Proxy): - view = view.SMProxy - return self.SMProxy.AssignView(location, view) - - def GetViewLocation(self, view): - if isinstance(view, Proxy): - view = view.SMProxy - return self.SMProxy.GetViewLocation(view) - -class Property(object): - """Generic property object that provides access to one of the properties of - a server object. This class does not allow setting/getting any values but - provides an interface to update a property using __call__. This can be used - for command properties that correspond to function calls without arguments. - For example, - > proxy.Foo() - would push a Foo property which may cause the proxy to call a Foo method - on the actual VTK object. - - For advanced users: - Python wrapper around a vtkSMProperty with a simple interface. - In addition to all method provided by vtkSMProperty (obtained by - forwarding unknown attributes requests to the underlying SMProxy), - Property and sub-class provide a list API. - - Please note that some of the methods accessible through the Property - class are not listed by help() because the Property objects forward - unresolved attributes to the underlying object. To get the full list, - see also dir(proxy.SMProperty). See also the doxygen based documentation - of the vtkSMProperty C++ class. - """ - def __init__(self, proxy, smproperty): - """Default constructor. Stores a reference to the proxy.""" - import weakref - self.SMProperty = smproperty - self.Proxy = proxy - - def __repr__(self): - """Returns a string representation containing property name - and value""" - if not type(self) is Property: - if self.GetData() is not None: - repr = self.GetData().__repr__() - else: - repr = "None" - else: - repr = "Property name= " - name = self.Proxy.GetPropertyName(self.SMProperty) - if name: - repr += name - else: - repr += "Unknown" - - return repr - - def __call__(self): - """Forces a property update using InvokeCommand.""" - if type(self) is Property: - self.Proxy.SMProxy.InvokeCommand(self._FindPropertyName()) - else: - raise RuntimeError, "Cannot invoke this property" - - def _FindPropertyName(self): - "Returns the name of this property." - return self.Proxy.GetPropertyName(self.SMProperty) - - def _UpdateProperty(self): - "Pushes the value of this property to the server." - # For now, we are updating all properties. This is due to an - # issue with the representations. Their VTK objects are not - # created until Input is set therefore, updating a property - # has no effect. Updating all properties everytime one is - # updated has the effect of pushing values set before Input - # when Input is updated. - # self.Proxy.SMProxy.UpdateProperty(self._FindPropertyName()) - self.Proxy.SMProxy.UpdateVTKObjects() - - def __getattr__(self, name): - "Unknown attribute requests get forwarded to SMProperty." - return getattr(self.SMProperty, name) - - Name = property(_FindPropertyName, None, None, - "Returns the name for the property") - -class GenericIterator(object): - """Iterator for container type objects""" - - def __init__(self, obj): - self.Object = obj - self.index = 0 - - def __iter__(self): - return self - - def next(self): - if self.index >= len(self.Object): - raise StopIteration - - idx = self.index - self.index += 1 - return self.Object[idx] - -class VectorProperty(Property): - """A VectorProperty provides access to one or more values. You can use - a slice to get one or more property values: - > val = property[2] - or - > vals = property[0:5:2] - You can use a slice to set one or more property values: - > property[2] = val - or - > property[1:3] = (1,2) - """ - def ConvertValue(self, value): - return value - - def __len__(self): - """Returns the number of elements.""" - return self.SMProperty.GetNumberOfElements() - - def __iter__(self): - """Implementation of the sequence API""" - return GenericIterator(self) - - def __setitem__(self, idx, value): - """Given a list or tuple of values, sets a slice of values [min, max)""" - if isinstance(idx, slice): - indices = idx.indices(len(self)) - for i, j in zip(range(*indices), value): - self.SMProperty.SetElement(i, self.ConvertValue(j)) - self._UpdateProperty() - elif idx >= len(self) or idx < 0: - raise IndexError - else: - self.SMProperty.SetElement(idx, self.ConvertValue(value)) - self._UpdateProperty() - - def GetElement(self, index): - return self.SMProperty.GetElement(index) - - def __getitem__(self, idx): - """Returns the range [min, max) of elements. Raises an IndexError - exception if an argument is out of bounds.""" - ls = len(self) - if isinstance(idx, slice): - indices = idx.indices(ls) - retVal = [] - for i in range(*indices): - retVal.append(self.GetElement(i)) - return retVal - elif idx >= ls: - raise IndexError - elif idx < 0: - idx = ls + idx - if idx < 0: - raise IndexError - - return self.GetElement(idx) - - def GetData(self): - "Returns all elements as either a list or a single value." - property = self.SMProperty - if property.GetRepeatable() or \ - property.GetNumberOfElements() > 1: - return self[0:len(self)] - elif property.GetNumberOfElements() == 1: - return self.GetElement(0) - - def SetData(self, values): - """Allows setting of all values at once. Requires a single value or - a iterable object.""" - if not hasattr(values, "__iter__"): - values = (values,) - if not self.GetRepeatable() and len(values) != self.GetNumberOfElements(): - raise RuntimeError("This property requires %d values." % self.GetNumberOfElements()) - if self.GetRepeatable(): - # Clean up first - self.SMProperty.SetNumberOfElements(0) - idx = 0 - for val in values: - self.SMProperty.SetElement(idx, self.ConvertValue(val)) - idx += 1 - self._UpdateProperty() - - def Clear(self): - "Removes all elements." - self.SMProperty().SetNumberOfElements(0) - self._UpdateProperty() - -class ColorArrayProperty(VectorProperty): - """This subclass of VectorProperty handles setting of the array to - color by. It handles attribute type as well as well array name.""" - - def GetAvailable(self): - """Returns the list of available arrays as (attribute type, array name - tuples.""" - arrays = [] - for a in self.Proxy.Input.PointData: - arrays.append(('POINT_DATA', a.GetName())) - for a in self.Proxy.Input.CellData: - arrays.append(('CELL_DATA', a.GetName())) - return arrays - - def SetData(self, value): - """Overwritten to enable setting attribute type (the ColorAttributeType - property and the array name. The argument should be the array name - (in which case the first appropriate attribute type is picked) or - a tuple of attribute type and array name.""" - if isinstance(value, tuple) and len(value) == 2: - att = value[0] - arr = value[1] - elif isinstance(value, str): - att = None - arr = value - else: - raise ValueError("Expected a tuple of 2 values or a string.") - - if not arr: - self.SMProperty.SetElement(0, '') - self._UpdateProperty() - return - - found = False - for a in self.Available: - if a[1] == arr and (not att or att == a[0]): - att = a[0] - found = True - break - - if not found: - pvoptions = vtkProcessModule.GetProcessModule().GetOptions() - # if this process is from a parallel batch run in symmetric mpi mode - # then we may not have any points or cells on some processes in which - # case we'll probably be missing the point and cell data too. the - # check below makes sure that we avoid this situation. - if pvoptions.GetProcessType() != 0x40 or pvoptions.GetSymmetricMPIMode() == False \ - or len(self.Available) != 0: - raise ValueError("Could not locate array %s in the input." % arr) - - catt = self.Proxy.GetProperty("ColorAttributeType") - if att != None: - catt.SetData(att) - self.SMProperty.SetElement(0, arr) - self._UpdateProperty() - - Available = property(GetAvailable, None, None, \ - "This read-only property returns the list of arrays that can be colored by.") - - -class EnumerationProperty(VectorProperty): - """Subclass of VectorProperty that is applicable for enumeration type - properties.""" - - def GetElement(self, index): - """Returns the text for the given element if available. Returns - the numerical values otherwise.""" - val = self.SMProperty.GetElement(index) - domain = self.SMProperty.GetDomain("enum") - for i in range(domain.GetNumberOfEntries()): - if domain.GetEntryValue(i) == val: - return domain.GetEntryText(i) - return val - - def ConvertValue(self, value): - """Converts value to type suitable for vtSMProperty::SetElement()""" - if type(value) == str: - domain = self.SMProperty.GetDomain("enum") - if domain.HasEntryText(value): - return domain.GetEntryValueForText(value) - else: - raise ValueError("%s is not a valid value." % value) - return VectorProperty.ConvertValue(self, value) - - def GetAvailable(self): - "Returns the list of available values for the property." - retVal = [] - domain = self.SMProperty.GetDomain("enum") - for i in range(domain.GetNumberOfEntries()): - retVal.append(domain.GetEntryText(i)) - return retVal - - Available = property(GetAvailable, None, None, \ - "This read-only property contains the list of values that can be applied to this property.") - - -class FileNameProperty(VectorProperty): - """Property to set/get one or more file names. - This property updates the pipeline information everytime its value changes. - This is used to keep the array lists up to date.""" - - def _UpdateProperty(self): - "Pushes the value of this property to the server." - VectorProperty._UpdateProperty(self) - self.Proxy.FileNameChanged() - -class ArraySelectionProperty(VectorProperty): - "Property to select an array to be processed by a filter." - - def GetAssociation(self): - val = self.GetElement(3) - if val == "": - return None - for key, value in ASSOCIATIONS.iteritems(): - if value == int(val): - return key - - return None - - def GetArrayName(self): - return self.GetElement(4) - - def __len__(self): - """Returns the number of elements.""" - return 2 - - def __setitem__(self, idx, value): - raise RuntimeError, "This property cannot be accessed using __setitem__" - - def __getitem__(self, idx): - """Returns attribute type for index 0, array name for index 1""" - if isinstance(idx, slice): - indices = idx.indices(len(self)) - retVal = [] - for i in range(*indices): - if i >= 2 or i < 0: - raise IndexError - if i == 0: - retVal.append(self.GetAssociation()) - else: - retVal.append(self.GetArrayName()) - return retVal - elif idx >= 2 or idx < 0: - raise IndexError - - if i == 0: - return self.GetAssociation() - else: - return self.GetArrayName() - - def SetData(self, values): - """Allows setting of all values at once. Requires a single value, - a tuple or list.""" - if not isinstance(values, tuple) and \ - not isinstance(values, list): - values = (values,) - if len(values) == 1: - self.SMProperty.SetElement(4, values[0]) - elif len(values) == 2: - if isinstance(values[0], str): - val = str(ASSOCIATIONS[values[0]]) - else: - # In case user didn't specify valid association, - # just pick POINTS. - val = str(ASSOCIATIONS['POINTS']) - self.SMProperty.SetElement(3, str(val)) - self.SMProperty.SetElement(4, values[1]) - else: - raise RuntimeError, "Expected 1 or 2 values." - self._UpdateProperty() - - def UpdateDefault(self): - "Helper method to set default values." - if self.SMProperty.GetNumberOfElements() != 5: - return - if self.GetElement(4) != '' or \ - self.GetElement(3) != '': - return - - for i in range(0,3): - if self.GetElement(i) == '': - self.SMProperty.SetElement(i, '0') - al = self.SMProperty.GetDomain("array_list") - al.Update(self.SMProperty) - al.SetDefaultValues(self.SMProperty) - -class ArrayListProperty(VectorProperty): - """This property provides a simpler interface for selecting arrays. - Simply assign a list of arrays that should be loaded by the reader. - Use the Available property to get a list of available arrays.""" - - def __init__(self, proxy, smproperty): - VectorProperty.__init__(self, proxy, smproperty) - self.__arrays = [] - - def GetAvailable(self): - "Returns the list of available arrays" - dm = self.GetDomain("array_list") - retVal = [] - for i in range(dm.GetNumberOfStrings()): - retVal.append(dm.GetString(i)) - return retVal - - Available = property(GetAvailable, None, None, \ - "This read-only property contains the list of items that can be read by a reader.") - - def SelectAll(self): - "Selects all arrays." - self.SetData(self.Available) - - def DeselectAll(self): - "Deselects all arrays." - self.SetData([]) - - def __iter__(self): - """Implementation of the sequence API""" - return GenericIterator(self) - - def __len__(self): - """Returns the number of elements.""" - return len(self.GetData()) - - def __setitem__(self, idx, value): - """Given a list or tuple of values, sets a slice of values [min, max)""" - self.GetData() - if isinstance(idx, slice): - indices = idx.indices(len(self)) - for i, j in zip(range(*indices), value): - self.__arrays[i] = j - self.SetData(self.__arrays) - elif idx >= len(self) or idx < 0: - raise IndexError - else: - self.__arrays[idx] = self.ConvertValue(value) - self.SetData(self.__arrays) - - def __getitem__(self, idx): - """Returns the range [min, max) of elements. Raises an IndexError - exception if an argument is out of bounds.""" - self.GetData() - if isinstance(idx, slice): - indices = idx.indices(len(self)) - retVal = [] - for i in range(*indices): - retVal.append(self.__arrays[i]) - return retVal - elif idx >= len(self) or idx < 0: - raise IndexError - return self.__arrays[idx] - - def SetData(self, values): - """Allows setting of all values at once. Requires a single value, - a tuple or list.""" - # Clean up first - iup = self.SMProperty.GetImmediateUpdate() - self.SMProperty.SetImmediateUpdate(False) - # Clean up first - self.SMProperty.SetNumberOfElements(0) - if not isinstance(values, tuple) and \ - not isinstance(values, list): - values = (values,) - fullvalues = [] - - # WARNING: - # The order of the two loops below are delibrately set in this way - # so that values passed in will take precedence. - # This is needed for backward compatibility of the - # property ElementBlocks for vtkExodusIIReader. - # If you attemp to change this, please verify that - # python state files for opening old .ex2 file (<=3.14) still works. - for array in self.Available: - if not values.__contains__(array): - fullvalues.append(array) - fullvalues.append('0') - - for i in range(len(values)): - val = self.ConvertValue(values[i]) - fullvalues.append(val) - fullvalues.append('1') - - - i = 0 - for value in fullvalues: - self.SMProperty.SetElement(i, value) - i += 1 - - self._UpdateProperty() - self.SMProperty.SetImmediateUpdate(iup) - - def GetData(self): - "Returns all elements as a list." - property = self.SMProperty - nElems = property.GetNumberOfElements() - if nElems%2 != 0: - raise ValueError, "The SMProperty with XML label '%s' has a size that is not a multiple of 2." % property.GetXMLLabel() - self.__arrays = [] - for i in range(0, nElems, 2): - if self.GetElement(i+1) != '0': - self.__arrays.append(self.GetElement(i)) - return list(self.__arrays) - -class ProxyProperty(Property): - """A ProxyProperty provides access to one or more proxies. You can use - a slice to get one or more property values: - > proxy = property[2] - or - > proxies = property[0:5:2] - You can use a slice to set one or more property values: - > property[2] = proxy - or - > property[1:3] = (proxy1, proxy2) - You can also append and delete: - > property.append(proxy) - and - > del property[1:2] - - You can also remove all elements with Clear(). - - Note that some properties expect only 1 proxy and will complain if - you set the number of values to be something else. - """ - def __init__(self, proxy, smproperty): - """Default constructor. Stores a reference to the proxy. Also looks - at domains to find valid values.""" - Property.__init__(self, proxy, smproperty) - # Check to see if there is a proxy list domain and, if so, - # initialize ourself. (Should this go in ProxyProperty?) - listdomain = self.GetDomain('proxy_list') - if listdomain: - if listdomain.GetClassName() != 'vtkSMProxyListDomain': - raise ValueError, "Found a 'proxy_list' domain on an InputProperty that is not a ProxyListDomain." - pm = ProxyManager() - group = "pq_helper_proxies." + proxy.GetGlobalIDAsString() - if listdomain.GetNumberOfProxies() == 0: - for i in xrange(listdomain.GetNumberOfProxyTypes()): - igroup = listdomain.GetProxyGroup(i) - name = listdomain.GetProxyName(i) - iproxy = CreateProxy(igroup, name) - listdomain.AddProxy(iproxy) - pm.RegisterProxy(group, proxy.GetPropertyName(smproperty), iproxy) - listdomain.SetDefaultValues(self.SMProperty) - - def GetAvailable(self): - """If this proxy has a list domain, then this function returns the - strings you can use to select from the domain. If there is no such - list domain, the returned list is empty.""" - listdomain = self.GetDomain('proxy_list') - retval = [] - if listdomain: - for i in xrange(listdomain.GetNumberOfProxies()): - proxy = listdomain.GetProxy(i) - retval.append(proxy.GetXMLLabel()) - return retval - - Available = property(GetAvailable, None, None, - """This read only property is a list of strings you can - use to select from the list domain. If there is no - such list domain, the array is empty.""") - - def __iter__(self): - """Implementation of the sequence API""" - return GenericIterator(self) - - def __len__(self): - """Returns the number of elements.""" - return self.SMProperty.GetNumberOfProxies() - - def remove(self, proxy): - """Removes the first occurence of the proxy from the property.""" - self.SMProperty.RemoveProxy(proxy.SMProxy) - self._UpdateProperty() - - def __setitem__(self, idx, value): - """Given a list or tuple of values, sets a slice of values [min, max)""" - if isinstance(idx, slice): - indices = idx.indices(len(self)) - for i, j in zip(range(*indices), value): - self.SMProperty.SetProxy(i, j.SMProxy) - self._UpdateProperty() - elif idx >= len(self) or idx < 0: - raise IndexError - else: - self.SMProperty.SetProxy(idx, value.SMProxy) - self._UpdateProperty() - - def __delitem__(self,idx): - """Removes the element idx""" - if isinstance(idx, slice): - indices = idx.indices(len(self)) - # Collect the elements to delete to a new list first. - # Otherwise indices are screwed up during the actual - # remove loop. - toremove = [] - for i in range(*indices): - toremove.append(self[i]) - for i in toremove: - self.SMProperty.RemoveProxy(i.SMProxy) - self._UpdateProperty() - elif idx >= len(self) or idx < 0: - raise IndexError - else: - self.SMProperty.RemoveProxy(self[idx].SMProxy) - self._UpdateProperty() - - def __getitem__(self, idx): - """Returns the range [min, max) of elements. Raises an IndexError - exception if an argument is out of bounds.""" - if isinstance(idx, slice): - indices = idx.indices(len(self)) - retVal = [] - for i in range(*indices): - retVal.append(_getPyProxy(self.SMProperty.GetProxy(i))) - return retVal - elif idx >= len(self) or idx < 0: - raise IndexError - return _getPyProxy(self.SMProperty.GetProxy(idx)) - - def __getattr__(self, name): - "Unknown attribute requests get forwarded to SMProperty." - return getattr(self.SMProperty, name) - - def index(self, proxy): - idx = 0 - for px in self: - ## VSV: == - if proxy.IsSame(px): - return idx - idx += 1 - raise ValueError("proxy is not in the list.") - - def append(self, proxy): - "Appends the given proxy to the property values." - self.SMProperty.AddProxy(proxy.SMProxy) - self._UpdateProperty() - - def GetData(self): - "Returns all elements as either a list or a single value." - property = self.SMProperty - if property.GetRepeatable() or property.GetNumberOfProxies() > 1: - return self[0:len(self)] - else: - if property.GetNumberOfProxies() > 0: - return _getPyProxy(property.GetProxy(0)) - return None - - def SetData(self, values): - """Allows setting of all values at once. Requires a single value, - a tuple or list.""" - if isinstance(values, str): - position = -1 - try: - position = self.Available.index(values) - except: - raise ValueError, values + " is not a valid object in the domain." - values = self.GetDomain('proxy_list').GetProxy(position) - if not isinstance(values, tuple) and \ - not isinstance(values, list): - values = (values,) - self.SMProperty.RemoveAllProxies() - for value in values: - if isinstance(value, Proxy): - value_proxy = value.SMProxy - else: - value_proxy = value - self.SMProperty.AddProxy(value_proxy) - self._UpdateProperty() - - def Clear(self): - "Removes all elements." - self.SMProperty.RemoveAllProxies() - self._UpdateProperty() - -class InputProperty(ProxyProperty): - """An InputProperty allows making pipeline connections. You can set either - a source proxy or an OutputProperty to an input property: - - > property[0] = proxy - or - > property[0] = OuputPort(proxy, 1) - - > property.append(proxy) - or - > property.append(OutputPort(proxy, 0)) - """ - def __setitem__(self, idx, value): - """Given a list or tuple of values, sets a slice of values [min, max)""" - if isinstance(idx, slice): - indices = idx.indices(len(self)) - for i, j in zip(range(*indices), value): - op = value[i-min] - self.SMProperty.SetInputConnection(i, op.SMProxy, op.Port) - self._UpdateProperty() - elif idx >= len(self) or idx < 0: - raise IndexError - else: - self.SMProperty.SetInputConnection(idx, value.SMProxy, value.Port) - self._UpdateProperty() - - def __getitem__(self, idx): - """Returns the range [min, max) of elements. Raises an IndexError - exception if an argument is out of bounds.""" - if isinstance(idx, slice): - indices = idx.indices(len(self)) - retVal = [] - for i in range(*indices): - port = None - if self.SMProperty.GetProxy(i): - port = OutputPort(_getPyProxy(self.SMProperty.GetProxy(i)),\ - self.SMProperty.GetOutputPortForConnection(i)) - retVal.append(port) - return retVal - elif idx >= len(self) or idx < 0: - raise IndexError - return OutputPort(_getPyProxy(self.SMProperty.GetProxy(idx)),\ - self.SMProperty.GetOutputPortForConnection(idx)) - - def append(self, value): - """Appends the given proxy to the property values. - Accepts Proxy or OutputPort objects.""" - self.SMProperty.AddInputConnection(value.SMProxy, value.Port) - self._UpdateProperty() - - def GetData(self): - """Returns all elements as either a list of OutputPort objects or - a single OutputPort object.""" - property = self.SMProperty - if property.GetRepeatable() or property.GetNumberOfProxies() > 1: - return self[0:len(self)] - else: - if property.GetNumberOfProxies() > 0: - return OutputPort(_getPyProxy(property.GetProxy(0)),\ - self.SMProperty.GetOutputPortForConnection(0)) - return None - - def SetData(self, values): - """Allows setting of all values at once. Requires a single value, - a tuple or list. Accepts Proxy or OutputPort objects.""" - if isinstance(values, str): - ProxyProperty.SetData(self, values) - return - if not isinstance(values, tuple) and \ - not isinstance(values, list): - values = (values,) - self.SMProperty.RemoveAllProxies() - for value in values: - if value: - self.SMProperty.AddInputConnection(value.SMProxy, value.Port) - self._UpdateProperty() - - def _UpdateProperty(self): - "Pushes the value of this property to the server." - ProxyProperty._UpdateProperty(self) - iter = PropertyIterator(self.Proxy) - for prop in iter: - if isinstance(prop, ArraySelectionProperty): - prop.UpdateDefault() - - -class DataInformation(object): - """DataInformation is a contained for meta-data associated with an - output data. - - DataInformation is a python wrapper around a vtkPVDataInformation. - In addition to proving all methods of a vtkPVDataInformation, it provides - a few convenience methods. - - Please note that some of the methods accessible through the DataInformation - class are not listed by help() because the DataInformation objects forward - unresolved attributes to the underlying object. To get the full list, - see also dir(proxy.DataInformation). - See also the doxygen based documentation of the vtkPVDataInformation C++ - class. - """ - def __init__(self, dataInformation, proxy, idx): - """Default constructor. Requires a vtkPVDataInformation, a source proxy - and an output port id.""" - self.DataInformation = dataInformation - self.Proxy = proxy - self.Idx = idx - - def Update(self): - """****Deprecated**** There is no reason anymore to use this method - explicitly, it is called automatically when one gets any value from the - data information object. - Update the data information if necessary. Note that this - does not cause execution of the underlying object. In certain - cases, you may have to call UpdatePipeline() on the proxy.""" - if self.Proxy: - self.Proxy.GetDataInformation(self.Idx) - - def GetDataSetType(self): - """Returns the dataset type as defined in vtkDataObjectTypes.""" - self.Update() - if not self.DataInformation: - raise RuntimeError, "No data information is available" - if self.DataInformation.GetCompositeDataSetType() > -1: - return self.DataInformation.GetCompositeDataSetType() - return self.DataInformation.GetDataSetType() - - def GetDataSetTypeAsString(self): - """Returns the dataset type as a user-friendly string. This is - not the same as the enumaration used by VTK""" - return vtk.vtkDataObjectTypes.GetClassNameFromTypeId(self.GetDataSetType()) - - def __getattr__(self, name): - """Forwards unknown attribute requests to the underlying - vtkPVInformation.""" - if not self.DataInformation: - raise AttributeError("class has no attribute %s" % name) - return None - self.Update() - return getattr(self.DataInformation, name) - -class ArrayInformation(object): - """Meta-information associated with an array. Use the Name - attribute to get the array name. - - Please note that some of the methods accessible through the ArrayInformation - class are not listed by help() because the ArrayInformation objects forward - unresolved attributes to the underlying object. - See the doxygen based documentation of the vtkPVArrayInformation C++ - class for a full list. - """ - def __init__(self, proxy, field, name): - self.Proxy = proxy - self.FieldData = field - self.Name = name - - def __getattr__(self, name): - """Forward unknown methods to vtkPVArrayInformation""" - array = self.FieldData.GetFieldData().GetArrayInformation(self.Name) - if not array: return None - return getattr(array, name) - - def __repr__(self): - """Returns a user-friendly representation string.""" - return "Array: " + self.Name - - def GetRange(self, component=0): - """Given a component, returns its value range as a tuple of 2 values.""" - array = self.FieldData.GetFieldData().GetArrayInformation(self.Name) - range = array.GetComponentRange(component) - return (range[0], range[1]) - -class FieldDataInformationIterator(object): - """Iterator for FieldDataInformation""" - - def __init__(self, info, items=False): - self.FieldDataInformation = info - self.index = 0 - self.items = items - - def __iter__(self): - return self - - def next(self): - if self.index >= self.FieldDataInformation.GetNumberOfArrays(): - raise StopIteration - - self.index += 1 - ai = self.FieldDataInformation[self.index-1] - if self.items: - return (ai.GetName(), ai) - else: - return ai - - -class FieldDataInformation(object): - """Meta-data for a field of an output object (point data, cell data etc...). - Provides easy access to the arrays using the slice interface: - > narrays = len(field_info) - > for i in range(narrays): - > array_info = field_info[i] - - Full slice interface is supported: - > arrays = field_info[0:5:3] - where arrays is a list. - - Array access by name is also possible: - > array_info = field_info['Temperature'] - - The number of arrays can also be accessed using the NumberOfArrays - property. - """ - def __init__(self, proxy, idx, field): - self.Proxy = proxy - self.OutputPort = idx - self.FieldData = field - - def GetFieldData(self): - """Convenience method to get the underlying - vtkPVDataSetAttributesInformation""" - return getattr(self.Proxy.GetDataInformation(self.OutputPort), "Get%sInformation" % self.FieldData)() - - def GetNumberOfArrays(self): - """Returns the number of arrays.""" - self.Proxy.UpdatePipeline() - return self.GetFieldData().GetNumberOfArrays() - - def GetArray(self, idx): - """Given an index or a string, returns an array information. - Raises IndexError if the index is out of bounds.""" - self.Proxy.UpdatePipeline() - if not self.GetFieldData().GetArrayInformation(idx): - return None - if isinstance(idx, str): - return ArrayInformation(self.Proxy, self, idx) - elif idx >= len(self) or idx < 0: - raise IndexError - return ArrayInformation(self.Proxy, self, self.GetFieldData().GetArrayInformation(idx).GetName()) - - def __len__(self): - """Returns the number of arrays.""" - return self.GetNumberOfArrays() - - def __getitem__(self, idx): - """Implements the [] operator. Accepts an array name.""" - if isinstance(idx, slice): - indices = idx.indices(self.GetNumberOfArrays()) - retVal = [] - for i in range(*indices): - retVal.append(self.GetArray(i)) - return retVal - return self.GetArray(idx) - - def keys(self): - """Implementation of the dictionary API""" - kys = [] - narrays = self.GetNumberOfArrays() - for i in range(narrays): - kys.append(self.GetArray(i).GetName()) - return kys - - def values(self): - """Implementation of the dictionary API""" - vals = [] - narrays = self.GetNumberOfArrays() - for i in range(narrays): - vals.append(self.GetArray(i)) - return vals - - def iteritems(self): - """Implementation of the dictionary API""" - return FieldDataInformationIterator(self, True) - - def items(self): - """Implementation of the dictionary API""" - itms = [] - narrays = self.GetNumberOfArrays() - for i in range(narrays): - ai = self.GetArray(i) - itms.append((ai.GetName(), ai)) - return itms - - def has_key(self, key): - """Implementation of the dictionary API""" - if self.GetArray(key): - return True - return False - - def __iter__(self): - """Implementation of the dictionary API""" - return FieldDataInformationIterator(self) - - def __getattr__(self, name): - """Forwards unknown attributes to the underlying - vtkPVDataSetAttributesInformation""" - array = self.GetArray(name) - if array: return array - raise AttributeError("class has no attribute %s" % name) - return None - - NumberOfArrays = property(GetNumberOfArrays, None, None, "Returns the number of arrays.") - -def OutputPort(proxy, outputPort=0): - if not Proxy: - return None - if isinstance(outputPort, str): - outputPort = proxy.GetOutputPortIndex(outputPort) - if outputPort >= proxy.GetNumberOfOutputPorts(): - return None - if proxy.Port == outputPort: - return proxy - newinstance = _getPyProxy(proxy.SMProxy, outputPort) - newinstance.Port = outputPort - newinstance._Proxy__Properties = proxy._Proxy__Properties - return newinstance - -class ProxyManager(object): - """When running scripts from the python shell in the ParaView application, - registering proxies with the proxy manager is the only mechanism to - notify the graphical user interface (GUI) that a proxy - exists. Therefore, unless a proxy is registered, it will not show up in - the user interface. Also, the proxy manager is the only way to get - access to proxies created using the GUI. Proxies created using the GUI - are automatically registered under an appropriate group (sources, - filters, representations and views). To get access to these objects, - you can use proxyManager.GetProxy(group, name). The name is the same - as the name shown in the pipeline browser. - - This class is a python wrapper for vtkSMProxyManager. Note that the - underlying vtkSMProxyManager is a singleton. All instances of this - class will refer to the same object. In addition to all methods provided by - vtkSMProxyManager (all unknown attribute requests are forwarded - to the vtkSMProxyManager), this class provides several convenience - methods. - - Please note that some of the methods accessible through the ProxyManager - class are not listed by help() because the ProxyManager objects forwards - unresolved attributes to the underlying object. To get the full list, - see also dir(proxy.SMProxyManager). See also the doxygen based documentation - of the vtkSMProxyManager C++ class. - """ - - def __init__(self, session=None): - """Constructor. Assigned self.SMProxyManager to - vtkSMProxyManager.GetProxyManager().""" - global ActiveConnection - if not session: - session = ActiveConnection.Session - self.SMProxyManager = session.GetSessionProxyManager() - - def RegisterProxy(self, group, name, aProxy): - """Registers a proxy (either SMProxy or proxy) with the - server manager""" - if isinstance(aProxy, Proxy): - self.SMProxyManager.RegisterProxy(group, name, aProxy.SMProxy) - else: - self.SMProxyManager.RegisterProxy(group, name, aProxy) - - def NewProxy(self, group, name): - """Creates a new proxy of given group and name and returns an SMProxy. - Note that this is a server manager object. You should normally create - proxies using the class objects. For example: - obj = servermanager.sources.SphereSource()""" - if not self.SMProxyManager: - return None - aProxy = self.SMProxyManager.NewProxy(group, name, "NULL") - if not aProxy: - return None - aProxy.UnRegister(None) - return aProxy - - def GetProxy(self, group, name): - """Returns a Proxy registered under a group and name""" - if not self.SMProxyManager: - return None - aProxy = self.SMProxyManager.GetProxy(group, name) - if not aProxy: - return None - return _getPyProxy(aProxy) - - def GetPrototypeProxy(self, group, name): - """Returns a prototype proxy given a group and name. This is an - SMProxy. This is a low-level method. You should not normally - have to call it.""" - if not self.SMProxyManager: - return None - aProxy = self.SMProxyManager.GetPrototypeProxy(group, name) - if not aProxy: - return None - return aProxy - - def GetProxiesInGroup(self, groupname): - """Returns a map of proxies in a particular group.""" - proxies = {} - iter = self.NewGroupIterator(groupname) - for aProxy in iter: - proxies[(iter.GetKey(), aProxy.GetGlobalIDAsString())] = aProxy - return proxies - - def UnRegisterProxy(self, groupname, proxyname, aProxy): - """Unregisters a proxy.""" - if not self.SMProxyManager: - return - if aProxy != None and isinstance(aProxy,Proxy): - aProxy = aProxy.SMProxy - if aProxy: - self.SMProxyManager.UnRegisterProxy(groupname, proxyname, aProxy) - - def GetProxies(self, groupname, proxyname): - """Returns all proxies registered under the given group with the - given name. Note that it is possible to register more than one - proxy with the same name in the same group. Because the proxies - are different, there is no conflict. Use this method instead of - GetProxy() if you know that there are more than one proxy registered - with this name.""" - if not self.SMProxyManager: - return [] - collection = vtk.vtkCollection() - result = [] - self.SMProxyManager.GetProxies(groupname, proxyname, collection) - for i in range(0, collection.GetNumberOfItems()): - aProxy = _getPyProxy(collection.GetItemAsObject(i)) - if aProxy: - result.append(aProxy) - - return result - - def __iter__(self): - """Returns a new ProxyIterator.""" - iter = ProxyIterator() - iter.Begin() - return iter - - def NewGroupIterator(self, group_name): - """Returns a ProxyIterator for a group. The resulting object - can be used to traverse the proxies that are in the given - group.""" - iter = self.__iter__() - iter.SetModeToOneGroup() - iter.Begin(group_name) - return iter - - def NewDefinitionIterator(self, groupname=None): - """Returns an iterator that can be used to iterate over - all groups and types of proxies that the proxy manager - can create.""" - iter = None - if groupname != None: - iter = ProxyDefinitionIterator(self.GetProxyDefinitionManager().NewSingleGroupIterator(groupname,0)) - else: - iter = ProxyDefinitionIterator(self.GetProxyDefinitionManager().NewIterator(0)) - - return iter - - def __ConvertArgumentsAndCall(self, *args): - newArgs = [] - for arg in args: - if issubclass(type(arg), Proxy) or isinstance(arg, Proxy): - newArgs.append(arg.SMProxy) - else: - newArgs.append(arg) - func = getattr(self.SMProxyManager, self.__LastAttrName) - retVal = func(*newArgs) - if type(retVal) is type(self.SMProxyManager) and retVal.IsA("vtkSMProxy"): - return _getPyProxy(retVal) - else: - return retVal - - def __getattr__(self, name): - """Returns attribute from the ProxyManager""" - try: - pmAttr = getattr(self.SMProxyManager, name) - self.__LastAttrName = name - return self.__ConvertArgumentsAndCall - except: - pass - return getattr(self.SMProxyManager, name) - - def LoadState(self, filename, loader = None): - self.SMProxyManager.LoadXMLState(filename, loader) - - def SaveState(self, filename): - self.SMProxyManager.SaveXMLState(filename) - -class PropertyIterator(object): - """Wrapper for a vtkSMPropertyIterator class to satisfy - the python iterator protocol. Note that the list of - properties can also be obtained from the class object's - dictionary. - See the doxygen documentation for vtkSMPropertyIterator C++ - class for details. - """ - - def __init__(self, aProxy): - self.SMIterator = aProxy.NewPropertyIterator() - if self.SMIterator: - self.SMIterator.UnRegister(None) - self.SMIterator.Begin() - self.Key = None - self.PropertyLabel = None - self.Proxy = aProxy - - def __iter__(self): - return self - - def next(self): - if not self.SMIterator: - raise StopIteration - - if self.SMIterator.IsAtEnd(): - self.Key = None - raise StopIteration - self.Key = self.SMIterator.GetKey() - self.PropertyLabel = self.SMIterator.GetPropertyLabel() - self.SMIterator.Next() - return self.Proxy.GetProperty(self.Key) - - def GetProxy(self): - """Returns the proxy for the property last returned by the call to - 'next()'""" - return self.Proxy - - def GetKey(self): - """Returns the key for the property last returned by the call to - 'next()' """ - return self.Key - - def GetProperty(self): - """Returns the property last returned by the call to 'next()' """ - return self.Proxy.GetProperty(self.Key) - - def __getattr__(self, name): - """returns attributes from the vtkSMPropertyIterator.""" - return getattr(self.SMIterator, name) - -class ProxyDefinitionIterator(object): - """Wrapper for a vtkPVProxyDefinitionIterator class to satisfy - the python iterator protocol. - See the doxygen documentation of the vtkPVProxyDefinitionIterator - C++ class for more information.""" - def __init__(self, iter): - self.SMIterator = iter - if self.SMIterator: - self.SMIterator.UnRegister(None) - self.SMIterator.InitTraversal() - self.Group = None - self.Key = None - - def __iter__(self): - return self - - def next(self): - if self.SMIterator.IsDoneWithTraversal(): - self.Group = None - self.Key = None - raise StopIteration - self.Group = self.SMIterator.GetGroupName() - self.Key = self.SMIterator.GetProxyName() - self.SMIterator.GoToNextItem() - return {"group": self.Group, "key":self.Key } - - def GetProxyName(self): - """Returns the key for the proxy definition last returned by the call - to 'next()' """ - return self.Key - - def GetGroup(self): - """Returns the group for the proxy definition last returned by the - call to 'next()' """ - return self.Group - - def __getattr__(self, name): - """returns attributes from the vtkPVProxyDefinitionIterator.""" - return getattr(self.SMIterator, name) - - -class ProxyIterator(object): - """Wrapper for a vtkSMProxyIterator class to satisfy the - python iterator protocol. - See the doxygen documentation of vtkSMProxyIterator C++ class for - more information. - """ - def __init__(self): - self.SMIterator = vtkSMProxyIterator() - self.SMIterator.SetSession(ActiveConnection.Session) - self.SMIterator.Begin() - self.AProxy = None - self.Group = None - self.Key = None - - def __iter__(self): - return self - - def next(self): - if self.SMIterator.IsAtEnd(): - self.AProxy = None - self.Group = None - self.Key = None - raise StopIteration - return None - self.AProxy = _getPyProxy(self.SMIterator.GetProxy()) - self.Group = self.SMIterator.GetGroup() - self.Key = self.SMIterator.GetKey() - self.SMIterator.Next() - return self.AProxy - - def GetProxy(self): - """Returns the proxy last returned by the call to 'next()'""" - return self.AProxy - - def GetKey(self): - """Returns the key for the proxy last returned by the call to - 'next()' """ - return self.Key - - def GetGroup(self): - """Returns the group for the proxy last returned by the call to - 'next()' """ - return self.Group - - def __getattr__(self, name): - """returns attributes from the vtkSMProxyIterator.""" - return getattr(self.SMIterator, name) - -# Caution: Observers must be global methods otherwise we run into memory -# leak when the interpreter get reset from the C++ layer. -def _update_definitions(caller, event): - updateModules(ActiveConnection.Modules) - -class Connection(object): - """ - This is a python representation for a session/connection. - """ - def __init__(self, connectionId, session): - """Default constructor. Creates a Connection with the given - ID, all other data members initialized to None.""" - global MultiServerConnections - global ActiveConnection - self.ID = connectionId - self.Session = session - self.Modules = PVModule() - self.Alive = True - self.DefinitionObserverTag = 0 - self.CustomDefinitionObserverTag = 0 - if MultiServerConnections == None and ActiveConnection: - raise RuntimeError, "Concurrent connections not supported!" - if MultiServerConnections != None and not self in MultiServerConnections: - MultiServerConnections.append(self) - ActiveConnection = self - __InitAfterConnect__(self) - __exposeActiveModules__() - - def __eq__(self, other): - "Returns true if the connection ids are the same." - return (self.ID == other.ID) - - def __repr__(self): - """User friendly string representation""" - return "Connection (%s) [%d]" % (self.Session.GetURI(), self.ID) - - def GetURI(self): - """Get URI of the connection""" - return self.Session.GetURI() - - def IsRemote(self): - """Returns True if the connection to a remote server, False if - it is local (built-in)""" - if self.Session.IsA("vtkSMSessionClient"): - return True - return False - - def GetNumberOfDataPartitions(self): - """Returns the number of partitions on the data server for this - connection""" - return self.Session.GetServerInformation().GetNumberOfProcesses() - - def AttachDefinitionUpdater(self): - """Attach observer to automatically update modules when needed.""" - # VTN: Observers are not supported - # ProxyDefinitionsUpdated = 2000 -## self.DefinitionObserverTag = self.Session.GetProxyDefinitionManager().AddObserver(2000, _update_definitions) - # CompoundProxyDefinitionsUpdated = 2001 -## self.CustomDefinitionObserverTag = self.Session.GetProxyDefinitionManager().AddObserver(2001, _update_definitions) - pass - - def close(self): - if self.DefinitionObserverTag: - self.Session.GetProxyDefinitionManager().RemoveObserver(self.DefinitionObserverTag) - self.Session.GetProxyDefinitionManager().RemoveObserver(self.CustomDefinitionObserverTag) - self.Session = None - self.Modules = None - self.Alive = False - - def __del__(self): - if self.Alive: - self.close() - -def SaveState(filename): - """Given a state filename, saves the state of objects registered - with the proxy manager.""" - pm = ProxyManager() - pm.SaveState(filename) - -def LoadState(filename, connection=None): - """Given a state filename and an optional connection, loads the server - manager state.""" - if not connection: - connection = ActiveConnection - if not connection: - raise RuntimeError, "Cannot load state without a connection" - pm = ProxyManager() - pm.LoadState(filename, None) - views = GetRenderViews() - for view in views: - # Make sure that the client window size matches the - # ViewSize property. In paraview, the GUI takes care - # of this. - if view.GetClassName() == "vtkSMIceTDesktopRenderViewProxy": - view.GetRenderWindow().SetSize(view.ViewSize[0], \ - view.ViewSize[1]) - -def InitFromGUI(): - """ - Method used to initialize the Python Shell from the ParaView GUI. - """ - global fromGUI, ActiveConnection -# if not fromGUI: -# print "from paraview.simple import *" - fromGUI = True - # ToggleProgressPrinting() ### FIXME COLLABORATION - enableMultiServer(vtkProcessModule.GetProcessModule().GetMultipleSessionsSupport()) - iter = vtkProcessModule.GetProcessModule().NewSessionIterator(); - iter.InitTraversal() - ActiveConnection = None - activeSession = vtkSMProxyManager.GetProxyManager().GetActiveSession() - tmpActiveConnection = None - while not iter.IsDoneWithTraversal(): - c = Connection(iter.GetCurrentSessionId(), iter.GetCurrentSession()) - if c.Session == activeSession: - tmpActiveConnection = c - iter.GoToNextItem() - iter.UnRegister(None) - if tmpActiveConnection: - ActiveConnection = tmpActiveConnection - -def Connect(ds_host=None, ds_port=11111, rs_host=None, rs_port=22221): - """ - Use this function call to create a new session. On success, - it returns a vtkSMSession object that abstracts the connection. - Otherwise, it returns None. - There are several ways in which this function can be called: - * When called with no arguments, it creates a new session - to the built-in server on the client itself. - * When called with ds_host and ds_port arguments, it - attempts to connect to a server(data and render server on the same server) - on the indicated host:port. - * When called with ds_host, ds_port, rs_host, rs_port, it - creates a new connection to the data server on ds_host:ds_port and to the - render server on rs_host: rs_port. - """ - if ds_host == None: - session = vtkSMSession() - elif rs_host == None: - session = vtkSMSessionClient() - session.Connect("cs://%s:%d" % (ds_host, ds_port)) - else: - session = vtkSMSessionClient() - session.Connect("cdsrs://%s:%d/%s:%d" % (ds_host, ds_port, rs_host, rs_port)) - id = vtkProcessModule.GetProcessModule().RegisterSession(session) - connection = Connection(id, session) - return connection - -def ReverseConnect(port=11111): - """ - Use this function call to create a new session. On success, - it returns a Session object that abstracts the connection. - Otherwise, it returns None. - In reverse connection mode, the client waits for a connection - from the server (client has to be started first). The server - then connects to the client (run pvserver with -rc and -ch - option). - The optional port specified the port to listen to. - """ - session = vtkSMSessionClient() - session.Connect("csrc://hostname:" + port) - id = vtkProcessModule.GetProcessModule().RegisterSession(session) - connection = Connection(id, session) - return connection - -def Disconnect(session=None): - """Disconnects the connection. Make sure to clear the proxy manager - first.""" - global ActiveConnection - global MultiServerConnections - global fromGUI - if fromGUI: - # Let the UI know that we want to disconnect - ActiveConnection.Session.InvokeEvent('ExitEvent') - return - if ActiveConnection and (not session or session == ActiveConnection.Session): - session = ActiveConnection.Session - if MultiServerConnections: - MultiServerConnections.remove(ActiveConnection) - ActiveConnection.close() - ActiveConnection = None - switchActiveConnection() - else: - ActiveConnection.close() - ActiveConnection = None - elif MultiServerConnections: - for connection in MultiServerConnections: - if connection.Session == session: - connection.close() - MultiServerConnections.remove(connection) - if session: - vtkProcessModule.GetProcessModule().UnRegisterSession(session) - return - -def CreateProxy(xml_group, xml_name, session=None): - """Creates a proxy. If session is set, the proxy's session is - set accordingly. If session is None, the current Session is used, if - present. You should not have to use method normally. Instantiate the - appropriate class from the appropriate module, for example: - sph = servermanager.sources.SphereSource()""" - global ActiveConnection - if not session: - session = ActiveConnection.Session - if not session: - raise RuntimeError, "Cannot create objects without a session." - pxm = ProxyManager(session) - return pxm.NewProxy(xml_group, xml_name) - -def GetRenderView(connection=None): - """Return the render view in use. If more than one render view is in - use, return the first one.""" - - render_module = None - for aProxy in ProxyManager(): - if aProxy.IsA("vtkSMRenderViewProxy"): - render_module = aProxy - break - return render_module - -def GetRenderViews(connection=None): - """Returns the set of all render views.""" - render_modules = [] - for aProxy in ProxyManager(): - if aProxy.IsA("vtkSMRenderViewProxy"): - render_modules.append(aProxy) - return render_modules - -def GetContextViews(connection=None): - """Returns the set of all context views.""" - context_modules = [] - for aProxy in ProxyManager(): - if aProxy.IsA("vtkSMContextViewProxy"): - context_modules.append(aProxy) - return context_modules - -def CreateRenderView(session=None, **extraArgs): - """Creates a render window on the particular session. If session - is not specified, then the active session is used, if available. - - This method can also be used to initialize properties by passing - keyword arguments where the key is the name of the property. In addition - registrationGroup and registrationName (optional) can be specified (as - keyword arguments) to automatically register the proxy with the proxy - manager.""" - return _create_view("RenderView", session, **extraArgs) - -def _create_view(view_xml_name, session=None, **extraArgs): - """Creates a view on the particular session. If session - is not specified, then the active session is used, if available. - This method can also be used to initialize properties by passing - keyword arguments where the key is the name of the property.""" - if not session: - session = ActiveConnection.Session - if not session: - raise RuntimeError, "Cannot create view without session." - pxm = ProxyManager() - view_module = None - if view_xml_name: - view_module = CreateProxy("views", view_xml_name, session) - if not view_module: - return None - extraArgs['proxy'] = view_module - python_proxy_name = _make_name_valid(view_module.GetXMLName()) - proxy = rendering.__dict__[python_proxy_name](**extraArgs) - return proxy - -def GetRepresentation(aProxy, view): - for rep in view.Representations: - #VSV: == - try: isRep = rep.Input.IsSame(aProxy) - except: isRep = False - if isRep: return rep - return None - -def CreateRepresentation(aProxy, view, **extraArgs): - """Creates a representation for the proxy and adds it to the render - module. - - This method can also be used to initialize properties by passing - keyword arguments where the key is the name of the property.In addition - registrationGroup and registrationName (optional) can be specified (as - keyword arguments) to automatically register the proxy with the proxy - manager. - - This method tries to create the best possible representation for the given - proxy in the given view. Additionally, the user can specify proxyName - (optional) to create a representation of a particular type.""" - - global rendering - if not aProxy: - raise RuntimeError, "proxy argument cannot be None." - if not view: - raise RuntimeError, "view argument cannot be None." - if "proxyName" in extraArgs: - display = CreateProxy("representations", extraArgs['proxyName'], None) - del extraArgs['proxyName'] - else: - display = view.SMProxy.CreateDefaultRepresentation(aProxy.SMProxy, 0) - if display: - display.UnRegister(None) - if not display: - return None - extraArgs['proxy'] = display - proxy = rendering.__dict__[display.GetXMLName()](**extraArgs) - proxy.Input = aProxy - proxy.UpdateVTKObjects() - view.Representations.append(proxy) - return proxy - -class _ModuleLoader(object): - def find_module(self, fullname, path=None): - if vtkPVPythonModule.HasModule(fullname): - return self - else: - return None - def load_module(self, fullname): - import imp - moduleInfo = vtkPVPythonModule.GetModule(fullname) - if not moduleInfo: - raise ImportError - module = sys.modules.setdefault(fullname, imp.new_module(fullname)) - module.__file__ = "<%s>" % moduleInfo.GetFullName() - module.__loader__ = self - if moduleInfo.GetIsPackage: - module.__path__ = moduleInfo.GetFullName() - code = compile(moduleInfo.GetSource(), module.__file__, 'exec') - exec code in module.__dict__ - return module - -def LoadXML(xmlstring): - """DEPRECATED. Given a server manager XML as a string, parse and process it.""" - raise RuntimeError, "Deprecated. Use LoadPlugin(...) instead." - - -def LoadPlugin(filename, remote=True, connection=None): - """ Given a filename and a session (optional, otherwise uses - ActiveConnection), loads a plugin. It then updates the sources, - filters and rendering modules.""" - - if not connection: - connection = ActiveConnection - if not connection: - raise RuntimeError, "Cannot load a plugin without a connection." - plm = vtkSMProxyManager.GetProxyManager().GetPluginManager() - - if remote: - status = plm.LoadRemotePlugin(filename, connection.Session) - else: - status = plm.LoadLocalPlugin(filename) - - # shouldn't the extension check happend before attempting to load the plugin? - if not status: - raise RuntimeError, "Problem loading plugin %s" % (filename) - else: - # we should never have to call this. The modules should update automatically. - updateModules(connection.Modules) - - -def Fetch(input, arg1=None, arg2=None, idx=0): - """ - A convenience method that moves data from the server to the client, - optionally performing some operation on the data as it moves. - The input argument is the name of the (proxy for a) source or filter - whose output is needed on the client. - - You can use Fetch to do three things: - - If arg1 is None (the default) then all of the data is brought to the client. - In parallel runs an appropriate append Filter merges the - data on each processor into one data object. The filter chosen will be - vtkAppendPolyData for vtkPolyData, vtkAppendRectilinearGrid for - vtkRectilinearGrid, vtkMultiBlockDataGroupFilter for vtkCompositeData, - and vtkAppendFilter for anything else. - - If arg1 is an integer then one particular processor's output is brought to - the client. In serial runs the arg is ignored. If you have a filter that - computes results in parallel and brings them to the root node, then set - arg to be 0. - - If arg1 and arg2 are a algorithms, for example vtkMinMax, the algorithm - will be applied to the data to obtain some result. Here arg1 will be - applied pre-gather and arg2 will be applied post-gather. In parallel - runs the algorithm will be run on each processor to make intermediate - results and then again on the root processor over all of the - intermediate results to create a global result. - - Optional argument idx is used to specify the output port number to fetch the - data from. Default is port 0. - """ - - import types - - reducer = filters.ReductionFilter(Input=OutputPort(input,idx)) - - #create the pipeline that reduces and transmits the data - if arg1 == None: - cdinfo = input.GetDataInformation(idx).GetCompositeDataInformation() - if cdinfo.GetDataIsComposite(): - print "use composite data append" - reducer.PostGatherHelperName = "vtkMultiBlockDataGroupFilter" - - elif input.GetDataInformation(idx).GetDataClassName() == "vtkPolyData": - print "use append poly data filter" - reducer.PostGatherHelperName = "vtkAppendPolyData" - - elif input.GetDataInformation(idx).GetDataClassName() == "vtkRectilinearGrid": - print "use append rectilinear grid filter" - reducer.PostGatherHelperName = "vtkAppendRectilinearGrid" - - elif input.GetDataInformation(idx).IsA("vtkDataSet"): - print "use unstructured append filter" - reducer.PostGatherHelperName = "vtkAppendFilter" - - elif type(arg1) is types.IntType: - reducer.PassThrough = arg1 - - else: - reducer.PreGatherHelper = arg1 - reducer.PostGatherHelper = arg2 - - # reduce - reducer.UpdatePipeline() - dataInfo = reducer.GetDataInformation(0) - dataType = dataInfo.GetDataSetType() - if dataInfo.GetCompositeDataSetType() > 0: - dataType = dataInfo.GetCompositeDataSetType() - - fetcher = filters.ClientServerMoveData(Input=reducer) - fetcher.OutputDataType = dataType - fetcher.WholeExtent = dataInfo.GetExtent()[:] - #fetch - fetcher.UpdatePipeline() - - op = fetcher.GetClientSideObject().GetOutputDataObject(0) - opc = op.NewInstance() - opc.ShallowCopy(op) - opc.UnRegister(None) - return opc - -def AnimateReader(reader, view, filename=None): - """This is a utility function that, given a reader and a view - animates over all time steps of the reader. If the optional - filename is provided, a movie is created (type depends on the - extension of the filename.""" - if not reader: - raise RuntimeError, "No reader was specified, cannot animate." - if not view: - raise RuntimeError, "No view was specified, cannot animate." - # Create an animation scene - scene = animation.AnimationScene() - - # We need to have the reader and the view registered with - # the time keeper. This is how the scene gets its time values. - try: - tk = ProxyManager().GetProxiesInGroup("timekeeper").values()[0] - scene.TimeKeeper = tk - except IndexError: - tk = misc.TimeKeeper() - scene.TimeKeeper = tk - - if not reader in tk.TimeSources: - tk.TimeSources.append(reader) - if not view in tk.Views: - tk.Views.append(view) - - - # with 1 view - scene.ViewModules = [view] - # Update the reader to get the time information - reader.UpdatePipelineInformation() - # Animate from 1st time step to last - scene.StartTime = reader.TimestepValues.GetData()[0] - scene.EndTime = reader.TimestepValues.GetData()[-1] - - # Each frame will correspond to a time step - scene.PlayMode = 2 #Snap To Timesteps - - # Create a special animation cue for time. - cue = animation.TimeAnimationCue() - cue.AnimatedProxy = view - cue.AnimatedPropertyName = "ViewTime" - scene.Cues = [cue] - - if filename: - writer = vtkSMAnimationSceneImageWriter() - writer.SetFileName(filename) - writer.SetFrameRate(1) - writer.SetAnimationScene(scene.SMProxy) - - # Now save the animation. - if not writer.Save(): - raise RuntimeError, "Saving of animation failed!" - else: - scene.Play() - return scene - -def GetProgressPrintingIsEnabled(): - return progressObserverTag is not None - -def SetProgressPrintingEnabled(value): - """Is not supported because of not supported observers""" - pass - -def ToggleProgressPrinting(): - """Turn on/off printing of progress. See SetProgressPrintingEnabled.""" - SetProgressPrintingEnabled(not GetProgressPrintingIsEnabled()) - -def Finalize(): - """Although not required, this can be called at exit to cleanup.""" - global progressObserverTag - # Make sure to remove the observer - if progressObserverTag: - ToggleProgressPrinting() - vtkInitializationHelper.Finalize() - -# Internal methods - -def _getPyProxy(smproxy, outputPort=0): - """Returns a python wrapper for a server manager proxy. This method - first checks if there is already such an object by looking in the - _pyproxies group and returns it if found. Otherwise, it creates a - new one. Proxies register themselves in _pyproxies upon creation.""" - if not smproxy: - return None - if (smproxy, outputPort) in _pyproxies: - return _pyproxies[(smproxy, outputPort)]() - - xmlName = smproxy.GetXMLName() - if smproxy.GetXMLLabel(): - xmlName = smproxy.GetXMLLabel() - classForProxy = _findClassForProxy(_make_name_valid(xmlName), smproxy.GetXMLGroup()) - if classForProxy: - retVal = classForProxy(proxy=smproxy, port=outputPort) - else: - retVal = Proxy(proxy=smproxy, port=outputPort) - return retVal - -def _makeUpdateCameraMethod(rv): - """ This internal method is used to create observer methods """ - if not hasattr(rv(), "BlockUpdateCamera"): - rv().add_attribute("BlockUpdateCamera", False) - def UpdateCamera(obj, string): - if not rv().BlockUpdateCamera: - # used to avoid some nasty recursion that occurs when interacting in - # the GUI. - rv().BlockUpdateCamera = True - rv().SynchronizeCameraProperties() - rv().BlockUpdateCamera = False - return UpdateCamera - -def _createInitialize(group, name): - """Internal method to create an Initialize() method for the sub-classes - of Proxy""" - pgroup = group - pname = name - def aInitialize(self, connection=None, update=True): - if not connection: - connection = ActiveConnection - if not connection: - raise RuntimeError,\ - 'Cannot create a proxy without a session.' - if not connection.Session.GetProxyDefinitionManager().HasDefinition(pgroup, pname): - error_msg = "The connection does not provide any definition for %s." % pname - raise RuntimeError, error_msg - self.InitializeFromProxy(\ - CreateProxy(pgroup, pname, connection.Session), update) - return aInitialize - -def _createGetProperty(pName): - """Internal method to create a GetXXX() method where XXX == pName.""" - propName = pName - def getProperty(self): - return self.GetPropertyValue(propName) - return getProperty - -def _createSetProperty(pName): - """Internal method to create a SetXXX() method where XXX == pName.""" - propName = pName - def setProperty(self, value): - return self.SetPropertyWithName(propName, value) - return setProperty - -def _findClassForProxy(xmlName, xmlGroup): - """Given the xmlName for a proxy, returns a Proxy class. Note - that if there are duplicates, the first one is returned.""" - global sources, filters, writers, rendering, animation, implicit_functions,\ - piecewise_functions, extended_sources, misc - if not xmlName: - return None - if xmlGroup == "sources": - return sources.__dict__[xmlName] - elif xmlGroup == "filters": - return filters.__dict__[xmlName] - elif xmlGroup == "implicit_functions": - return implicit_functions.__dict__[xmlName] - elif xmlGroup == "piecewise_functions": - return piecewise_functions.__dict__[xmlName] - elif xmlGroup == "writers": - return writers.__dict__[xmlName] - elif xmlGroup == "extended_sources": - return extended_sources.__dict__[xmlName] - elif xmlName in rendering.__dict__: - return rendering.__dict__[xmlName] - elif xmlName in animation.__dict__: - return animation.__dict__[xmlName] - elif xmlName in misc.__dict__: - return misc.__dict__[xmlName] - else: - return None - -def _printProgress(caller, event): - """The default event handler for progress. Prints algorithm - name and 1 '.' per 10% progress.""" - global currentAlgorithm, currentProgress - - pm = vtkProcessModule.GetProcessModule() - progress = pm.GetLastProgress() / 10 - # If we got a 100% as the first thing, ignore - # This is to get around the fact that some vtk - # algorithms report 100% more than once (which is - # a bug) - if not currentAlgorithm and progress == 10: - return - alg = pm.GetLastProgressName() - if alg != currentAlgorithm and alg: - if currentAlgorithm: - while currentProgress <= 10: - import sys - sys.stdout.write(".") - currentProgress += 1 - print "]" - currentProgress = 0 - print alg, ": [ ", - currentAlgorithm = alg - while currentProgress <= progress: - import sys - sys.stdout.write(".") - #sys.stdout.write("%d " % pm.GetLastProgress()) - currentProgress += 1 - if progress == 10: - print "]" - currentAlgorithm = None - currentProgress = 0 - -def updateModules(m): - """Called when a plugin is loaded, this method updates - the proxy class object in all known modules.""" - - createModule("sources", m.sources) - createModule("filters", m.filters) - createModule("writers", m.writers) - createModule("representations", m.rendering) - createModule("views", m.rendering) - createModule("lookup_tables", m.rendering) - createModule("textures", m.rendering) - createModule('cameramanipulators', m.rendering) - createModule("animation", m.animation) - createModule("misc", m.misc) - createModule('animation_keyframes', m.animation) - createModule('implicit_functions', m.implicit_functions) - createModule('piecewise_functions', m.piecewise_functions) - createModule("extended_sources", m.extended_sources) - createModule("incremental_point_locators", m.misc) - -def _createModules(m): - """Called when the module is loaded, this creates sub- - modules for all know proxy groups.""" - - m.sources = createModule('sources') - m.filters = createModule('filters') - m.writers = createModule('writers') - m.rendering = createModule('representations') - createModule('views', m.rendering) - createModule("lookup_tables", m.rendering) - createModule("textures", m.rendering) - createModule('cameramanipulators', m.rendering) - m.animation = createModule('animation') - createModule('animation_keyframes', m.animation) - m.implicit_functions = createModule('implicit_functions') - m.piecewise_functions = createModule('piecewise_functions') - m.extended_sources = createModule("extended_sources") - m.misc = createModule("misc") - createModule("incremental_point_locators", m.misc) - -class PVModule(object): - pass - -def _make_name_valid(name): - """Make a string into a valid Python variable name.""" - if not name: - return None - import string - valid_chars = "_%s%s" % (string.ascii_letters, string.digits) - name = str().join([c for c in name if c in valid_chars]) - if not name[0].isalpha(): - name = 'a' + name - return name - -def createModule(groupName, mdl=None): - """Populates a module with proxy classes defined in the given group. - If mdl is not specified, it also creates the module""" - global ActiveConnection - - if not ActiveConnection: - raise RuntimeError, "Please connect to a server using \"Connect\"" - - pxm = ProxyManager() - # Use prototypes to find all proxy types. - pxm.InstantiateGroupPrototypes(groupName) - - debug = False - if not mdl: - debug = True - mdl = PVModule() - definitionIter = pxm.NewDefinitionIterator(groupName) - for i in definitionIter: - proxyName = i['key'] - proto = pxm.GetPrototypeProxy(groupName, proxyName) - if not proto: - print "Error while loading %s/%s %s"%(groupName, i['group'], proxyName) - continue - pname = proxyName - if proto.GetXMLLabel(): - pname = proto.GetXMLLabel() - pname = _make_name_valid(pname) - if not pname: - continue - if pname in mdl.__dict__: - if debug: - print "Warning: %s is being overwritten. This may point to an issue in the ParaView configuration files" % pname - cdict = {} - # Create an Initialize() method for this sub-class. - cdict['Initialize'] = _createInitialize(groupName, proxyName) - iter = PropertyIterator(proto) - # Add all properties as python properties. - for prop in iter: - propName = iter.GetKey() - if (prop.GetInformationOnly() and propName != "TimestepValues" ) \ - or prop.GetIsInternal(): - continue - names = [propName] - names = [iter.PropertyLabel] - - propDoc = None - if prop.GetDocumentation(): - propDoc = prop.GetDocumentation().GetDescription() - for name in names: - name = _make_name_valid(name) - if name: - cdict[name] = property(_createGetProperty(propName), - _createSetProperty(propName), - None, - propDoc) - # Add the documentation as the class __doc__ - if proto.GetDocumentation() and \ - proto.GetDocumentation().GetDescription(): - doc = proto.GetDocumentation().GetDescription() - else: - doc = Proxy.__doc__ - cdict['__doc__'] = doc - # Create the new type - if proto.GetXMLName() == "ExodusIIReader": - superclasses = (ExodusIIReaderProxy,) - elif proto.IsA("vtkSMSourceProxy"): - superclasses = (SourceProxy,) - elif proto.IsA("vtkSMViewLayoutProxy"): - superclasses = (ViewLayoutProxy,) - else: - superclasses = (Proxy,) - - cobj = type(pname, superclasses, cdict) - # Add it to the modules dictionary - mdl.__dict__[pname] = cobj - return mdl - - -def __determineGroup(proxy): - """Internal method""" - if not proxy: - return None - xmlgroup = proxy.GetXMLGroup() - xmlname = proxy.GetXMLName() - if xmlgroup == "sources": - if xmlname in ["BlockSelectionSource", - "FrustumSelectionSource", - "GlobalIDSelectionSource", - "PedigreeIDSelectionSource", - "IDSelectionSource", - "CompositeDataIDSelectionSource", - "HierarchicalDataIDSelectionSource", - "ThresholdSelectionSource", - "LocationSelectionSource"]: - return "selection_sources" - return "sources" - elif xmlgroup == "filters": - return "sources" - elif xmlgroup == "representations": - if xmlname == "ScalarBarWidgetRepresentation": - return "scalar_bars" - return "representations" - elif xmlgroup == "animation_keyframes": - return "animation" - return xmlgroup - -__nameCounter = {} -def __determineName(proxy, group): - global __nameCounter - name = _make_name_valid(proxy.GetXMLLabel()) - if not name: - return None - if not __nameCounter.has_key(name): - __nameCounter[name] = 1 - val = 1 - else: - __nameCounter[name] += 1 - val = __nameCounter[name] - return "%s%d" % (name, val) - -def __getName(proxy, group): - pxm = ProxyManager(proxy.GetSession()) - if isinstance(proxy, Proxy): - proxy = proxy.SMProxy - return pxm.GetProxyName(group, proxy) - -class MissingRegistrationInformation(Exception): - """Exception for missing registration information. Raised when a name or group - is not specified or when a group cannot be deduced.""" - pass - -class MissingProxy(Exception): - """Exception fired when the requested proxy is missing.""" - pass - -def Register(proxy, **extraArgs): - """Registers a proxy with the proxy manager. If no 'registrationGroup' is - specified, then the group is inferred from the type of the proxy. - 'registrationName' may be specified to register with a particular name - otherwise a default name will be created.""" - # TODO: handle duplicate registration - if "registrationGroup" in extraArgs: - registrationGroup = extraArgs["registrationGroup"] - else: - registrationGroup = __determineGroup(proxy) - - if "registrationName" in extraArgs: - registrationName = extraArgs["registrationName"] - else: - registrationName = __determineName(proxy, registrationGroup) - if registrationGroup and registrationName: - pxm = ProxyManager() - pxm.RegisterProxy(registrationGroup, registrationName, proxy) - else: - raise MissingRegistrationInformation, "Registration error %s %s." % (registrationGroup, registrationName) - return (registrationGroup, registrationName) - -def UnRegister(proxy, **extraArgs): - """UnRegisters proxies registered using Register().""" - if "registrationGroup" in extraArgs: - registrationGroup = extraArgs["registrationGroup"] - else: - registrationGroup = __determineGroup(proxy) - - if "registrationName" in extraArgs: - registrationName = extraArgs["registrationName"] - else: - registrationName = __getName(proxy, registrationGroup) - - if registrationGroup and registrationName: - pxm = ProxyManager() - pxm.UnRegisterProxy(registrationGroup, registrationName, proxy) - else: - raise RuntimeError, "UnRegistration error." - return (registrationGroup, registrationName) - -def demo1(): - """This simple demonstration creates a sphere, renders it and delivers - it to the client using Fetch. It returns a tuple of (data, render - view)""" - if not ActiveConnection: - Connect() - ss = sources.Sphere(Radius=2, ThetaResolution=32) - shr = filters.Shrink(Input=OutputPort(ss,0)) - cs = sources.Cone() - app = filters.AppendDatasets() - app.Input = [shr, cs] - rv = CreateRenderView() - rep = CreateRepresentation(app, rv) - rv.ResetCamera() - rv.StillRender() - data = Fetch(ss) - - return (data, rv) - -def demo2(fname="/Users/berk/Work/ParaViewData/Data/disk_out_ref.ex2"): - """This method demonstrates the user of a reader, representation and - view. It also demonstrates how meta-data can be obtained using proxies. - Make sure to pass the full path to an exodus file. Also note that certain - parameters are hard-coded for disk_out_ref.ex2 which can be found - in ParaViewData. This method returns the render view.""" - if not ActiveConnection: - Connect() - # Create the exodus reader and specify a file name - reader = sources.ExodusIIReader(FileName=fname) - # Get the list of point arrays. - arraySelection = reader.PointVariables - print arraySelection.Available - # Select all arrays - arraySelection.SetData(arraySelection.Available) - - # Next create a default render view appropriate for the session type. - rv = CreateRenderView() - # Create the matching representation - rep = CreateRepresentation(reader, rv) - rep.Representation = 1 # Wireframe - # Black background is not pretty - rv.Background = [0.4, 0.4, 0.6] - rv.StillRender() - # Reset the camera to include the whole thing - rv.ResetCamera() - rv.StillRender() - # Change the elevation of the camera. See VTK documentation of vtkCamera - # for camera parameters. - c = rv.GetActiveCamera() - c.Elevation(45) - rv.StillRender() - # Now that the reader execute, let's get some information about it's - # output. - pdi = reader[0].PointData - # This prints a list of all read point data arrays as well as their - # value ranges. - print 'Number of point arrays:', len(pdi) - for i in range(len(pdi)): - ai = pdi[i] - print "----------------" - print "Array:", i, ai.Name, ":" - numComps = ai.GetNumberOfComponents() - print "Number of components:", numComps - for j in range(numComps): - print "Range:", ai.GetRange(j) - # White is boring. Let's color the geometry using a variable. - # First create a lookup table. This object controls how scalar - # values are mapped to colors. See VTK documentation for - # details. - lt = rendering.PVLookupTable() - # Assign it to the representation - rep.LookupTable = lt - # Color by point array called Pres - rep.ColorAttributeType = 0 # point data - rep.ColorArrayName = "Pres" - # Add to RGB points. These are tuples of 4 values. First one is - # the scalar values, the other 3 the RGB values. This list has - # 2 points: Pres: 0.00678, color: blue, Pres: 0.0288, color: red - lt.RGBPoints = [0.00678, 0, 0, 1, 0.0288, 1, 0, 0] - lt.ColorSpace = 1 # HSV - rv.StillRender() - return rv - -def demo3(): - """This method demonstrates the use of servermanager with numpy as - well as pylab for plotting. It creates an artificial data sources, - probes it with a line, delivers the result to the client using Fetch - and plots it using pylab. This demo requires numpy and pylab installed. - It returns a tuple of (data, render view).""" - import paraview.numpy_support - import pylab - - if not ActiveConnection: - Connect() - # Create a synthetic data source - source = sources.Wavelet() - # Let's get some information about the data. First, for the - # source to execute - source.UpdatePipeline() - - di = source.GetDataInformation() - print "Data type:", di.GetPrettyDataTypeString() - print "Extent:", di.GetExtent() - print "Array name:", \ - source[0].PointData[0].Name - - rv = CreateRenderView() - - rep1 = CreateRepresentation(source, rv) - rep1.Representation = 3 # outline - - # Let's apply a contour filter - cf = filters.Contour(Input=source, ContourValues=[200]) - - # Select the array to contour by - #cf.SelectInputScalars = 'RTData' - - rep2 = CreateRepresentation(cf, rv) - - rv.Background = (0.4, 0.4, 0.6) - # Reset the camera to include the whole thing - rv.StillRender() - rv.ResetCamera() - rv.StillRender() - - # Now, let's probe the data - probe = filters.ResampleWithDataset(Input=source) - # with a line - line = sources.Line(Resolution=60) - # that spans the dataset - bounds = di.GetBounds() - print "Bounds: ", bounds - line.Point1 = bounds[0:6:2] - line.Point2 = bounds[1:6:2] - - probe.Source = line - - # Render with the line - rep3 = CreateRepresentation(line, rv) - rv.StillRender() - - # Now deliver it to the client. Remember, this is for small data. - data = Fetch(probe) - # Convert it to a numpy array - data = paraview.numpy_support.vtk_to_numpy( - data.GetPointData().GetArray("RTData")) - # Plot it using matplotlib - pylab.plot(data) - pylab.show() - - return (data, rv, probe) - -def demo4(fname="/Users/berk/Work/ParaViewData/Data/can.ex2"): - """This method demonstrates the user of AnimateReader for - creating animations.""" - if not ActiveConnection: - Connect() - reader = sources.ExodusIIReader(FileName=fname) - view = CreateRenderView() - repr = CreateRepresentation(reader, view) - view.StillRender() - view.ResetCamera() - view.StillRender() - c = view.GetActiveCamera() - c.Elevation(95) - return AnimateReader(reader, view) - - -def demo5(): - """ Simple sphere animation""" - if not ActiveConnection: - Connect() - sphere = sources.Sphere() - view = CreateRenderView() - repr = CreateRepresentation(sphere, view) - - view.StillRender() - view.ResetCamera() - view.StillRender() - - # Create an animation scene - scene = animation.AnimationScene() - # Add 1 view - scene.ViewModules = [view] - - # Create a cue to animate the StartTheta property - cue = animation.KeyFrameAnimationCue() - cue.AnimatedProxy = sphere - cue.AnimatedPropertyName = "StartTheta" - # Add it to the scene's cues - scene.Cues = [cue] - - # Create 2 keyframes for the StartTheta track - keyf0 = animation.CompositeKeyFrame() - keyf0.Type = 2 # Set keyframe interpolation type to Ramp. - # At time = 0, value = 0 - keyf0.KeyTime = 0 - keyf0.KeyValues= [0] - - keyf1 = animation.CompositeKeyFrame() - # At time = 1.0, value = 200 - keyf1.KeyTime = 1.0 - keyf1.KeyValues= [200] - - # Add keyframes. - cue.KeyFrames = [keyf0, keyf1] - - scene.Play() - return scene - -ASSOCIATIONS = { 'POINTS' : 0, 'CELLS' : 1, 'VERTICES' : 4, 'EDGES' : 5, 'ROWS' : 6} - -# Users can set the active connection which will be used by API -# to create proxies etc when no connection argument is passed. -# Connect() automatically sets this if it is not already set. -ActiveConnection = None - -# Fields for multi-server support -MultiServerConnections = None - -# API for multi-server support -def enableMultiServer(multiServer=True): - """This method enable the current servermanager to support several - connections. Once we enable the multi-server support, the user can create - as many connection as he want and switch from one to another in order to - create and manage proxy.""" - global MultiServerConnections, ActiveConnection - if not multiServer and MultiServerConnections: - raise RuntimeError, "Once we enable Multi-Server support we can not get back" - MultiServerConnections = [] - if ActiveConnection: - MultiServerConnections.append(ActiveConnection) - -def switchActiveConnection(newActiveConnection=None): - """Switch active connection to be the provided one or if none just pick the - other one""" - global MultiServerConnections, ActiveConnection - if MultiServerConnections == None: - raise RuntimeError, "enableMultiServer() must be called before" - - # Manage the case when no connection is provided - if newActiveConnection: - ActiveConnection = newActiveConnection - __exposeActiveModules__() - # Update active session for ParaView - if vtkSMProxyManager.GetProxyManager().GetActiveSession() != ActiveConnection.Session: - vtkSMProxyManager.GetProxyManager().SetActiveSession(ActiveConnection.Session) - return ActiveConnection - else: - for connection in MultiServerConnections: - if connection != ActiveConnection: - ActiveConnection = connection - __exposeActiveModules__() - # Update active session for ParaView - if vtkSMProxyManager.GetProxyManager().GetActiveSession() != ActiveConnection.Session: - vtkSMProxyManager.GetProxyManager().SetActiveSession(ActiveConnection.Session) - return ActiveConnection - return None - -# Needs to be called when paraview module is loaded from python instead -# of pvpython, pvbatch or GUI. -if not vtkProcessModule.GetProcessModule(): -# pvoptions = None Not applicable for SALOME Python console -# if paraview.options.batch: -# pvoptions = vtkPVOptions(); -# pvoptions.SetProcessType(0x40) -# if paraview.options.symmetric: -# pvoptions.SetSymmetricMPIMode(True) - vtkInitializationHelper.Initialize(sys.executable, - vtkProcessModule.PROCESS_CLIENT, pvoptions) - -# Initialize progress printing. Can be turned off by calling -# ToggleProgressPrinting() again. -progressObserverTag = None -currentAlgorithm = False -currentProgress = 0 -fromGUI = False -ToggleProgressPrinting() - -_pyproxies = {} - -# Create needed sub-modules -# We can no longer create modules, unless we have connected to a server. -# _createModules() - -# Set up our custom importer (if possible) -loader = _ModuleLoader() -sys.meta_path.append(loader) - -def __InitAfterConnect__(connection): - """ - This function is called everytime after a server connection is made. - Since the ProxyManager and all proxy definitions are changed every time a - new connection is made, we re-create all the modules - """ - _createModules(connection.Modules) - ## VSV fromFilter is alwais False for SALOME because it can't be changed from ParaView code - #if not paraview.fromFilter: - # fromFilter is set when this module is imported from the programmable - # filter -# global _defUpdater -# _defUpdater = __DefinitionUpdater() - connection.AttachDefinitionUpdater() - pass - -def __exposeActiveModules__(): - """Update servermanager submodules to point to the current - ActiveConnection.Modules.*""" - # Expose all active module to the current servermanager module - if ActiveConnection: - for m in [mName for mName in dir(ActiveConnection.Modules) if mName[0] != '_' ]: - exec "global %s;%s = ActiveConnection.Modules.%s" % (m,m,m) - -# Definitions for working in SALOME GUI mode -#aParams = myParavis.GetConnectionParameters() -#ActiveConnection = Connect() -##Connection(aParams[0]) -#ActiveConnection.SetHost(aParams[1], aParams[2], aParams[3], aParams[4], aParams[5]) -#ToggleProgressPrinting() -#fromGUI = True - -InitFromGUI() - -if hasattr(sys, "ps1"): - # session is interactive. - print vtkSMProxyManager.GetParaViewSourceVersion(); - -def GetConnectionFromId(id): - for connection in MultiServerConnections: - if connection.ID == id: - return connection - return None - -def GetConnectionFromSession(session): - for connection in MultiServerConnections: - if connection.Session == session: - return connection - return None - -def GetConnectionAt(index): - return MultiServerConnections[index] - -def GetNumberOfConnections(): - return len(MultiServerConnections) - -#VTN: Problem during execution -#atexit.register(vtkPythonProgrammableFilter.DeleteGlobalPythonInterpretor) diff --git a/src/PV_SWIG/VTKWrapping/pvsimple.py b/src/PV_SWIG/VTKWrapping/pvsimple.py deleted file mode 100644 index 6b474725..00000000 --- a/src/PV_SWIG/VTKWrapping/pvsimple.py +++ /dev/null @@ -1,1173 +0,0 @@ -# Copyright (C) 2010-2014 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 -# License as published by the Free Software Foundation; either -# version 2.1 of the License, or (at your option) any later version. -# -# This library is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -r"""simple is a module for using paraview server manager in Python. It -provides a simple convenience layer to functionality provided by the -C++ classes wrapped to Python as well as the servermanager module. - -A simple example: - from paraview.simple import * - - # Create a new sphere proxy on the active connection and register it - # in the sources group. - sphere = Sphere(ThetaResolution=16, PhiResolution=32) - - # Apply a shrink filter - shrink = Shrink(sphere) - - # Turn the visiblity of the shrink object on. - Show(shrink) - - # Render the scene - Render() -""" - -import paravisSM - -servermanager = paravisSM - -def enableMultiServer(): - servermanager.enableMultiServer() - -def switchActiveConnection(newActiveConnection=None, ns=None): - if not ns: - ns = globals() - _remove_functions(ns) - servermanager.switchActiveConnection(newActiveConnection) - _add_functions(ns) - -def Disconnect(ns=None, force=True): - if servermanager.ActiveConnection and (force or servermanager.MultiServerConnections == None): - if ns: - _remove_functions(ns) - _remove_functions(globals()) - if not servermanager.fromGUI: - servermanager.ProxyManager().DisableStateUpdateNotification() - servermanager.ProxyManager().UnRegisterProxies() - active_objects.view = None - active_objects.source = None - servermanager.Disconnect() - if not servermanager.fromGUI: - import gc - gc.collect() - -def Connect(ds_host=None, ds_port=11111, rs_host=None, rs_port=11111): - """Creates a connection to a server. Example usage: - > Connect("amber") # Connect to a single server at default port - > Connect("amber", 12345) # Connect to a single server at port 12345 - > Connect("amber", 11111, "vis_cluster", 11111) # connect to data server, render server pair""" - Disconnect(globals(), False) - connection = servermanager.Connect(ds_host, ds_port, rs_host, rs_port) - _add_functions(globals()) - - servermanager.ProxyManager().DisableStateUpdateNotification() - servermanager.ProxyManager().UpdateFromRemote() - tk = servermanager.ProxyManager().GetProxy("timekeeper", "TimeKeeper") - if not tk: - try: - tk = servermanager.misc.TimeKeeper() - servermanager.ProxyManager().RegisterProxy("timekeeper", "TimeKeeper", tk) - except AttributeError: - print "Error: Could not create TimeKeeper" - - scene = servermanager.ProxyManager().GetProxy("animation", "AnimationScene") - if not scene: - try: - scene = AnimationScene() - scene.TimeKeeper = tk - except NameError: - print "Error: Could not create AnimationScene" - - servermanager.ProxyManager().EnableStateUpdateNotification() - servermanager.ProxyManager().TriggerStateUpdate() - - return connection - -def ReverseConnect(port=11111): - """Create a reverse connection to a server. Listens on port and waits for - an incoming connection from the server.""" - Disconnect(globals(), False) - connection = servermanager.ReverseConnect(port) - _add_functions(globals()) - - servermanager.ProxyManager().DisableStateUpdateNotification() - servermanager.ProxyManager().UpdateFromRemote() - tk = servermanager.ProxyManager().GetProxy("timekeeper", "TimeKeeper") - if not tk: - tk = servermanager.misc.TimeKeeper() - servermanager.ProxyManager().RegisterProxy("timekeeper", "TimeKeeper", tk) - - scene = servermanager.ProxyManager().GetProxy("animation", "AnimationScene") - if not scene: - scene = AnimationScene() - scene.TimeKeeper = tk - - servermanager.ProxyManager().EnableStateUpdateNotification() - servermanager.ProxyManager().TriggerStateUpdate() - - return connection - -def _create_view(view_xml_name): - "Creates and returns a 3D render view." - view = servermanager._create_view(view_xml_name) - servermanager.ProxyManager().RegisterProxy("views", \ - "my_view%d" % _funcs_internals.view_counter, view) - active_objects.view = view - _funcs_internals.view_counter += 1 - - tk = servermanager.ProxyManager().GetProxiesInGroup("timekeeper").values()[0] - views = tk.Views - if not view in views: - views.append(view) - try: - scene = GetAnimationScene() - if not view in scene.ViewModules: - scene.ViewModules.append(view) - except servermanager.MissingProxy: - pass - return view - -def CreateRenderView(): - return _create_view("RenderView") - -def CreateXYPlotView(): - return _create_view("XYChartView") - -def CreateBarChartView(): - return _create_view("XYBarChartView") - -def CreateComparativeRenderView(): - return _create_view("ComparativeRenderView") - -def CreateComparativeXYPlotView(): - return _create_view("ComparativeXYPlotView") - -def CreateComparativeBarChartView(): - return _create_view("ComparativeBarChartView") - -def CreateParallelCoordinatesChartView(): - return _create_view("ParallelCoordinatesChartView") - -def Create2DRenderView(): - return _create_view("2DRenderView") - -def OpenDataFile(filename, **extraArgs): - """Creates a reader to read the give file, if possible. - This uses extension matching to determine the best reader possible. - If a reader cannot be identified, then this returns None.""" - session = servermanager.ActiveConnection.Session - reader_factor = servermanager.vtkSMProxyManager.GetProxyManager().GetReaderFactory() - if reader_factor.GetNumberOfRegisteredPrototypes() == 0: - reader_factor.RegisterPrototypes(session, "sources") - first_file = filename - if type(filename) == list: - first_file = filename[0] - if not reader_factor.TestFileReadability(first_file, session): - msg = "File not readable: %s " % first_file - raise RuntimeError, msg - if not reader_factor.CanReadFile(first_file, session): - msg = "File not readable. No reader found for '%s' " % first_file - raise RuntimeError, msg - prototype = servermanager.ProxyManager().GetPrototypeProxy( - reader_factor.GetReaderGroup(), reader_factor.GetReaderName()) - # [ABN]: bug fix for Christian VW (temporary - pvsimple should disappear soon) - from paraview import make_name_valid # make_name_valid is not in paravisSM - xml_name = make_name_valid(prototype.GetXMLLabel()) - reader_func = _create_func(xml_name, servermanager.sources) - if prototype.GetProperty("FileNames"): - reader = reader_func(FileNames=filename, **extraArgs) - else : - reader = reader_func(FileName=filename, **extraArgs) - return reader - -def CreateWriter(filename, proxy=None, **extraArgs): - """Creates a writer that can write the data produced by the source proxy in - the given file format (identified by the extension). If no source is - provided, then the active source is used. This doesn't actually write the - data, it simply creates the writer and returns it.""" - if not filename: - raise RuntimeError, "filename must be specified" - session = servermanager.ActiveConnection.Session - writer_factory = servermanager.vtkSMProxyManager.GetProxyManager().GetWriterFactory() - if writer_factory.GetNumberOfRegisteredPrototypes() == 0: - writer_factory.RegisterPrototypes(session, "writers") - if not proxy: - proxy = GetActiveSource() - if not proxy: - raise RuntimeError, "Could not locate source to write" - writer_proxy = writer_factory.CreateWriter(filename, proxy.SMProxy, proxy.Port) - return servermanager._getPyProxy(writer_proxy) - -def GetRenderView(): - """Returns the active view if there is one. Else creates and returns a new view.""" - view = active_objects.view - if not view: - # it's possible that there's no active view, but a render view exists. - # If so, locate that and return it (before trying to create a new one). - view = servermanager.GetRenderView() - if not view: - view = CreateRenderView() - return view - -def GetRenderViews(): - """Returns all render views as a list.""" - return servermanager.GetRenderViews() - -def GetRepresentation(proxy=None, view=None): - """Given a pipeline object and view, returns the corresponding representation object. - If pipeline object and view are not specified, active objects are used.""" - if not view: - view = active_objects.view - if not proxy: - proxy = active_objects.source - rep = servermanager.GetRepresentation(proxy, view) - if not rep: - rep = servermanager.CreateRepresentation(proxy, view) - servermanager.ProxyManager().RegisterProxy("representations", \ - "my_representation%d" % _funcs_internals.rep_counter, rep) - _funcs_internals.rep_counter += 1 - return rep - -def GetDisplayProperties(proxy=None, view=None): - """Given a pipeline object and view, returns the corresponding representation object. - If pipeline object and/or view are not specified, active objects are used.""" - return GetRepresentation(proxy, view) - -def Show(proxy=None, view=None, **params): - """Turns the visibility of a given pipeline object on in the given view. - If pipeline object and/or view are not specified, active objects are used.""" - if proxy == None: - proxy = GetActiveSource() - if proxy == None: - raise RuntimeError, "Show() needs a proxy argument or that an active source is set." - if not view and not active_objects.view: - CreateRenderView() - rep = GetDisplayProperties(proxy, view) - if rep == None: - raise RuntimeError, "Could not create a representation object for proxy %s" % proxy.GetXMLLabel() - for param in params.keys(): - setattr(rep, param, params[param]) - rep.Visibility = 1 - return rep - -def Hide(proxy=None, view=None): - """Turns the visibility of a given pipeline object off in the given view. - If pipeline object and/or view are not specified, active objects are used.""" - rep = GetDisplayProperties(proxy, view) - rep.Visibility = 0 - -def Render(view=None): - """Renders the given view (default value is active view)""" - if not view: - view = active_objects.view - view.StillRender() - if _funcs_internals.first_render: - # Not all views have a ResetCamera method - try: - view.ResetCamera() - view.StillRender() - except AttributeError: pass - _funcs_internals.first_render = False - return view - -def ResetCamera(view=None): - """Resets the settings of the camera to preserver orientation but include - the whole scene. If an argument is not provided, the active view is - used.""" - if not view: - view = active_objects.view - if hasattr(view, "ResetCamera"): - view.ResetCamera() - if hasattr(view, "ResetDisplay"): - view.ResetDisplay() - Render(view) - -def _DisableFirstRenderCameraReset(): - """Disable the first render camera reset. Normally a ResetCamera is called - automatically when Render is called for the first time after importing - this module.""" - _funcs_internals.first_render = False - -def SetProperties(proxy=None, **params): - """Sets one or more properties of the given pipeline object. If an argument - is not provided, the active source is used. Pass a list of property_name=value - pairs to this function to set property values. For example: - SetProperties(Center=[1, 2, 3], Radius=3.5) - """ - if not proxy: - proxy = active_objects.source - for param in params.keys(): - if not hasattr(proxy, param): - raise AttributeError("object has no property %s" % param) - setattr(proxy, param, params[param]) - -def GetProperty(*arguments, **keywords): - """Get one property of the given pipeline object. If keywords are used, - you can set the proxy and the name of the property that you want to get - like in the following example : - GetProperty({proxy=sphere, name="Radius"}) - If it's arguments that are used, then you have two case: - - if only one argument is used that argument will be - the property name. - - if two arguments are used then the first one will be - the proxy and the second one the property name. - Several example are given below: - GetProperty({name="Radius"}) - GetProperty({proxy=sphereProxy, name="Radius"}) - GetProperty( sphereProxy, "Radius" ) - GetProperty( "Radius" ) - """ - name = None - proxy = None - for key in keywords: - if key == "name": - name = keywords[key] - if key == "proxy": - proxy = keywords[key] - if len(arguments) == 1 : - name = arguments[0] - if len(arguments) == 2 : - proxy = arguments[0] - name = arguments[1] - if not name: - raise RuntimeError, "Expecting at least a property name as input. Otherwise keyword could be used to set 'proxy' and property 'name'" - if not proxy: - proxy = active_objects.source - return proxy.GetProperty(name) - -def SetDisplayProperties(proxy=None, view=None, **params): - """Sets one or more display properties of the given pipeline object. If an argument - is not provided, the active source is used. Pass a list of property_name=value - pairs to this function to set property values. For example: - SetProperties(Color=[1, 0, 0], LineWidth=2) - """ - rep = GetDisplayProperties(proxy, view) - SetProperties(rep, **params) - -def SetViewProperties(view=None, **params): - """Sets one or more properties of the given view. If an argument - is not provided, the active view is used. Pass a list of property_name=value - pairs to this function to set property values. For example: - SetProperties(Background=[1, 0, 0], UseImmediateMode=0) - """ - if not view: - view = active_objects.view - SetProperties(view, **params) - -def RenameSource(newName, proxy=None): - """Renames the given source. If the given proxy is not registered - in the sources group this method will have no effect. If no source is - provided, the active source is used.""" - if not proxy: - proxy = active_objects.source - pxm = servermanager.ProxyManager() - oldName = pxm.GetProxyName("sources", proxy) - if oldName: - pxm.RegisterProxy("sources", newName, proxy) - pxm.UnRegisterProxy("sources", oldName, proxy) - -def FindSource(name): - return servermanager.ProxyManager().GetProxy("sources", name) - -def GetSources(): - """Given the name of a source, return its Python object.""" - return servermanager.ProxyManager().GetProxiesInGroup("sources") - -def GetRepresentations(): - """Returns all representations (display properties).""" - return servermanager.ProxyManager().GetProxiesInGroup("representations") - -def UpdatePipeline(time=None, proxy=None): - """Updates (executes) the given pipeline object for the given time as - necessary (i.e. if it did not already execute). If no source is provided, - the active source is used instead.""" - if not proxy: - proxy = active_objects.source - if time: - proxy.UpdatePipeline(time) - else: - proxy.UpdatePipeline() - -def Delete(proxy=None): - """Deletes the given pipeline object or the active source if no argument - is specified.""" - if not proxy: - proxy = active_objects.source - # Unregister any helper proxies stored by a vtkSMProxyListDomain - for prop in proxy: - listdomain = prop.GetDomain('proxy_list') - if listdomain: - if listdomain.GetClassName() != 'vtkSMProxyListDomain': - continue - group = "pq_helper_proxies." + proxy.GetGlobalIDAsString() - for i in xrange(listdomain.GetNumberOfProxies()): - pm = servermanager.ProxyManager() - iproxy = listdomain.GetProxy(i) - name = pm.GetProxyName(group, iproxy) - if iproxy and name: - pm.UnRegisterProxy(group, name, iproxy) - - # Remove source/view from time keeper - tk = servermanager.ProxyManager().GetProxiesInGroup("timekeeper").values()[0] - if isinstance(proxy, servermanager.SourceProxy): - try: - idx = tk.TimeSources.index(proxy) - del tk.TimeSources[idx] - except ValueError: - pass - else: - try: - idx = tk.Views.index(proxy) - del tk.Views[idx] - except ValueError: - pass - servermanager.UnRegister(proxy) - - # If this is a representation, remove it from all views. - if proxy.SMProxy.IsA("vtkSMRepresentationProxy") or \ - proxy.SMProxy.IsA("vtkSMNewWidgetRepresentationProxy"): - for view in GetRenderViews(): - view.Representations.remove(proxy) - # If this is a source, remove the representation iff it has no consumers - # Also change the active source if necessary - elif proxy.SMProxy.IsA("vtkSMSourceProxy"): - sources = servermanager.ProxyManager().GetProxiesInGroup("sources") - for i in range(proxy.GetNumberOfConsumers()): - if proxy.GetConsumerProxy(i) in sources: - raise RuntimeError("Source has consumers. It cannot be deleted " + - "until all consumers are deleted.") - #VSV:== - if proxy.IsSame(GetActiveSource()): - if hasattr(proxy, "Input") and proxy.Input: - if isinstance(proxy.Input, servermanager.Proxy): - SetActiveSource(proxy.Input) - else: - SetActiveSource(proxy.Input[0]) - else: SetActiveSource(None) - for rep in GetRepresentations().values(): - #VSV:== - if rep.Input.IsSame(proxy): - Delete(rep) - # Change the active view if necessary - elif proxy.SMProxy.IsA("vtkSMRenderViewProxy"): - ##VSV:== - if proxy.IsSame(GetActiveView()): - if len(GetRenderViews()) > 0: - SetActiveView(GetRenderViews()[0]) - else: - SetActiveView(None) - -def CreateLookupTable(**params): - """Create and return a lookup table. Optionally, parameters can be given - to assign to the lookup table. - """ - lt = servermanager.rendering.PVLookupTable() - servermanager.Register(lt) - SetProperties(lt, **params) - return lt - -def CreatePiecewiseFunction(**params): - """Create and return a piecewise function. Optionally, parameters can be - given to assign to the piecewise function. - """ - pfunc = servermanager.piecewise_functions.PiecewiseFunction() - servermanager.Register(pfunc) - SetProperties(pfunc, **params) - return pfunc - -def GetLookupTableForArray(arrayname, num_components, **params): - """Used to get an existing lookuptable for a array or to create one if none - exists. Keyword arguments can be passed in to initialize the LUT if a new - one is created.""" - proxyName = "%d.%s.PVLookupTable" % (int(num_components), arrayname) - lut = servermanager.ProxyManager().GetProxy("lookup_tables", proxyName) - if lut: - return lut - # No LUT exists for this array, create a new one. - # TODO: Change this to go a LookupTableManager that is shared with the GUI, - # so that the GUI and python end up create same type of LUTs. For now, - # python will create a Blue-Red LUT, unless overridden by params. - lut = servermanager.rendering.PVLookupTable( - ColorSpace="HSV", RGBPoints=[0, 0, 0, 1, 1, 1, 0, 0]) - SetProperties(lut, **params) - servermanager.Register(lut, registrationName=proxyName) - return lut - -def CreateScalarBar(**params): - """Create and return a scalar bar widget. The returned widget may - be added to a render view by appending it to the view's representations - The widget must have a valid lookup table before it is added to a view. - It is possible to pass the lookup table (and other properties) as arguments - to this method: - - lt = MakeBlueToRedLt(3.5, 7.5) - bar = CreateScalarBar(LookupTable=lt, Title="Velocity") - GetRenderView().Representations.append(bar) - - By default the returned widget is selectable and resizable. - """ - sb = servermanager.rendering.ScalarBarWidgetRepresentation() - servermanager.Register(sb) - sb.Selectable = 1 - sb.Resizable = 1 - sb.Enabled = 1 - sb.Title = "Scalars" - SetProperties(sb, **params) - return sb - -# TODO: Change this to take the array name and number of components. Register -# the lt under the name ncomp.array_name -def MakeBlueToRedLT(min, max): - # Define RGB points. These are tuples of 4 values. First one is - # the scalar values, the other 3 the RGB values. - rgbPoints = [min, 0, 0, 1, max, 1, 0, 0] - return CreateLookupTable(RGBPoints=rgbPoints, ColorSpace="HSV") - -def _find_writer(filename): - """Internal function.""" - extension = None - parts = filename.split('.') - if len(parts) > 1: - extension = parts[-1] - else: - raise RuntimeError, "Filename has no extension, please specify a write" - - if extension == 'png': - return 'vtkPNGWriter' - elif extension == 'bmp': - return 'vtkBMPWriter' - elif extension == 'ppm': - return 'vtkPNMWriter' - elif extension == 'tif' or extension == 'tiff': - return 'vtkTIFFWriter' - elif extension == 'jpg' or extension == 'jpeg': - return 'vtkJPEGWriter' - else: - raise RuntimeError, "Cannot infer filetype from extension:", extension - -def AddCameraLink(viewProxy, viewProxyOther, linkName): - """Create a camera link between two view proxies. A name must be given - so that the link can be referred to by name. If a link with the given - name already exists it will be removed first.""" - if not viewProxyOther: viewProxyOther = GetActiveView() - link = servermanager.vtkSMCameraLink() - link.AddLinkedProxy(viewProxy.SMProxy, 1) - link.AddLinkedProxy(viewProxyOther.SMProxy, 2) - link.AddLinkedProxy(viewProxyOther.SMProxy, 1) - link.AddLinkedProxy(viewProxy.SMProxy, 2) - RemoveCameraLink(linkName) - servermanager.ProxyManager().RegisterLink(linkName, link) - -def RemoveCameraLink(linkName): - """Remove a camera link with the given name.""" - servermanager.ProxyManager().UnRegisterLink(linkName) - -def WriteImage(filename, view=None, **params): - """Saves the given view (or the active one if none is given) as an - image. Optionally, you can specify the writer and the magnification - using the Writer and Magnification named arguments. For example: - WriteImage("foo.mypng", aview, Writer=vtkPNGWriter, Magnification=2) - If no writer is provided, the type is determined from the file extension. - Currently supported extensions are png, bmp, ppm, tif, tiff, jpg and jpeg. - The writer is a VTK class that is capable of writing images. - Magnification is used to determine the size of the written image. The size - is obtained by multiplying the size of the view with the magnification. - Rendering may be done using tiling to obtain the correct size without - resizing the view.""" - if not view: - view = active_objects.view - writer = None - if params.has_key('Writer'): - writer = params['Writer'] - mag = 1 - if params.has_key('Magnification'): - mag = int(params['Magnification']) - if not writer: - writer = _find_writer(filename) - view.WriteImage(filename, writer, mag) - -def AnimateReader(reader=None, view=None, filename=None): - """This is a utility function that, given a reader and a view - animates over all time steps of the reader. If the optional - filename is provided, a movie is created (type depends on the - extension of the filename.""" - if not reader: - reader = active_objects.source - if not view: - view = active_objects.view - - return servermanager.AnimateReader(reader, view, filename) - - -def _create_func(key, module): - """Internal function.""" - - def CreateObject(*input, **params): - """This function creates a new proxy. For pipeline objects that accept inputs, - all non-keyword arguments are assumed to be inputs. All keyword arguments are - assumed to be property,value pairs and are passed to the new proxy.""" - - # Instantiate the actual object from the given module. - px = module.__dict__[key]() - - # Make sure non-keyword arguments are valid - for inp in input: - if inp != None and not isinstance(inp, servermanager.Proxy): - if px.GetProperty("Input") != None: - raise RuntimeError, "Expecting a proxy as input." - else: - raise RuntimeError, "This function does not accept non-keyword arguments." - - # Assign inputs - if px.GetProperty("Input") != None: - if len(input) > 0: - px.Input = input - else: - # If no input is specified, try the active pipeline object - if px.GetProperty("Input").GetRepeatable() and active_objects.get_selected_sources(): - px.Input = active_objects.get_selected_sources() - elif active_objects.source: - px.Input = active_objects.source - else: - if len(input) > 0: - raise RuntimeError, "This function does not expect an input." - - registrationName = None - for nameParam in ['registrationName', 'guiName']: - if nameParam in params: - registrationName = params[nameParam] - del params[nameParam] - - # Pass all the named arguments as property,value pairs - for param in params.keys(): - setattr(px, param, params[param]) - - try: - # Register the proxy with the proxy manager. - if registrationName: - group, name = servermanager.Register(px, registrationName=registrationName) - else: - group, name = servermanager.Register(px) - - - # Register pipeline objects with the time keeper. This is used to extract time values - # from sources. NOTE: This should really be in the servermanager controller layer. - if group == "sources": - has_tk = True - try: - tk = servermanager.ProxyManager().GetProxiesInGroup("timekeeper").values()[0] - except IndexError: - has_tk = False - if has_tk: - sources = tk.TimeSources - if not px in sources: - sources.append(px) - - active_objects.source = px - except servermanager.MissingRegistrationInformation: - pass - - return px - - return CreateObject - -def _create_doc(new, old): - """Internal function.""" - import string - res = "" - for doc in (new, old): - ts = [] - strpd = doc.split('\n') - for s in strpd: - ts.append(s.lstrip()) - res += string.join(ts) - res += '\n' - return res - -def _func_name_valid(name): - """Internal function.""" - valid = True - for c in name: - if c == '(' or c ==')': - valid = False - break - return valid - -def _add_functions(g): - activeModule = servermanager.ActiveConnection.Modules - for m in [activeModule.filters, activeModule.sources, - activeModule.writers, activeModule.animation]: - dt = m.__dict__ - for key in dt.keys(): - cl = dt[key] - if not isinstance(cl, str): - if not key in g and _func_name_valid(key): - g[key] = _create_func(key, m) - exec "g[key].__doc__ = _create_doc(m.%s.__doc__, g[key].__doc__)" % key - -def _remove_functions(g): - list = [] - if servermanager.ActiveConnection: - list = [m for m in dir(servermanager.ActiveConnection.Modules) if m[0] != '_'] - - for m in list: - dt = servermanager.ActiveConnection.Modules.__dict__[m].__dict__ - for key in dt.keys(): - cl = dt[key] - if not isinstance(cl, str) and g.has_key(key): - g.pop(key) - #print "remove %s function" % key - -def GetActiveView(): - """Returns the active view.""" - return active_objects.view - -def SetActiveView(view): - """Sets the active view.""" - active_objects.view = view - -def GetActiveSource(): - """Returns the active source.""" - return active_objects.source - -def SetActiveSource(source): - """Sets the active source.""" - active_objects.source = source - -def GetActiveCamera(): - """Returns the active camera for the active view. The returned object - is an instance of vtkCamera.""" - return GetActiveView().GetActiveCamera() - -def GetAnimationScene(): - """Returns the application-wide animation scene. ParaView has only one - global animation scene. This method provides access to that. Users are - free to create additional animation scenes directly, but those scenes - won't be shown in the ParaView GUI.""" - animation_proxies = servermanager.ProxyManager().GetProxiesInGroup("animation") - scene = None - for aProxy in animation_proxies.values(): - if aProxy.GetXMLName() == "AnimationScene": - scene = aProxy - break - if not scene: - raise servermanager.MissingProxy, "Could not locate global AnimationScene." - return scene - -def WriteAnimation(filename, **params): - """Writes the current animation as a file. Optionally one can specify - arguments that qualify the saved animation files as keyword arguments. - Accepted options are as follows: - * Magnification (integer) : set the maginification factor for the saved - animation. - * Quality (0 [worst] or 1 or 2 [best]) : set the quality of the generated - movie (if applicable). - * Subsampling (integer) : setting whether the movie encoder should use - subsampling of the chrome planes or not, if applicable. Since the human - eye is more sensitive to brightness than color variations, subsampling - can be useful to reduce the bitrate. Default value is 0. - * BackgroundColor (3-tuple of doubles) : set the RGB background color to - use to fill empty spaces in the image. - * FrameRate (double): set the frame rate (if applicable).""" - scene = GetAnimationScene() - # ensures that the TimeKeeper track is created. - GetTimeTrack() - iw = servermanager.vtkSMAnimationSceneImageWriter() - iw.SetAnimationScene(scene.SMProxy) - iw.SetFileName(filename) - if params.has_key("Magnification"): - iw.SetMagnification(int(params["Magnification"])) - if params.has_key("Quality"): - iw.SetQuality(int(params["Quality"])) - if params.has_key("Subsampling"): - iw.SetSubsampling(int(params["Subsampling"])) - if params.has_key("BackgroundColor"): - iw.SetBackgroundColor(params["BackgroundColor"]) - if params.has_key("FrameRate"): - iw.SetFrameRate(float(params["FrameRate"])) - iw.Save() - -def _GetRepresentationAnimationHelper(sourceproxy): - """Internal method that returns the representation animation helper for a - source proxy. It creates a new one if none exists.""" - # ascertain that proxy is a source proxy - if not sourceproxy in GetSources().values(): - return None - for proxy in servermanager.ProxyManager(): - if proxy.GetXMLName() == "RepresentationAnimationHelper" and\ - proxy.GetProperty("Source").IsProxyAdded(sourceproxy.SMProxy): - return proxy - # create a new helper - proxy = servermanager.misc.RepresentationAnimationHelper( - Source=sourceproxy) - servermanager.ProxyManager().RegisterProxy( - "pq_helper_proxies.%s" % sourceproxy.GetGlobalIDAsString(), - "RepresentationAnimationHelper", proxy) - return proxy - -def GetAnimationTrack(propertyname_or_property, index=None, proxy=None): - """Returns an animation cue for the property. If one doesn't exist then a - new one will be created. - Typical usage: - track = GetAnimationTrack("Center", 0, sphere) or - track = GetAnimationTrack(sphere.GetProperty("Radius")) or - - # this returns the track to animate visibility of the active source in - # all views. - track = GetAnimationTrack("Visibility") - - For animating properties on implicit planes etc., use the following - signatures: - track = GetAnimationTrack(slice.SliceType.GetProperty("Origin"), 0) or - track = GetAnimationTrack("Origin", 0, slice.SliceType) - - """ - if not proxy: - proxy = GetActiveSource() - if not isinstance(proxy, servermanager.Proxy): - raise TypeError, "proxy must be a servermanager.Proxy instance" - if isinstance(propertyname_or_property, str): - propertyname = propertyname_or_property - elif isinstance(propertyname_or_property, servermanager.Property): - prop = propertyname_or_property - propertyname = prop.Name - proxy = prop.Proxy - else: - raise TypeError, "propertyname_or_property must be a string or servermanager.Property" - - # To handle the case where the property is actually a "display" property, in - # which case we are actually animating the "RepresentationAnimationHelper" - # associated with the source. - if propertyname in ["Visibility", "Opacity"]: - proxy = _GetRepresentationAnimationHelper(proxy) - if not proxy or not proxy.GetProperty(propertyname): - raise AttributeError, "Failed to locate property %s" % propertyname - - scene = GetAnimationScene() - for cue in scene.Cues: - try: - if cue.AnimatedProxy.IsSame(proxy) and\ - cue.AnimatedPropertyName == propertyname: - if index == None or index.IsSame(cue.AnimatedElement): ##index == cue.AnimatedElement: - return cue - except AttributeError: - pass - - # matching animation track wasn't found, create a new one. - cue = KeyFrameAnimationCue() - cue.AnimatedProxy = proxy - cue.AnimatedPropertyName = propertyname - if index != None: - cue.AnimatedElement = index - scene.Cues.append(cue) - return cue - -def GetCameraTrack(view=None): - """Returns the camera animation track for the given view. If no view is - specified, active view will be used. If no exisiting camera animation track - is found, a new one will be created.""" - if not view: - view = GetActiveView() - if not view: - raise ValueError, "No view specified" - scene = GetAnimationScene() - for cue in scene.Cues: - if cue.AnimatedProxy.IsSame(view) and\ - cue.GetXMLName() == "CameraAnimationCue": - return cue - # no cue was found, create a new one. - cue = CameraAnimationCue() - cue.AnimatedProxy = view - scene.Cues.append(cue) - return cue - -def GetTimeTrack(): - """Returns the animation track used to control the time requested from all - readers/filters during playback. - This is the "TimeKeeper - Time" track shown in ParaView's 'Animation View'. - If none exists, a new one will be created.""" - scene = GetAnimationScene() - tk = scene.TimeKeeper - for cue in scene.Cues: - if cue.GetXMLName() == "TimeAnimationCue" and cue.AnimatedProxy.IsSame(tk)\ - and cue.AnimatedPropertyName == "Time": - return cue - # no cue was found, create a new one. - cue = TimeAnimationCue() - cue.AnimatedProxy = tk - cue.AnimatedPropertyName = "Time" - scene.Cues.append(cue) - return cue - -def LoadXML(xmlstring, ns=None): - """Given a server manager XML as a string, parse and process it. - If you loaded the simple module with from paraview.simple import *, - make sure to pass globals() as the second arguments: - LoadXML(xmlstring, globals()) - Otherwise, the new functions will not appear in the global namespace.""" - if not ns: - ns = globals() - servermanager.LoadXML(xmlstring) - _add_functions(ns) - -def LoadPlugin(filename, remote=True, ns=None): - """Loads a ParaView plugin and updates this module with new constructors - if any. The remote argument (default to True) is to specify whether - the plugin will be loaded on client (remote=False) or on server (remote=True). - If you loaded the simple module with from paraview.simple import *, - make sure to pass globals() as an argument: - LoadPlugin("myplugin", False, globals()), to load on client; - LoadPlugin("myplugin", True, globals()), to load on server; - LoadPlugin("myplugin", ns=globals()), to load on server. - Otherwise, the new functions will not appear in the global namespace.""" - - if not ns: - ns = globals() - servermanager.LoadPlugin(filename, remote) - _add_functions(ns) - -def LoadDistributedPlugin(pluginname, remote=True, ns=None): - """Loads a plugin that's distributed with the executable. This uses the - information known about plugins distributed with ParaView to locate the - shared library for the plugin to load. Raises a RuntimeError if the plugin - was not found.""" - if not servermanager.ActiveConnection: - raise RuntimeError, "Cannot load a plugin without a session." - plm = servermanager.vtkSMProxyManager.GetProxyManager().GetPluginManager() - if remote: - session = servermanager.ActiveConnection.Session - info = plm.GetRemoteInformation(session) - else: - info = plm.GetLocalInformation() - for cc in range(0, info.GetNumberOfPlugins()): - if info.GetPluginName(cc) == pluginname: - return LoadPlugin(info.GetPluginFileName(cc), remote, ns) - raise RuntimeError, "Plugin '%s' not found" % pluginname - -def GetLayouts(): - """Returns the layout proxies on the active session. - Layout proxies are used to place views in a grid.""" - return servermanager.ProxyManager().GetProxiesInGroup("layouts") - -def GetLayout(view=None): - """Return the layout containing the give view, if any. - If no view is specified, active view is used. - """ - if not view: - view = GetActiveView() - if not view: - raise RuntimeError, "No active view was found." - layouts = GetLayouts() - for layout in layouts.values(): - if layout.GetViewLocation(view) != -1: - return layout - return None - - -def SelectCells(query=None, proxy=None): - """Select cells satisfying the query. If query is None, then all cells are - selected. If proxy is None, then the active source is used.""" - if not proxy: - proxy = GetActiveSource() - if not proxy: - raise RuntimeError, "No active source was found." - - if not query: - # This ends up being true for all cells. - query = "id >= 0" - - # Note, selSource is not registered with the proxy manager. - selSource = servermanager.sources.SelectionQuerySource() - selSource.FieldType = "CELL" - selSource.QueryString = str(query) - proxy.SMProxy.SetSelectionInput(proxy.Port, selSource.SMProxy, 0) - return selSource - -def ClearSelection(proxy=None): - """Clears the selection on the active source.""" - if not proxy: - proxy = GetActiveSource() - if not proxy: - raise RuntimeError, "No active source was found." - proxy.SMProxy.SetSelectionInput(proxy.Port, None, 0) - -class ActiveObjects(object): - """This class manages the active objects (source and view). The active - objects are shared between Python and the user interface. This class - is for internal use. Use the Set/Get methods for setting and getting - active objects.""" - def __get_selection_model(self, name, session=None): - "Internal method." - if session and not servermanager.ActiveConnection.Session.IsSame(session): - raise RuntimeError, "Try to set an active object with invalid active connection." - pxm = servermanager.ProxyManager(session) - model = pxm.GetSelectionModel(name) - if not model: - model = servermanager.vtkSMProxySelectionModel() - pxm.RegisterSelectionModel(name, model) - return model - - def set_view(self, view): - "Sets the active view." - active_view_model = self.__get_selection_model("ActiveView") - if view: - active_view_model = self.__get_selection_model("ActiveView", view.GetSession()) - active_view_model.SetCurrentProxy(view.SMProxy, 0) - else: - active_view_model = self.__get_selection_model("ActiveView") - active_view_model.SetCurrentProxy(None, 0) - - def get_view(self): - "Returns the active view." - return servermanager._getPyProxy( - self.__get_selection_model("ActiveView").GetCurrentProxy()) - - def set_source(self, source): - "Sets the active source." - active_sources_model = self.__get_selection_model("ActiveSources") - if source: - # 3 == CLEAR_AND_SELECT - active_sources_model = self.__get_selection_model("ActiveSources", source.GetSession()) - active_sources_model.SetCurrentProxy(source.SMProxy, 3) - else: - active_sources_model = self.__get_selection_model("ActiveSources") - active_sources_model.SetCurrentProxy(None, 3) - - def __convert_proxy(self, px): - "Internal method." - if not px: - return None - if px.IsA("vtkSMSourceProxy"): - return servermanager._getPyProxy(px) - else: - return servermanager.OutputPort( - servermanager._getPyProxy(px.GetSourceProxy()), - px.GetPortIndex()) - - def get_source(self): - "Returns the active source." - return self.__convert_proxy( - self.__get_selection_model("ActiveSources").GetCurrentProxy()) - - def get_selected_sources(self): - "Returns the set of sources selected in the pipeline browser." - model = self.__get_selection_model("ActiveSources") - proxies = [] - for i in xrange(model.GetNumberOfSelectedProxies()): - proxies.append(self.__convert_proxy(model.GetSelectedProxy(i))) - return proxies - - view = property(get_view, set_view) - source = property(get_source, set_source) - -class _funcs_internals: - """Internal class.""" - first_render = True - view_counter = 0 - rep_counter = 0 - -def demo1(): - """Simple demo that create the following pipeline - sphere - shrink - \ - - append - cone - / - """ - # Create a sphere of radius = 2, theta res. = 32 - # This object becomes the active source. - ss = Sphere(Radius=2, ThetaResolution=32) - # Apply the shrink filter. The Input property is optional. If Input - # is not specified, the filter is applied to the active source. - shr = Shrink(Input=ss) - # Create a cone source. - cs = Cone() - # Append cone and shrink - app = AppendDatasets() - app.Input = [shr, cs] - # Show the output of the append filter. The argument is optional - # as the app filter is now the active object. - Show(app) - # Render the default view. - Render() - -def demo2(fname="/Users/berk/Work/ParaView/ParaViewData/Data/disk_out_ref.ex2"): - """This demo shows the use of readers, data information and display - properties.""" - - # Create the exodus reader and specify a file name - reader = ExodusIIReader(FileName=fname) - # Get the list of point arrays. - avail = reader.PointVariables.Available - print avail - # Select all arrays - reader.PointVariables = avail - - # Turn on the visibility of the reader - Show(reader) - # Set representation to wireframe - SetDisplayProperties(Representation = "Wireframe") - # Black background is not pretty - SetViewProperties(Background = [0.4, 0.4, 0.6]) - Render() - # Change the elevation of the camera. See VTK documentation of vtkCamera - # for camera parameters. - # NOTE: THIS WILL BE SIMPLER - GetActiveCamera().Elevation(45) - Render() - # Now that the reader executed, let's get some information about it's - # output. - pdi = reader[0].PointData - # This prints a list of all read point data arrays as well as their - # value ranges. - print 'Number of point arrays:', len(pdi) - for i in range(len(pdi)): - ai = pdi[i] - print "----------------" - print "Array:", i, " ", ai.Name, ":" - numComps = ai.GetNumberOfComponents() - print "Number of components:", numComps - for j in range(numComps): - print "Range:", ai.GetRange(j) - # White is boring. Let's color the geometry using a variable. - # First create a lookup table. This object controls how scalar - # values are mapped to colors. See VTK documentation for - # details. - # Map min (0.00678) to blue, max (0.0288) to red - SetDisplayProperties(LookupTable = MakeBlueToRedLT(0.00678, 0.0288)) - # Color by point array called Pres - SetDisplayProperties(ColorAttributeType = "POINT_DATA") - SetDisplayProperties(ColorArrayName = "Pres") - Render() - -def PrintTrace(): - print paravisSM.myParavis.GetTrace() - -def SaveTrace(fileName): - paravisSM.myParavis.SaveTrace(fileName) - - -if not servermanager.ActiveConnection: - Connect() -else: - _add_functions(globals()) - -def ImportFile(theFileName): - paravisSM.ImportFile(theFileName) - -active_objects = ActiveObjects() -active_objects.view = GetRenderView() diff --git a/src/PV_SWIG/no_wrap/paravis.py b/src/PV_SWIG/no_wrap/paravis.py new file mode 100644 index 00000000..071649da --- /dev/null +++ b/src/PV_SWIG/no_wrap/paravis.py @@ -0,0 +1,54 @@ +# Copyright (C) 2010-2014 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 +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# +# File : paravis.py +# Module : PARAVIS +# + +import os, new + +import PARAVIS +import SALOME +import SALOME_Session_idl +import SALOMEDS +import SALOME_ModuleCatalog +from omniORB import CORBA +from time import sleep +import salome + +## Initialization of paravis server +def Initialize(theDelay) : + mySession = None + while mySession == None: + mySession = salome.naming_service.Resolve("/Kernel/Session") + mySession = mySession._narrow(SALOME.Session) + mySession.GetInterface() + sleep(theDelay) + myLocalParavis = salome.lcc.FindOrLoadComponent("FactoryServer", "PARAVIS") +# myLocalStudy = salome.myStudy +# myLocalParavis.SetCurrentStudy(myLocalStudy) +# myLocalParavis.ActivateModule() ## CAN NOT WORK ANYMORE, now the engine and the GUI are properly decoupled + return myLocalParavis + +# def ImportFile(theFileName): +# "Import a file of any format supported by ParaView" +# myParavis.ImportFile(theFileName) + +## Initialize PARAVIS interface +myParavisEngine = Initialize(2) + diff --git a/src/PV_SWIG/no_wrap/paravisSM.py b/src/PV_SWIG/no_wrap/paravisSM.py new file mode 100644 index 00000000..04775112 --- /dev/null +++ b/src/PV_SWIG/no_wrap/paravisSM.py @@ -0,0 +1,30 @@ +# Copyright (C) 2010-2014 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 +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +r""" This module is a direct forward to the initial +'servermanager' module of ParaView. +""" + +from paraview.servermanager import * + +# for name in dir(servermanager): +# if name != "__file__": +# globals()[name] = getattr(servermanager, name) +# del servermanager +# diff --git a/src/PV_SWIG/VTKWrapping/presentations.py b/src/PV_SWIG/no_wrap/presentations.py similarity index 89% rename from src/PV_SWIG/VTKWrapping/presentations.py rename to src/PV_SWIG/no_wrap/presentations.py index bf1fac34..5169a60d 100644 --- a/src/PV_SWIG/VTKWrapping/presentations.py +++ b/src/PV_SWIG/no_wrap/presentations.py @@ -53,7 +53,6 @@ GAP_COEFFICIENT = 0.0001 # Globals _current_bar = None -_med_field_sep = '@@][@@' # Enumerations @@ -98,11 +97,11 @@ class EntityType: NODE = 0 CELL = 1 - _type2name = {NODE: 'P1', - CELL: 'P0'} + _type2name = {NODE: 'OnPoint', + CELL: 'OnCell'} - _name2type = {'P1': NODE, - 'P0': CELL} + _name2type = {'OnPoint': NODE, + 'OnCell': CELL} _type2pvtype = {NODE: 'POINT_DATA', CELL: 'CELL_DATA'} @@ -172,42 +171,6 @@ class GaussType: # Auxiliary functions - -def get_field_mesh_name(full_field_name): - """Return mesh name of the field by its full name.""" - aList = full_field_name.split('/') - if len(aList) >= 2 : - field_name = full_field_name.split('/')[1] - return field_name - - -def get_field_entity(full_field_name): - """Return entity type of the field by its full name.""" - aList = full_field_name.split(_med_field_sep) - if len(aList) == 2 : - entity_name = full_field_name.split(_med_field_sep)[-1] - entity = EntityType.get_type(entity_name) - return entity - - -def get_field_short_name(full_field_name): - """Return short name of the field by its full name.""" - aList = full_field_name.split('/') - if len(aList) == 4 : - short_name_with_type = full_field_name.split('/')[-1] - short_name = short_name_with_type.split(_med_field_sep)[0] - return short_name - - -def find_mesh_full_name(proxy, short_mesh_name): - """Return full mesh path by short mesh name, if found""" - proxy.UpdatePipeline() - all_mesh_names = get_mesh_full_names(proxy) - for name in all_mesh_names: - if short_mesh_name == get_field_short_name(name): - return name - - def process_prs_for_test(prs, view, picture_name, show_bar=True): """Show presentation and record snapshot image. @@ -280,13 +243,9 @@ def hide_all(view, to_remove=False): def display_only(prs, view=None): """Display only the given presentation in the view.""" - if not view: - view = pvs.GetRenderView() - - rep_list = view.Representations - for rep in rep_list: - if hasattr(rep, 'Visibility'): - rep.Visibility = (rep == prs) + hide_all(view) + if (hasattr(prs, 'Visibility') and prs.Visibility != 1): + prs.Visibility = 1 pvs.Render(view=view) @@ -369,7 +328,6 @@ def get_data_range(proxy, entity, field_name, vector_mode='Magnitude', Data range as [min, max] """ - proxy.UpdatePipeline() entity_data_info = None field_data = proxy.GetFieldDataInformation() @@ -402,7 +360,6 @@ def get_data_range(proxy, entity, field_name, vector_mode='Magnitude', def get_bounds(proxy): """Get bounds of the proxy in 3D.""" - proxy.UpdatePipeline() dataInfo = proxy.GetDataInformation() bounds_info = dataInfo.GetBounds() return bounds_info @@ -410,28 +367,24 @@ def get_bounds(proxy): def get_x_range(proxy): """Get X range of the proxy bounds in 3D.""" - proxy.UpdatePipeline() bounds_info = get_bounds(proxy) return bounds_info[0:2] def get_y_range(proxy): """Get Y range of the proxy bounds in 3D.""" - proxy.UpdatePipeline() bounds_info = get_bounds(proxy) return bounds_info[2:4] def get_z_range(proxy): """Get Z range of the proxy bounds in 3D.""" - proxy.UpdatePipeline() bounds_info = get_bounds(proxy) return bounds_info[4:6] def is_planar_input(proxy): """Check if the given input is planar.""" - proxy.UpdatePipeline() bounds_info = get_bounds(proxy) if (abs(bounds_info[0] - bounds_info[1]) <= FLT_MIN or @@ -444,7 +397,6 @@ def is_planar_input(proxy): def is_data_on_cells(proxy, field_name): """Check the existence of a field on cells with the given name.""" - proxy.UpdatePipeline() cell_data_info = proxy.GetCellDataInformation() return (field_name in cell_data_info.keys()) @@ -457,7 +409,6 @@ def is_empty(proxy): False: otherwise """ - proxy.UpdatePipeline() data_info = proxy.GetDataInformation() nb_cells = data_info.GetNumberOfCells() @@ -468,7 +419,6 @@ def is_empty(proxy): def get_orientation(proxy): """Get the optimum cutting plane orientation for Plot 3D.""" - proxy.UpdatePipeline() orientation = Orientation.XY bounds = get_bounds(proxy) @@ -640,17 +590,14 @@ def get_contours(scalar_range, nb_contours): def get_nb_components(proxy, entity, field_name): """Return number of components for the field.""" - proxy.UpdatePipeline() entity_data_info = None field_data = proxy.GetFieldDataInformation() if field_name in field_data.keys(): entity_data_info = field_data elif entity == EntityType.CELL: - select_cells_with_data(proxy, on_cells=[field_name]) entity_data_info = proxy.GetCellDataInformation() elif entity == EntityType.NODE: - select_cells_with_data(proxy, on_points=[field_name]) entity_data_info = proxy.GetPointDataInformation() nb_comp = None @@ -696,7 +643,6 @@ def get_scale_factor(proxy): def get_default_scale(prs_type, proxy, entity, field_name): """Get default scale factor.""" - proxy.UpdatePipeline() data_range = get_data_range(proxy, entity, field_name) if prs_type == PrsTypeEnum.DEFORMEDSHAPE: @@ -724,7 +670,6 @@ def get_calc_magnitude(proxy, array_entity, array_name): the calculator object. """ - proxy.UpdatePipeline() calculator = None # Transform vector array to scalar array if possible @@ -759,7 +704,6 @@ def get_add_component_calc(proxy, array_entity, array_name): the calculator object. """ - proxy.UpdatePipeline() calculator = None nb_components = get_nb_components(proxy, array_entity, array_name) @@ -783,13 +727,14 @@ def select_all_cells(proxy): Used in creation of mesh/submesh presentation. """ + ### Old API all_cell_types = proxy.CellTypes.Available + all_cell_types = proxy.Entity.Available + ### Old API proxy.CellTypes = all_cell_types + proxy.Entity = all_cell_types proxy.UpdatePipeline() - extractCT = pvs.ExtractCellType() - extractCT.AllGeoTypes = extractCT.GetProperty("GeoTypesInfo")[::2] - extractCT.UpdatePipelineInformation() -def select_cells_with_data(proxy, on_points=[], on_cells=[], on_gauss=[]): +def select_cells_with_data(proxy, on_points=None, on_cells=None): """Select cell types with data. Only cell types with data for the given fields will be selected. @@ -797,36 +742,8 @@ def select_cells_with_data(proxy, on_points=[], on_cells=[], on_gauss=[]): types with data for even one field (from available) will be selected. """ - if not proxy.GetProperty("FieldsTreeInfo"): - return - - proxy.UpdatePipeline() if not hasattr(proxy, 'Entity'): - fields_info = proxy.GetProperty("FieldsTreeInfo")[::2] - arr_name_with_dis=[elt.split("/")[-1] for elt in fields_info] - - proxy.AllArrays = [] - proxy.UpdatePipeline() - - fields = [] - for name in on_gauss: - fields.append(name+_med_field_sep+'GAUSS') - for name in on_cells: - fields.append(name+_med_field_sep+'P0') - for name in on_points: - fields.append(name+_med_field_sep+'P1') - - field_list = [] - for name in fields: - if arr_name_with_dis.count(name) > 0: - index = arr_name_with_dis.index(name) - field_list.append(fields_info[index]) - - proxy.AllArrays = field_list - proxy.UpdatePipeline() - return len(field_list) != 0 - - # TODO: VTN. Looks like this code is out of date. + return #all_cell_types = proxy.CellTypes.Available all_cell_types = proxy.Entity.Available @@ -869,9 +786,63 @@ def select_cells_with_data(proxy, on_points=[], on_cells=[], on_gauss=[]): proxy.Entity = cell_types_on proxy.UpdatePipeline() -def if_possible(proxy, field_name, entity, prs_type, extrGrps=None): - """Check if the presentation creation is possible on the given field.""" + +def extract_groups_for_field(proxy, field_name, field_entity, force=False): + """Exctract only groups which have the field. + + Arguments: + proxy: the pipeline object, containig data + field_name: the field name + field_entity: the field entity + force: if True - ExtractGroup object will be created in any case + + Returns: + ExtractGroup object: if not all groups have the field or + the force argument is true + The initial proxy: if no groups had been filtered. + + """ + source = proxy + + # Remember the state + initial_groups = list(proxy.Groups) + + # Get data information for the field entity + entity_data_info = None + field_data = proxy.GetFieldDataInformation() + + if field_name in field_data.keys(): + entity_data_info = field_data + elif field_entity == EntityType.CELL: + entity_data_info = proxy.GetCellDataInformation() + elif field_entity == EntityType.NODE: + entity_data_info = proxy.GetPointDataInformation() + + # Collect groups for extraction + groups_to_extract = [] + + for group in initial_groups: + proxy.Groups = [group] + proxy.UpdatePipeline() + if field_name in entity_data_info.keys(): + groups_to_extract.append(group) + + # Restore state + proxy.Groups = initial_groups proxy.UpdatePipeline() + + # Extract groups if necessary + if force or (len(groups_to_extract) < len(initial_groups)): + extract_group = pvs.ExtractGroup(proxy) + extract_group.Groups = groups_to_extract + extract_group.UpdatePipeline() + source = extract_group + + return source + + +def if_possible(proxy, field_name, entity, prs_type): + """Check if the presentation creation is possible on the given field.""" result = True if (prs_type == PrsTypeEnum.DEFORMEDSHAPE or prs_type == PrsTypeEnum.DEFORMEDSHAPESCALARMAP or @@ -883,7 +854,7 @@ def if_possible(proxy, field_name, entity, prs_type, extrGrps=None): result = (entity == EntityType.CELL or field_name in proxy.QuadraturePointArrays.Available) elif (prs_type == PrsTypeEnum.MESH): - result = len(get_group_names(extrGrps)) > 0 + result = len(get_group_names(proxy, field_name, entity)) > 0 return result @@ -981,28 +952,40 @@ def get_group_entity(full_group_name): def get_group_short_name(full_group_name): """Return short name of the group by its full name.""" - short_name = re.sub('^GRP_', '', full_group_name) - return short_name + aList = full_group_name.split('/') + if len(aList) >= 4 : + short_name = full_group_name.split('/')[3] + return short_name -def get_mesh_full_names(proxy): +def get_mesh_names(proxy): """Return all mesh names in the given proxy as a set.""" - proxy.UpdatePipeline() - fields = proxy.GetProperty("FieldsTreeInfo")[::2] - mesh_full_names = set([item for item in fields if get_field_mesh_name(item) == get_field_short_name(item)]) - return mesh_full_names + groups = proxy.Groups.Available + mesh_names = set([get_group_mesh_name(item) for item in groups]) + return mesh_names -def get_group_names(extrGrps): - """Return full names of all groups of the given 'ExtractGroup' filter object. + +def get_group_names(proxy, mesh_name, entity, wo_nogroups=False): + """Return full names of all groups of the given entity type + from the mesh with the given name as a list. """ - group_names = filter(lambda x:x[:4]=="GRP_",list(extrGrps.GetProperty("GroupsFlagsInfo")[::2])) + groups = proxy.Groups.Available + + condition = lambda item: (get_group_mesh_name(item) == mesh_name and + get_group_entity(item) == entity) + group_names = [item for item in groups if condition(item)] + + if wo_nogroups: + # Remove "No_Group" group + not_no_group = lambda item: get_group_short_name(item) != "No_Group" + group_names = filter(not_no_group, group_names) + return group_names def get_time(proxy, timestamp_nb): """Get time value by timestamp number.""" - proxy.UpdatePipeline() # Check timestamp number timestamps = [] @@ -1011,15 +994,12 @@ def get_time(proxy, timestamp_nb): elif (hasattr(proxy.Input, 'TimestepValues')): timestamps = proxy.Input.TimestepValues.GetData() - length = len(timestamps) - if (timestamp_nb > 0 and (timestamp_nb - 1) not in xrange(length) ) or (timestamp_nb < 0 and -timestamp_nb > length): + if ((timestamp_nb - 1) not in xrange(len(timestamps))): raise ValueError("Timestamp number is out of range: " + str(timestamp_nb)) # Return time value - if timestamp_nb > 0: - return timestamps[timestamp_nb - 1] - else: - return timestamps[timestamp_nb] + return timestamps[timestamp_nb - 1] + def create_prs(prs_type, proxy, field_entity, field_name, timestamp_nb): """Auxiliary function. @@ -1029,7 +1009,6 @@ def create_prs(prs_type, proxy, field_entity, field_name, timestamp_nb): Set the presentation properties like visu.CreatePrsForResult() do. """ - proxy.UpdatePipeline() prs = None if prs_type == PrsTypeEnum.SCALARMAP: @@ -1081,7 +1060,6 @@ def ScalarMapOnField(proxy, entity, field_name, timestamp_nb, Scalar Map as representation object. """ - proxy.UpdatePipeline() # We don't need mesh parts with no data on them if entity == EntityType.NODE: select_cells_with_data(proxy, on_points=[field_name]) @@ -1099,8 +1077,12 @@ def ScalarMapOnField(proxy, entity, field_name, timestamp_nb, pvs.GetRenderView().ViewTime = time_value pvs.UpdatePipeline(time_value, proxy) + # Extract only groups with data for the field + new_proxy = extract_groups_for_field(proxy, field_name, entity, + force=True) + # Get Scalar Map representation object - scalarmap = pvs.GetRepresentation(proxy) + scalarmap = pvs.GetRepresentation(new_proxy) # Get lookup table lookup_table = get_lookup_table(field_name, nb_components, vector_mode) @@ -1152,12 +1134,6 @@ def CutPlanesOnField(proxy, entity, field_name, timestamp_nb, Cut Planes as representation object. """ - proxy.UpdatePipeline() - if entity == EntityType.NODE: - select_cells_with_data(proxy, on_points=[field_name]) - else: - select_cells_with_data(proxy, on_cells=[field_name]) - # Check vector mode nb_components = get_nb_components(proxy, entity, field_name) check_vector_mode(vector_mode, nb_components) @@ -1248,12 +1224,6 @@ def CutLinesOnField(proxy, entity, field_name, timestamp_nb, (Cut Lines as representation object, list of 'PlotOverLine') otherwise """ - proxy.UpdatePipeline() - if entity == EntityType.NODE: - select_cells_with_data(proxy, on_points=[field_name]) - else: - select_cells_with_data(proxy, on_cells=[field_name]) - # Check vector mode nb_components = get_nb_components(proxy, entity, field_name) check_vector_mode(vector_mode, nb_components) @@ -1376,12 +1346,6 @@ def CutSegmentOnField(proxy, entity, field_name, timestamp_nb, Cut Segment as 3D representation object. """ - proxy.UpdatePipeline() - if entity == EntityType.NODE: - select_cells_with_data(proxy, on_points=[field_name]) - else: - select_cells_with_data(proxy, on_cells=[field_name]) - # Check vector mode nb_components = get_nb_components(proxy, entity, field_name) check_vector_mode(vector_mode, nb_components) @@ -1450,12 +1414,6 @@ def VectorsOnField(proxy, entity, field_name, timestamp_nb, Vectors as representation object. """ - proxy.UpdatePipeline() - if entity == EntityType.NODE: - select_cells_with_data(proxy, on_points=[field_name]) - else: - select_cells_with_data(proxy, on_cells=[field_name]) - # Check vector mode nb_components = get_nb_components(proxy, entity, field_name) check_vector_mode(vector_mode, nb_components) @@ -1468,7 +1426,8 @@ def VectorsOnField(proxy, entity, field_name, timestamp_nb, pvs.UpdatePipeline(time_value, proxy) # Extract only groups with data for the field - source = proxy + new_proxy = extract_groups_for_field(proxy, field_name, entity) + source = new_proxy # Cell centers if is_data_on_cells(proxy, field_name): @@ -1511,7 +1470,7 @@ def VectorsOnField(proxy, entity, field_name, timestamp_nb, glyph.SetScaleFactor = scale_factor else: def_scale = get_default_scale(PrsTypeEnum.DEFORMEDSHAPE, - proxy, entity, field_name) + new_proxy, entity, field_name) glyph.SetScaleFactor = def_scale glyph.UpdatePipeline() @@ -1569,7 +1528,6 @@ def DeformedShapeOnField(proxy, entity, field_name, Defromed Shape as representation object. """ - proxy.UpdatePipeline() # We don't need mesh parts with no data on them if entity == EntityType.NODE: select_cells_with_data(proxy, on_points=[field_name]) @@ -1587,8 +1545,11 @@ def DeformedShapeOnField(proxy, entity, field_name, pvs.GetRenderView().ViewTime = time_value pvs.UpdatePipeline(time_value, proxy) + # Extract only groups with data for the field + new_proxy = extract_groups_for_field(proxy, field_name, entity) + # Do merge - source = pvs.MergeBlocks(proxy) + source = pvs.MergeBlocks(new_proxy) # Cell data to point data if is_data_on_cells(proxy, field_name): @@ -1667,7 +1628,6 @@ def DeformedShapeAndScalarMapOnField(proxy, entity, field_name, Defromed Shape And Scalar Map as representation object. """ - proxy.UpdatePipeline() # We don't need mesh parts with no data on them on_points = [] on_cells = [] @@ -1683,12 +1643,10 @@ def DeformedShapeAndScalarMapOnField(proxy, entity, field_name, else: on_cells.append(scalar_field_name) - nb_components = get_nb_components(proxy, entity, field_name) - - # Select fields select_cells_with_data(proxy, on_points, on_cells) # Check vector mode + nb_components = get_nb_components(proxy, entity, field_name) check_vector_mode(vector_mode, nb_components) # Get time value @@ -1705,8 +1663,11 @@ def DeformedShapeAndScalarMapOnField(proxy, entity, field_name, scalar_field_entity = entity scalar_field = field_name + # Extract only groups with data for the field + new_proxy = extract_groups_for_field(proxy, field_name, entity) + # Do merge - source = pvs.MergeBlocks(proxy) + source = pvs.MergeBlocks(new_proxy) # Cell data to point data if is_data_on_cells(proxy, field_name): @@ -1728,7 +1689,7 @@ def DeformedShapeAndScalarMapOnField(proxy, entity, field_name, warp_vector.ScaleFactor = scale_factor else: def_scale = get_default_scale(PrsTypeEnum.DEFORMEDSHAPE, - proxy, entity, field_name) + new_proxy, entity, field_name) warp_vector.ScaleFactor = def_scale # Get Defromed Shape And Scalar Map representation object @@ -1792,7 +1753,6 @@ def Plot3DOnField(proxy, entity, field_name, timestamp_nb, Plot 3D as representation object. """ - proxy.UpdatePipeline() # We don't need mesh parts with no data on them if entity == EntityType.NODE: select_cells_with_data(proxy, on_points=[field_name]) @@ -1810,8 +1770,11 @@ def Plot3DOnField(proxy, entity, field_name, timestamp_nb, pvs.GetRenderView().ViewTime = time_value pvs.UpdatePipeline(time_value, proxy) + # Extract only groups with data for the field + new_proxy = extract_groups_for_field(proxy, field_name, entity) + # Do merge - merge_blocks = pvs.MergeBlocks(proxy) + merge_blocks = pvs.MergeBlocks(new_proxy) merge_blocks.UpdatePipeline() poly_data = None @@ -1950,7 +1913,6 @@ def IsoSurfacesOnField(proxy, entity, field_name, timestamp_nb, Iso Surfaces as representation object. """ - proxy.UpdatePipeline() # We don't need mesh parts with no data on them if entity == EntityType.NODE: select_cells_with_data(proxy, on_points=[field_name]) @@ -1968,8 +1930,11 @@ def IsoSurfacesOnField(proxy, entity, field_name, timestamp_nb, pvs.GetRenderView().ViewTime = time_value pvs.UpdatePipeline(time_value, proxy) + # Extract only groups with data for the field + new_proxy = extract_groups_for_field(proxy, field_name, entity) + # Do merge - source = pvs.MergeBlocks(proxy) + source = pvs.MergeBlocks(new_proxy) # Transform cell data into point data if necessary if is_data_on_cells(proxy, field_name): @@ -2070,14 +2035,11 @@ def GaussPointsOnField(proxy, entity, field_name, Gauss Points as representation object. """ - proxy.UpdatePipeline() # We don't need mesh parts with no data on them - on_gauss = select_cells_with_data(proxy, on_gauss=[field_name]) - if not on_gauss: - if entity == EntityType.NODE: - select_cells_with_data(proxy, on_points=[field_name]) - else: - select_cells_with_data(proxy, on_cells=[field_name]) + if entity == EntityType.NODE: + select_cells_with_data(proxy, on_points=[field_name]) + else: + select_cells_with_data(proxy, on_cells=[field_name]) # Check vector mode nb_components = get_nb_components(proxy, entity, field_name) @@ -2090,12 +2052,16 @@ def GaussPointsOnField(proxy, entity, field_name, pvs.GetRenderView().ViewTime = time_value proxy.UpdatePipeline(time=time_value) - source = proxy + # Extract only groups with data for the field + source = extract_groups_for_field(proxy, field_name, entity) + + # Quadrature point arrays + qp_arrays = proxy.QuadraturePointArrays.Available # If no quadrature point array is passed, use cell centers - if on_gauss: + if field_name in qp_arrays: generate_qp = pvs.GenerateQuadraturePoints(source) - generate_qp.QuadratureSchemeDef = ['CELLS', 'ELGA@0'] + generate_qp.SelectSourceArray = ['CELLS', 'ELGA_Offset'] source = generate_qp else: # Cell centers @@ -2243,11 +2209,6 @@ def GaussPointsOnField1(proxy, entity, field_name, Gauss Points as representation object. """ - proxy.UpdatePipeline() - select_cells_with_data(proxy, on_gauss=[field_name]) - - nb_components = get_nb_components(proxy, entity, field_name) - # Get time value time_value = get_time(proxy, timestamp_nb) @@ -2263,6 +2224,14 @@ def GaussPointsOnField1(proxy, entity, field_name, gausspnt = pvs.GetRepresentation(source) # Get lookup table + entity_data_info = None + point_data_info = source.GetPointDataInformation() + if field_name in point_data_info.keys(): + entity_data_info = point_data_info + else: + entity_data_info = source.GetCellDataInformation() + nb_components = entity_data_info[field_name].GetNumberOfComponents() + lookup_table = get_lookup_table(field_name, nb_components, vector_mode) # Set field range if necessary @@ -2365,7 +2334,6 @@ def StreamLinesOnField(proxy, entity, field_name, timestamp_nb, Stream Lines as representation object. """ - proxy.UpdatePipeline() # We don't need mesh parts with no data on them if entity == EntityType.NODE: select_cells_with_data(proxy, on_points=[field_name]) @@ -2383,8 +2351,11 @@ def StreamLinesOnField(proxy, entity, field_name, timestamp_nb, pvs.GetRenderView().ViewTime = time_value pvs.UpdatePipeline(time_value, proxy) + # Extract only groups with data for the field + new_proxy = extract_groups_for_field(proxy, field_name, entity) + # Do merge - source = pvs.MergeBlocks(proxy) + source = pvs.MergeBlocks(new_proxy) # Cell data to point data if is_data_on_cells(proxy, field_name): @@ -2419,7 +2390,7 @@ def StreamLinesOnField(proxy, entity, field_name, timestamp_nb, lookup_table = get_lookup_table(field_name, nb_components, vector_mode) # Set field range if necessary - data_range = get_data_range(proxy, entity, + data_range = get_data_range(new_proxy, entity, field_name, vector_mode) lookup_table.LockScalarRange = 1 lookup_table.RGBPoints = [data_range[0], 0, 0, 1, data_range[1], 1, 0, 0] @@ -2447,25 +2418,21 @@ def MeshOnEntity(proxy, mesh_name, entity): Arguments: proxy -- the pipeline object, containig data - mesh_name -- the full or short name of mesh field + mesh_name -- the mesh name + entity -- the entity type Returns: Submesh as representation object of the given source. """ - proxy.UpdatePipeline() - mesh_full_name = None - aList = mesh_name.split('/') - if len(aList) >= 2: - mesh_full_name = mesh_name - else: - mesh_full_name = find_mesh_full_name(proxy, mesh_name) - if not mesh_full_name: - raise RuntimeError, "The given mesh name was not found" - # Select only the given mesh - proxy.AllArrays = [] - proxy.UpdatePipeline() - proxy.AllArrays = [mesh_full_name] + # Select all cell types + select_all_cells(proxy) + + # Get subset of groups on the given entity + subset = get_group_names(proxy, mesh_name, entity) + + # Select only groups of the given entity type + proxy.Groups = subset proxy.UpdatePipeline() # Get representation object if the submesh is not empty @@ -2478,42 +2445,42 @@ def MeshOnEntity(proxy, mesh_name, entity): return prs -def MeshOnGroup(proxy, extrGroups, group_name): +def MeshOnGroup(proxy, group_name): """Creates submesh on the group. Arguments: proxy -- the pipeline object, containig data group_name -- the full group name - extrGroups -- all extracted groups object Returns: Representation object of the given source with single group selected. """ - proxy.UpdatePipeline() - # Deselect all groups - extrGroups.AllGroups = [] - extrGroups.UpdatePipelineInformation() + # Select all cell types + select_all_cells(proxy) + # Select only the group with the given name - extrGroups.AllGroups = [group_name] - extrGroups.UpdatePipelineInformation() + one_group = [group_name] + proxy.Groups = one_group + proxy.UpdatePipeline() # Get representation object if the submesh is not empty prs = None # Check if the group was set - if len(extrGroups.AllGroups) == 1 and \ - extrGroups.AllGroups[0] == group_name: + if proxy.Groups.GetData() == one_group: + group_entity = get_group_entity(group_name) # Check if the submesh is not empty - nb_points = proxy.GetDataInformation().GetNumberOfPoints() - nb_cells = proxy.GetDataInformation().GetNumberOfCells() - - if nb_points or nb_cells: -# prs = pvs.GetRepresentation(proxy) - prs = pvs.Show() + nb_items = 0 + if group_entity == EntityType.NODE: + nb_items = proxy.GetDataInformation().GetNumberOfPoints() + elif group_entity == EntityType.CELL: + nb_items = proxy.GetDataInformation().GetNumberOfCells() + + if nb_items: + prs = pvs.GetRepresentation(proxy) prs.ColorArrayName = '' - display_only(prs) return prs @@ -2536,7 +2503,8 @@ def CreatePrsForFile(paravis_instance, file_name, prs_types, print "Import " + file_name.split(os.sep)[-1] + "..." try: - proxy = pvs.MEDReader(FileName=file_name) + paravis_instance.ImportFile(file_name) + proxy = pvs.GetActiveSource() if proxy is None: print "FAILED" else: @@ -2552,6 +2520,7 @@ def CreatePrsForFile(paravis_instance, file_name, prs_types, CreatePrsForProxy(proxy, view, prs_types, picture_dir, picture_ext) + def CreatePrsForProxy(proxy, view, prs_types, picture_dir, picture_ext): """Build presentations of the given types for all fields of the proxy. @@ -2566,9 +2535,10 @@ def CreatePrsForProxy(proxy, view, prs_types, picture_dir, picture_ext): picture_ext: graphics files extension (determines file type) """ - proxy.UpdatePipeline() # List of the field names - fields_info = proxy.GetProperty("FieldsTreeInfo")[::2] + field_names = list(proxy.PointArrays.GetData()) + nb_on_nodes = len(field_names) + field_names.extend(proxy.CellArrays.GetData()) # Add path separator to the end of picture path if necessery if not picture_dir.endswith(os.sep): @@ -2576,60 +2546,77 @@ def CreatePrsForProxy(proxy, view, prs_types, picture_dir, picture_ext): # Mesh Presentation if PrsTypeEnum.MESH in prs_types: + # Create Mesh presentation. Build all possible submeshes. + + # Remember the current state + groups = list(proxy.Groups) + # Iterate on meshes - mesh_names = get_mesh_full_names(proxy) + mesh_names = get_mesh_names(proxy) for mesh_name in mesh_names: - # Build mesh field presentation - print "Creating submesh for '" + get_field_short_name(mesh_name) + "' mesh... " - prs = MeshOnEntity(proxy, mesh_name, None) - if prs is None: - print "FAILED" - continue - else: - print "OK" - # Construct image file name - pic_name = picture_dir + get_field_short_name(mesh_name) + "." + picture_ext - - # Show and dump the presentation into a graphics file - process_prs_for_test(prs, view, pic_name, False) - - # Create Mesh presentation. Build all groups. - extGrp = pvs.ExtractGroup() - extGrp.UpdatePipelineInformation() - if if_possible(proxy, None, None, PrsTypeEnum.MESH, extGrp): - for group in get_group_names(extGrp): - print "Creating submesh on group " + get_group_short_name(group) + "... " - prs = MeshOnGroup(proxy, extGrp, group) + # Build mesh on nodes and cells + for entity in (EntityType.NODE, EntityType.CELL): + entity_name = EntityType.get_name(entity) + if if_possible(proxy, mesh_name, entity, PrsTypeEnum.MESH): + print "Creating submesh on " + entity_name + " for '" + mesh_name + "' mesh... " + prs = MeshOnEntity(proxy, mesh_name, entity) if prs is None: print "FAILED" continue else: print "OK" # Construct image file name - pic_name = picture_dir + get_group_short_name(group) + "." + picture_ext - + pic_name = picture_dir + mesh_name + "_" + entity_name + "." + picture_ext + # Show and dump the presentation into a graphics file process_prs_for_test(prs, view, pic_name, False) - # Presentations on fields - for field in fields_info: - field_name = get_field_short_name(field) - # Ignore mesh presentation - if field_name == get_field_mesh_name(field): - continue - field_entity = get_field_entity(field) - # Clear fields selection state - proxy.AllArrays = [] + # Build submesh on all groups of the mesh + mesh_groups = get_group_names(proxy, mesh_name, + entity, wo_nogroups=True) + for group in mesh_groups: + print "Creating submesh on group " + group + "... " + prs = MeshOnGroup(proxy, group) + if prs is None: + print "FAILED" + continue + else: + print "OK" + # Construct image file name + pic_name = picture_dir + group.replace('/', '_') + "." + picture_ext + + # Show and dump the presentation into a graphics file + process_prs_for_test(prs, view, pic_name, False) + + # Restore the state + proxy.Groups = groups proxy.UpdatePipeline() + + # Presentations on fields + for (i, field_name) in enumerate(field_names): # Select only the current field: # necessary for getting the right timestamps - proxy.AllArrays = field - proxy.UpdatePipeline() + cell_arrays = proxy.CellArrays.GetData() + point_arrays = proxy.PointArrays.GetData() + field_entity = None + if (i >= nb_on_nodes): + field_entity = EntityType.CELL + proxy.PointArrays.DeselectAll() + proxy.CellArrays = [field_name] + else: + field_entity = EntityType.NODE + proxy.CellArrays.DeselectAll() + proxy.PointArrays = [field_name] # Get timestamps - entity_data_info = proxy.GetCellDataInformation() + proxy.UpdatePipelineInformation() timestamps = proxy.TimestepValues.GetData() + # Restore fields selection state + proxy.CellArrays = cell_arrays + proxy.PointArrays = point_arrays + proxy.UpdatePipelineInformation() + for prs_type in prs_types: # Ignore mesh presentation if prs_type == PrsTypeEnum.MESH: @@ -2647,12 +2634,6 @@ def CreatePrsForProxy(proxy, view, prs_types, picture_dir, picture_ext): for timestamp_nb in xrange(1, len(timestamps) + 1): time = timestamps[timestamp_nb - 1] - if (time == 0.0): - scalar_range = get_data_range(proxy, field_entity, - field_name, cut_off=True) - # exclude time stamps with null lenght of scalar range - if (scalar_range[0] == scalar_range[1]): - continue print "Creating " + prs_name + " on " + field_name + ", time = " + str(time) + "... " prs = create_prs(prs_type, proxy, field_entity, field_name, timestamp_nb) @@ -2667,4 +2648,3 @@ def CreatePrsForProxy(proxy, view, prs_types, picture_dir, picture_ext): # Show and dump the presentation into a graphics file process_prs_for_test(prs, view, pic_name) - return diff --git a/src/PV_SWIG/no_wrap/pvsimple.py b/src/PV_SWIG/no_wrap/pvsimple.py new file mode 100644 index 00000000..4890ed1b --- /dev/null +++ b/src/PV_SWIG/no_wrap/pvsimple.py @@ -0,0 +1,50 @@ +# Copyright (C) 2010-2014 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 +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# +# Author: Adrien Bruneton (CEA) + +r""" This module is a direct forward to the initial 'simple' module of ParaView. +On top of that it also establishes a connection to a valid PVServer whose address +is provided by the PARAVIS engine. +""" + +from paraview.simple import * +import paravis ## Triggers the "FindOrLoadCompo(PARAVIS)" + +def __my_log(msg): + print "[PARAVIS] %s" % msg + +def SalomeConnectToPVServer(): + __my_log("Connecting to PVServer ...") + server_url = "" + try: + server_url = paravis.myParavisEngine.FindOrStartPVServer(0) + # Extract host and port from URL: + a = server_url.split(':') + b = a[1].split('//') + host, port = b[-1], int(a[-1]) + Connect(host, port) + except Exception as e: + __my_log("*******************************************") + __my_log("** Could not connect to a running PVServer!") + __my_log("*******************************************") + raise e + __my_log("Connected to %s!" % server_url) + +# Automatically connect to the right PVServer: +SalomeConnectToPVServer() diff --git a/src/PV_SWIG/paravis.py b/src/PV_SWIG/paravis.py index 52f0c47f..da1119a1 100644 --- a/src/PV_SWIG/paravis.py +++ b/src/PV_SWIG/paravis.py @@ -29,30 +29,69 @@ import SALOMEDS import SALOME_ModuleCatalog from omniORB import CORBA from time import sleep -import salome +from salome import * + +myORB = None +myNamingService = None +myLifeCycleCORBA = None +myNamingService = None +myLocalStudyManager = None +myLocalStudy = None +myLocalParavis = None +myDelay = None +mySession = None ## Initialization of paravis server -def Initialize(theDelay) : - mySession = None +def Initialize(theORB, theNamingService, theLifeCycleCORBA, theStudyManager, theStudy, theDelay) : + global myORB, myNamingService, myLifeCycleCORBA, myLocalStudyManager, myLocalStudy + global mySession, myDelay + myDelay = theDelay + myORB = theORB + myNamingService = theNamingService + myLifeCycleCORBA = theLifeCycleCORBA + myLocalStudyManager = theStudyManager while mySession == None: - mySession = salome.naming_service.Resolve("/Kernel/Session") + mySession = myNamingService.Resolve("/Kernel/Session") mySession = mySession._narrow(SALOME.Session) mySession.GetInterface() - sleep(theDelay) - myLocalParavis = salome.lcc.FindOrLoadComponent("FactoryServer", "PARAVIS") - myLocalStudy = salome.myStudy + myDelay = theDelay + sleep(myDelay) + myLocalParavis = myLifeCycleCORBA.FindOrLoadComponent("FactoryServer", "PARAVIS") + myLocalStudy = theStudy myLocalParavis.SetCurrentStudy(myLocalStudy) - myLocalParavis.ActivateModule() ## TO BE DISCUSSED! + myLocalParavis.ActivateModule() return myLocalParavis -def StartOrRetrievePVServerURL(): - """ To be completed!!! Should invoke IDL methods from 'PARAVIS' module""" - return "localhost" -# def ImportFile(theFileName): -# "Import a file of any format supported by ParaView" -# myParavis.ImportFile(theFileName) +def ImportFile(theFileName): + "Import a file of any format supported by ParaView" + myParavis.ImportFile(theFileName) + + +def createFunction(theName): + "Create function - constructor of Paravis object" + def MyFunction(): + return myParavis.CreateClass(theName) + return MyFunction + + +def createConstructors(): + "Create constructor functions according to list of extracted classes" + g = globals() + aClassNames = myParavis.GetClassesList(); + for aName in aClassNames: + g[aName] = createFunction(aName) + +## Initialize of a PARAVIS interface +myParavis = Initialize(orb, naming_service,lcc,myStudyManager,myStudy, 2) + +## Initialize constructor functions +createConstructors() + +## Initialize Paravis static objects +vtkSMObject = vtkSMObject() +vtkProcessModule = vtkProcessModule() +vtkPVPythonModule = vtkPVPythonModule() +vtkSMProxyManager = vtkSMProxyManager() -## Initialize PARAVIS interface -myParavisEngine = Initialize(2) diff --git a/src/PV_SWIG/paravisSM.py b/src/PV_SWIG/paravisSM.py index 04775112..b82ee0f5 100644 --- a/src/PV_SWIG/paravisSM.py +++ b/src/PV_SWIG/paravisSM.py @@ -17,14 +17,2998 @@ # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # -r""" This module is a direct forward to the initial -'servermanager' module of ParaView. +r"""servermanager is a module for using paraview server manager in Python. +One can always use the server manager API directly. However, this module +provides an interface easier to use from Python by wrapping several VTK +classes around Python classes. + +Note that, upon load, this module will create several sub-modules: sources, +filters and rendering. These modules can be used to instantiate specific +proxy types. For a list, try "dir(servermanager.sources)" + +A simple example: + from paraview.servermanager import * + + # Creates a new built-in session and makes it the active session. + Connect() + + # Creates a new render view on the active session. + renModule = CreateRenderView() + + # Create a new sphere proxy on the active session and register it + # in the sources group. + sphere = sources.SphereSource(registrationGroup="sources", ThetaResolution=16, PhiResolution=32) + + # Create a representation for the sphere proxy and adds it to the render + # module. + display = CreateRepresentation(sphere, renModule) + + renModule.StillRender() """ -from paraview.servermanager import * -# for name in dir(servermanager): -# if name != "__file__": -# globals()[name] = getattr(servermanager, name) -# del servermanager -# + +import re, os, new, sys +from paravis import * + +# VTN: Avoid paraview.* instructions in this file. +# It leads to problems during execution. + +def _wrap_property(proxy, smproperty): + """ Internal function. + Given a server manager property and its domains, returns the + appropriate python object. + """ + property = None + if smproperty.IsA("vtkSMStringVectorProperty"): + al = smproperty.GetDomain("array_list") + if al and al.IsA("vtkSMArraySelectionDomain") and \ + smproperty.GetRepeatable(): + property = ArrayListProperty(proxy, smproperty) + elif al and al.IsA("vtkSMArrayListDomain") and smproperty.GetNumberOfElements() == 5: + property = ArraySelectionProperty(proxy, smproperty) + else: + iter = smproperty.NewDomainIterator() + isFileName = False + while not iter.IsAtEnd(): + # Refer to BUG #9710 to see why optional domains need to be + # ignored. + if iter.GetDomain().IsA("vtkSMFileListDomain") and \ + iter.GetDomain().GetIsOptional() == 0 : + isFileName = True + break + iter.Next() + iter.UnRegister(None) + if isFileName: + property = FileNameProperty(proxy, smproperty) + elif _make_name_valid(smproperty.GetXMLLabel()) == 'ColorArrayName': + property = ColorArrayProperty(proxy, smproperty) + else: + property = VectorProperty(proxy, smproperty) + elif smproperty.IsA("vtkSMVectorProperty"): + if smproperty.IsA("vtkSMIntVectorProperty") and \ + smproperty.GetDomain("enum"): + property = EnumerationProperty(proxy, smproperty) + else: + property = VectorProperty(proxy, smproperty) + elif smproperty.IsA("vtkSMInputProperty"): + property = InputProperty(proxy, smproperty) + elif smproperty.IsA("vtkSMProxyProperty"): + property = ProxyProperty(proxy, smproperty) + else: + property = Property(proxy, smproperty) + return property + +class Proxy(object): + """Proxy for a server side object. A proxy manages the lifetime of + one or more server manager objects. It also provides an interface + to set and get the properties of the server side objects. These + properties are presented as Python properties. For example, + you can set a property Foo using the following: + proxy.Foo = (1,2) + or + proxy.Foo.SetData((1,2)) + or + proxy.Foo[0:2] = (1,2) + For more information, see the documentation of the property which + you can obtain with + help(proxy.Foo). + + This class also provides an iterator which can be used to iterate + over all properties. + eg: + proxy = Proxy(proxy=smproxy) + for property in proxy: + print property + + For advanced users: + This is a python class that wraps a vtkSMProxy.. Makes it easier to + set/get properties. + Instead of: + proxy.GetProperty("Foo").SetElement(0, 1) + proxy.GetProperty("Foo").SetElement(0, 2) + you can do: + proxy.Foo = (1,2) + or + proxy.Foo.SetData((1,2)) + or + proxy.Foo[0:2] = (1,2) + Instead of: + proxy.GetProperty("Foo").GetElement(0) + you can do: + proxy.Foo.GetData()[0] + or + proxy.Foo[0] + For proxy properties, you can use append: + proxy.GetProperty("Bar").AddProxy(foo) + you can do: + proxy.Bar.append(foo) + Properties support most of the list API. See VectorProperty and + ProxyProperty documentation for details. + + Please note that some of the methods accessible through the Proxy + class are not listed by help() because the Proxy objects forward + unresolved attributes to the underlying object. To get the full list, + see also dir(proxy.SMProxy). See also the doxygen based documentation + of the vtkSMProxy C++ class. + """ + + def __init__(self, **args): + """ Default constructor. It can be used to initialize properties + by passing keyword arguments where the key is the name of the + property. In addition registrationGroup and registrationName (optional) + can be specified (as keyword arguments) to automatically register + the proxy with the proxy manager. """ + self.add_attribute('Observed', None) + self.add_attribute('ObserverTag', -1) + self.add_attribute('_Proxy__Properties', {}) + self.add_attribute('_Proxy__LastAttrName', None) + self.add_attribute('SMProxy', None) + self.add_attribute('Port', 0) + + if 'port' in args: + self.Port = args['port'] + del args['port'] + + update = True + if 'no_update' in args: + if args['no_update']: + update = False + del args['no_update'] + + if 'proxy' in args: + self.InitializeFromProxy(args['proxy']) + del args['proxy'] + else: + self.Initialize(None, update) + if 'registrationGroup' in args: + registrationGroup = args['registrationGroup'] + del args['registrationGroup'] + registrationName = self.SMProxy.GetGlobalIDAsString() + if 'registrationName' in args: + registrationName = args['registrationName'] + del args['registrationName'] + pxm = ProxyManager() + pxm.RegisterProxy(registrationGroup, registrationName, self.SMProxy) + if update: + self.UpdateVTKObjects() + for key in args.keys(): + setattr(self, key, args[key]) + # Visit all properties so that they are created + for prop in self: + pass + + def __setattr__(self, name, value): + try: + setter = getattr(self.__class__, name) + setter = setter.__set__ + except AttributeError: + if not hasattr(self, name): + raise AttributeError("Attribute %s does not exist. " % name + + " This class does not allow addition of new attributes to avoid " + + "mistakes due to typos. Use add_attribute() if you really want " + + "to add this attribute.") + self.__dict__[name] = value + else: + setter(self, value) + + def add_attribute(self, name, value): + self.__dict__[name] = value + + def __del__(self): + """Destructor. Cleans up all observers as well as remove + the proxy from the _pyproxies dictionary""" + # Make sure that we remove observers we added + if self.Observed: + observed = self.Observed + tag = self.ObserverTag + self.Observed = None + self.ObserverTag = -1 + observed.RemoveObserver(tag) + if _pyproxies and self.SMProxy and (self.SMProxy, self.Port) in _pyproxies: + del _pyproxies[(self.SMProxy, self.Port)] + + def InitializeFromProxy(self, aProxy, update=True): + """Constructor. Assigns proxy to self.SMProxy, updates the server + object as well as register the proxy in _pyproxies dictionary.""" + import weakref + self.SMProxy = aProxy + if update: + self.SMProxy.UpdateVTKObjects() + _pyproxies[(self.SMProxy, self.Port)] = weakref.ref(self) + + def Initialize(self): + "Overridden by the subclass created automatically" + pass + + def __eq__(self, other): + "Returns true if the underlying SMProxies are the same." + if isinstance(other, Proxy): + try: + if self.Port != other.Port: + return False + except: + pass + ## VSV using IsSame instead == + return self.SMProxy.IsSame(other.SMProxy) + return self.SMProxy.IsSame(other) + + def __ne__(self, other): + "Returns false if the underlying SMProxies are the same." + return not self.__eq__(other) + + def __iter__(self): + "Creates an iterator for the properties." + return PropertyIterator(self) + + def SetPropertyWithName(self, pname, arg): + """Generic method for setting the value of a property.""" + prop = self.GetProperty(pname) + if prop is None: + raise RuntimeError, "Property %s does not exist. Please check the property name for typos." % pname + prop.SetData(arg) + + def GetPropertyValue(self, name): + """Returns a scalar for properties with 1 elements, the property + itself for vectors.""" + p = self.GetProperty(name) + if isinstance(p, VectorProperty): + if p.GetNumberOfElements() == 1 and not p.GetRepeatable(): + if p.SMProperty.IsA("vtkSMStringVectorProperty") or not p.GetArgumentIsArray(): + return p[0] + elif isinstance(p, InputProperty): + if not p.GetMultipleInput(): + if len(p) > 0: + return p[0] + else: + return None + elif isinstance(p, ProxyProperty): + if not p.GetRepeatable(): + if len(p) > 0: + return p[0] + else: + return None + return p + + def GetProperty(self, name): + """Given a property name, returns the property object.""" + if name in self.__Properties and self.__Properties[name](): + return self.__Properties[name]() + smproperty = self.SMProxy.GetProperty(name) + # Maybe they are looking by the label. Try to match that. + if not smproperty: + iter = PropertyIterator(self) + for prop in iter: + if name == _make_name_valid(iter.PropertyLabel): + smproperty = prop.SMProperty + break + if smproperty: + property = _wrap_property(self, smproperty) + if property is not None: + import weakref + self.__Properties[name] = weakref.ref(property) + return property + return None + + def ListProperties(self): + """Returns a list of all property names on this proxy.""" + property_list = [] + iter = self.__iter__() + for property in iter: + name = _make_name_valid(iter.PropertyLabel) + if name: + property_list.append(name) + return property_list + + def __ConvertArgumentsAndCall(self, *args): + """ Internal function. + Used to call a function on SMProxy. Converts input and + output values as appropriate. + """ + newArgs = [] + for arg in args: + if issubclass(type(arg), Proxy) or isinstance(arg, Proxy): + newArgs.append(arg.SMProxy) + else: + newArgs.append(arg) + func = getattr(self.SMProxy, self.__LastAttrName) + retVal = func(*newArgs) + if type(retVal) is type(self.SMProxy) and retVal.IsA("vtkSMProxy"): + return _getPyProxy(retVal) + elif type(retVal) is type(self.SMProxy) and retVal.IsA("vtkSMProperty"): + return _wrap_property(self, retVal) + else: + return retVal + + def __GetActiveCamera(self): + """ This method handles GetActiveCamera specially. It adds + an observer to the camera such that everytime it is modified + the render view updated""" + import weakref + c = self.SMProxy.GetActiveCamera() + # VSV: Observers are not supported +## if not c.HasObserver("ModifiedEvent"): +## self.ObserverTag =c.AddObserver("ModifiedEvent", _makeUpdateCameraMethod(weakref.ref(self))) +## self.Observed = c + return c + + def __getattr__(self, name): + """With the exception of a few overloaded methods, + returns the SMProxy method""" + if not self.SMProxy: + raise AttributeError("class %s has no attribute %s" % ("None", name)) + return None + # Handle GetActiveCamera specially. + if name == "GetActiveCamera" and \ + hasattr(self.SMProxy, "GetActiveCamera"): + return self.__GetActiveCamera + if name == "SaveDefinition" and hasattr(self.SMProxy, "SaveDefinition"): + return self.__SaveDefinition + # If not a property, see if SMProxy has the method + try: + proxyAttr = getattr(self.SMProxy, name) + self.__LastAttrName = name + return self.__ConvertArgumentsAndCall + except: + pass + return getattr(self.SMProxy, name) + +class SourceProxy(Proxy): + """Proxy for a source object. This class adds a few methods to Proxy + that are specific to sources. It also provides access to the output + ports. Output ports can be accessed by name or index: + > op = source[0] + or + > op = source['some name']. + """ + def UpdatePipeline(self, time=None): + """This method updates the server-side VTK pipeline and the associated + data information. Make sure to update a source to validate the output + meta-data.""" + if time != None: + self.SMProxy.UpdatePipeline(time) + else: + self.SMProxy.UpdatePipeline() + # This is here to cause a receive + # on the client side so that progress works properly. + if ActiveConnection and ActiveConnection.IsRemote(): + self.SMProxy.GetDataInformation() + + def FileNameChanged(self): + "Called when the filename of a source proxy is changed." + self.UpdatePipelineInformation() + + def UpdatePipelineInformation(self): + """This method updates the meta-data of the server-side VTK pipeline and + the associated information properties""" + self.SMProxy.UpdatePipelineInformation() + + def GetDataInformation(self, idx=None): + """This method returns a DataInformation wrapper around a + vtkPVDataInformation""" + if idx == None: + idx = self.Port + if self.SMProxy: + return DataInformation( \ + self.SMProxy.GetDataInformation(idx), \ + self.SMProxy, idx) + + def __getitem__(self, idx): + """Given a slice, int or string, returns the corresponding + output port""" + if isinstance(idx, slice): + indices = idx.indices(self.SMProxy.GetNumberOfOutputPorts()) + retVal = [] + for i in range(*indices): + retVal.append(OutputPort(self, i)) + return retVal + elif isinstance(idx, int): + if idx >= self.SMProxy.GetNumberOfOutputPorts() or idx < 0: + raise IndexError + return OutputPort(self, idx) + else: + return OutputPort(self, self.SMProxy.GetOutputPortIndex(idx)) + + def GetPointDataInformation(self): + """Returns the associated point data information.""" + self.UpdatePipeline() + return FieldDataInformation(self.SMProxy, self.Port, "PointData") + + def GetCellDataInformation(self): + """Returns the associated cell data information.""" + self.UpdatePipeline() + return FieldDataInformation(self.SMProxy, self.Port, "CellData") + + def GetFieldDataInformation(self): + """Returns the associated cell data information.""" + self.UpdatePipeline() + return FieldDataInformation(self.SMProxy, self.Port, "FieldData") + + PointData = property(GetPointDataInformation, None, None, "Returns point data information") + CellData = property(GetCellDataInformation, None, None, "Returns cell data information") + FieldData = property(GetFieldDataInformation, None, None, "Returns field data information") + + +class ExodusIIReaderProxy(SourceProxy): + """Special class to define convenience functions for array + selection.""" + + def FileNameChanged(self): + "Called when the filename changes. Selects all variables." + SourceProxy.FileNameChanged(self) + self.SelectAllVariables() + + def SelectAllVariables(self): + "Select all available variables for reading." + for prop in ('PointVariables', 'EdgeVariables', 'FaceVariables', + 'ElementVariables', 'GlobalVariables'): + f = getattr(self, prop) + f.SelectAll() + + def DeselectAllVariables(self): + "Deselects all variables." + for prop in ('PointVariables', 'EdgeVariables', 'FaceVariables', + 'ElementVariables', 'GlobalVariables'): + f = getattr(self, prop) + f.DeselectAll() + +class ViewLayoutProxy(Proxy): + """Special class to define convenience methods for View Layout""" + + def SplitViewHorizontal(self, view, fraction=0.5): + """Split the cell containing the specified view horizontally. + If no fraction is specified, the frame is split into equal parts. + On success returns a positve number that identifying the new cell + location that can be used to assign view to, or split further. + Return -1 on failure.""" + location = self.GetViewLocation(view) + if location == -1: + raise RuntimeError, "View is not present in this layout." + if fraction < 0.0 or fraction > 1.0: + raise RuntimeError, "'fraction' must be in the range [0.0, 1.0]" + return self.SMProxy.SplitHorizontal(location, fraction) + + def SplitViewVertical(self, view=None, fraction=0.5): + """Split the cell containing the specified view horizontally. + If no view is specified, active view is used. + If no fraction is specified, the frame is split into equal parts. + On success returns a positve number that identifying the new cell + location that can be used to assign view to, or split further. + Return -1 on failure.""" + location = self.GetViewLocation(view) + if location == -1: + raise RuntimeError, "View is not present in this layout." + if fraction < 0.0 or fraction > 1.0: + raise RuntimeError, "'fraction' must be in the range [0.0, 1.0]" + return self.SMProxy.SplitVertical(location, fraction) + + def AssignView(self, location, view): + """Assign a view at a particular location. Note that the view's position may + be changed by subsequent Split() calls. Returns true on success.""" + viewproxy = None + if isinstance(view, Proxy): + view = view.SMProxy + return self.SMProxy.AssignView(location, view) + + def GetViewLocation(self, view): + if isinstance(view, Proxy): + view = view.SMProxy + return self.SMProxy.GetViewLocation(view) + +class Property(object): + """Generic property object that provides access to one of the properties of + a server object. This class does not allow setting/getting any values but + provides an interface to update a property using __call__. This can be used + for command properties that correspond to function calls without arguments. + For example, + > proxy.Foo() + would push a Foo property which may cause the proxy to call a Foo method + on the actual VTK object. + + For advanced users: + Python wrapper around a vtkSMProperty with a simple interface. + In addition to all method provided by vtkSMProperty (obtained by + forwarding unknown attributes requests to the underlying SMProxy), + Property and sub-class provide a list API. + + Please note that some of the methods accessible through the Property + class are not listed by help() because the Property objects forward + unresolved attributes to the underlying object. To get the full list, + see also dir(proxy.SMProperty). See also the doxygen based documentation + of the vtkSMProperty C++ class. + """ + def __init__(self, proxy, smproperty): + """Default constructor. Stores a reference to the proxy.""" + import weakref + self.SMProperty = smproperty + self.Proxy = proxy + + def __repr__(self): + """Returns a string representation containing property name + and value""" + if not type(self) is Property: + if self.GetData() is not None: + repr = self.GetData().__repr__() + else: + repr = "None" + else: + repr = "Property name= " + name = self.Proxy.GetPropertyName(self.SMProperty) + if name: + repr += name + else: + repr += "Unknown" + + return repr + + def __call__(self): + """Forces a property update using InvokeCommand.""" + if type(self) is Property: + self.Proxy.SMProxy.InvokeCommand(self._FindPropertyName()) + else: + raise RuntimeError, "Cannot invoke this property" + + def _FindPropertyName(self): + "Returns the name of this property." + return self.Proxy.GetPropertyName(self.SMProperty) + + def _UpdateProperty(self): + "Pushes the value of this property to the server." + # For now, we are updating all properties. This is due to an + # issue with the representations. Their VTK objects are not + # created until Input is set therefore, updating a property + # has no effect. Updating all properties everytime one is + # updated has the effect of pushing values set before Input + # when Input is updated. + # self.Proxy.SMProxy.UpdateProperty(self._FindPropertyName()) + self.Proxy.SMProxy.UpdateVTKObjects() + + def __getattr__(self, name): + "Unknown attribute requests get forwarded to SMProperty." + return getattr(self.SMProperty, name) + + Name = property(_FindPropertyName, None, None, + "Returns the name for the property") + +class GenericIterator(object): + """Iterator for container type objects""" + + def __init__(self, obj): + self.Object = obj + self.index = 0 + + def __iter__(self): + return self + + def next(self): + if self.index >= len(self.Object): + raise StopIteration + + idx = self.index + self.index += 1 + return self.Object[idx] + +class VectorProperty(Property): + """A VectorProperty provides access to one or more values. You can use + a slice to get one or more property values: + > val = property[2] + or + > vals = property[0:5:2] + You can use a slice to set one or more property values: + > property[2] = val + or + > property[1:3] = (1,2) + """ + def ConvertValue(self, value): + return value + + def __len__(self): + """Returns the number of elements.""" + return self.SMProperty.GetNumberOfElements() + + def __iter__(self): + """Implementation of the sequence API""" + return GenericIterator(self) + + def __setitem__(self, idx, value): + """Given a list or tuple of values, sets a slice of values [min, max)""" + if isinstance(idx, slice): + indices = idx.indices(len(self)) + for i, j in zip(range(*indices), value): + self.SMProperty.SetElement(i, self.ConvertValue(j)) + self._UpdateProperty() + elif idx >= len(self) or idx < 0: + raise IndexError + else: + self.SMProperty.SetElement(idx, self.ConvertValue(value)) + self._UpdateProperty() + + def GetElement(self, index): + return self.SMProperty.GetElement(index) + + def __getitem__(self, idx): + """Returns the range [min, max) of elements. Raises an IndexError + exception if an argument is out of bounds.""" + ls = len(self) + if isinstance(idx, slice): + indices = idx.indices(ls) + retVal = [] + for i in range(*indices): + retVal.append(self.GetElement(i)) + return retVal + elif idx >= ls: + raise IndexError + elif idx < 0: + idx = ls + idx + if idx < 0: + raise IndexError + + return self.GetElement(idx) + + def GetData(self): + "Returns all elements as either a list or a single value." + property = self.SMProperty + if property.GetRepeatable() or \ + property.GetNumberOfElements() > 1: + return self[0:len(self)] + elif property.GetNumberOfElements() == 1: + return self.GetElement(0) + + def SetData(self, values): + """Allows setting of all values at once. Requires a single value or + a iterable object.""" + if not hasattr(values, "__iter__"): + values = (values,) + if not self.GetRepeatable() and len(values) != self.GetNumberOfElements(): + raise RuntimeError("This property requires %d values." % self.GetNumberOfElements()) + if self.GetRepeatable(): + # Clean up first + self.SMProperty.SetNumberOfElements(0) + idx = 0 + for val in values: + self.SMProperty.SetElement(idx, self.ConvertValue(val)) + idx += 1 + self._UpdateProperty() + + def Clear(self): + "Removes all elements." + self.SMProperty().SetNumberOfElements(0) + self._UpdateProperty() + +class ColorArrayProperty(VectorProperty): + """This subclass of VectorProperty handles setting of the array to + color by. It handles attribute type as well as well array name.""" + + def GetAvailable(self): + """Returns the list of available arrays as (attribute type, array name + tuples.""" + arrays = [] + for a in self.Proxy.Input.PointData: + arrays.append(('POINT_DATA', a.GetName())) + for a in self.Proxy.Input.CellData: + arrays.append(('CELL_DATA', a.GetName())) + return arrays + + def SetData(self, value): + """Overwritten to enable setting attribute type (the ColorAttributeType + property and the array name. The argument should be the array name + (in which case the first appropriate attribute type is picked) or + a tuple of attribute type and array name.""" + if isinstance(value, tuple) and len(value) == 2: + att = value[0] + arr = value[1] + elif isinstance(value, str): + att = None + arr = value + else: + raise ValueError("Expected a tuple of 2 values or a string.") + + if not arr: + self.SMProperty.SetElement(0, '') + self._UpdateProperty() + return + + found = False + for a in self.Available: + if a[1] == arr and (not att or att == a[0]): + att = a[0] + found = True + break + + if not found: + pvoptions = vtkProcessModule.GetProcessModule().GetOptions() + # if this process is from a parallel batch run in symmetric mpi mode + # then we may not have any points or cells on some processes in which + # case we'll probably be missing the point and cell data too. the + # check below makes sure that we avoid this situation. + if pvoptions.GetProcessType() != 0x40 or pvoptions.GetSymmetricMPIMode() == False \ + or len(self.Available) != 0: + raise ValueError("Could not locate array %s in the input." % arr) + + catt = self.Proxy.GetProperty("ColorAttributeType") + if att != None: + catt.SetData(att) + self.SMProperty.SetElement(0, arr) + self._UpdateProperty() + + Available = property(GetAvailable, None, None, \ + "This read-only property returns the list of arrays that can be colored by.") + + +class EnumerationProperty(VectorProperty): + """Subclass of VectorProperty that is applicable for enumeration type + properties.""" + + def GetElement(self, index): + """Returns the text for the given element if available. Returns + the numerical values otherwise.""" + val = self.SMProperty.GetElement(index) + domain = self.SMProperty.GetDomain("enum") + for i in range(domain.GetNumberOfEntries()): + if domain.GetEntryValue(i) == val: + return domain.GetEntryText(i) + return val + + def ConvertValue(self, value): + """Converts value to type suitable for vtSMProperty::SetElement()""" + if type(value) == str: + domain = self.SMProperty.GetDomain("enum") + if domain.HasEntryText(value): + return domain.GetEntryValueForText(value) + else: + raise ValueError("%s is not a valid value." % value) + return VectorProperty.ConvertValue(self, value) + + def GetAvailable(self): + "Returns the list of available values for the property." + retVal = [] + domain = self.SMProperty.GetDomain("enum") + for i in range(domain.GetNumberOfEntries()): + retVal.append(domain.GetEntryText(i)) + return retVal + + Available = property(GetAvailable, None, None, \ + "This read-only property contains the list of values that can be applied to this property.") + + +class FileNameProperty(VectorProperty): + """Property to set/get one or more file names. + This property updates the pipeline information everytime its value changes. + This is used to keep the array lists up to date.""" + + def _UpdateProperty(self): + "Pushes the value of this property to the server." + VectorProperty._UpdateProperty(self) + self.Proxy.FileNameChanged() + +class ArraySelectionProperty(VectorProperty): + "Property to select an array to be processed by a filter." + + def GetAssociation(self): + val = self.GetElement(3) + if val == "": + return None + for key, value in ASSOCIATIONS.iteritems(): + if value == int(val): + return key + + return None + + def GetArrayName(self): + return self.GetElement(4) + + def __len__(self): + """Returns the number of elements.""" + return 2 + + def __setitem__(self, idx, value): + raise RuntimeError, "This property cannot be accessed using __setitem__" + + def __getitem__(self, idx): + """Returns attribute type for index 0, array name for index 1""" + if isinstance(idx, slice): + indices = idx.indices(len(self)) + retVal = [] + for i in range(*indices): + if i >= 2 or i < 0: + raise IndexError + if i == 0: + retVal.append(self.GetAssociation()) + else: + retVal.append(self.GetArrayName()) + return retVal + elif idx >= 2 or idx < 0: + raise IndexError + + if i == 0: + return self.GetAssociation() + else: + return self.GetArrayName() + + def SetData(self, values): + """Allows setting of all values at once. Requires a single value, + a tuple or list.""" + if not isinstance(values, tuple) and \ + not isinstance(values, list): + values = (values,) + if len(values) == 1: + self.SMProperty.SetElement(4, values[0]) + elif len(values) == 2: + if isinstance(values[0], str): + val = str(ASSOCIATIONS[values[0]]) + else: + # In case user didn't specify valid association, + # just pick POINTS. + val = str(ASSOCIATIONS['POINTS']) + self.SMProperty.SetElement(3, str(val)) + self.SMProperty.SetElement(4, values[1]) + else: + raise RuntimeError, "Expected 1 or 2 values." + self._UpdateProperty() + + def UpdateDefault(self): + "Helper method to set default values." + if self.SMProperty.GetNumberOfElements() != 5: + return + if self.GetElement(4) != '' or \ + self.GetElement(3) != '': + return + + for i in range(0,3): + if self.GetElement(i) == '': + self.SMProperty.SetElement(i, '0') + al = self.SMProperty.GetDomain("array_list") + al.Update(self.SMProperty) + al.SetDefaultValues(self.SMProperty) + +class ArrayListProperty(VectorProperty): + """This property provides a simpler interface for selecting arrays. + Simply assign a list of arrays that should be loaded by the reader. + Use the Available property to get a list of available arrays.""" + + def __init__(self, proxy, smproperty): + VectorProperty.__init__(self, proxy, smproperty) + self.__arrays = [] + + def GetAvailable(self): + "Returns the list of available arrays" + dm = self.GetDomain("array_list") + retVal = [] + for i in range(dm.GetNumberOfStrings()): + retVal.append(dm.GetString(i)) + return retVal + + Available = property(GetAvailable, None, None, \ + "This read-only property contains the list of items that can be read by a reader.") + + def SelectAll(self): + "Selects all arrays." + self.SetData(self.Available) + + def DeselectAll(self): + "Deselects all arrays." + self.SetData([]) + + def __iter__(self): + """Implementation of the sequence API""" + return GenericIterator(self) + + def __len__(self): + """Returns the number of elements.""" + return len(self.GetData()) + + def __setitem__(self, idx, value): + """Given a list or tuple of values, sets a slice of values [min, max)""" + self.GetData() + if isinstance(idx, slice): + indices = idx.indices(len(self)) + for i, j in zip(range(*indices), value): + self.__arrays[i] = j + self.SetData(self.__arrays) + elif idx >= len(self) or idx < 0: + raise IndexError + else: + self.__arrays[idx] = self.ConvertValue(value) + self.SetData(self.__arrays) + + def __getitem__(self, idx): + """Returns the range [min, max) of elements. Raises an IndexError + exception if an argument is out of bounds.""" + self.GetData() + if isinstance(idx, slice): + indices = idx.indices(len(self)) + retVal = [] + for i in range(*indices): + retVal.append(self.__arrays[i]) + return retVal + elif idx >= len(self) or idx < 0: + raise IndexError + return self.__arrays[idx] + + def SetData(self, values): + """Allows setting of all values at once. Requires a single value, + a tuple or list.""" + # Clean up first + iup = self.SMProperty.GetImmediateUpdate() + self.SMProperty.SetImmediateUpdate(False) + # Clean up first + self.SMProperty.SetNumberOfElements(0) + if not isinstance(values, tuple) and \ + not isinstance(values, list): + values = (values,) + fullvalues = [] + + # WARNING: + # The order of the two loops below are delibrately set in this way + # so that values passed in will take precedence. + # This is needed for backward compatibility of the + # property ElementBlocks for vtkExodusIIReader. + # If you attemp to change this, please verify that + # python state files for opening old .ex2 file (<=3.14) still works. + for array in self.Available: + if not values.__contains__(array): + fullvalues.append(array) + fullvalues.append('0') + + for i in range(len(values)): + val = self.ConvertValue(values[i]) + fullvalues.append(val) + fullvalues.append('1') + + + i = 0 + for value in fullvalues: + self.SMProperty.SetElement(i, value) + i += 1 + + self._UpdateProperty() + self.SMProperty.SetImmediateUpdate(iup) + + def GetData(self): + "Returns all elements as a list." + property = self.SMProperty + nElems = property.GetNumberOfElements() + if nElems%2 != 0: + raise ValueError, "The SMProperty with XML label '%s' has a size that is not a multiple of 2." % property.GetXMLLabel() + self.__arrays = [] + for i in range(0, nElems, 2): + if self.GetElement(i+1) != '0': + self.__arrays.append(self.GetElement(i)) + return list(self.__arrays) + +class ProxyProperty(Property): + """A ProxyProperty provides access to one or more proxies. You can use + a slice to get one or more property values: + > proxy = property[2] + or + > proxies = property[0:5:2] + You can use a slice to set one or more property values: + > property[2] = proxy + or + > property[1:3] = (proxy1, proxy2) + You can also append and delete: + > property.append(proxy) + and + > del property[1:2] + + You can also remove all elements with Clear(). + + Note that some properties expect only 1 proxy and will complain if + you set the number of values to be something else. + """ + def __init__(self, proxy, smproperty): + """Default constructor. Stores a reference to the proxy. Also looks + at domains to find valid values.""" + Property.__init__(self, proxy, smproperty) + # Check to see if there is a proxy list domain and, if so, + # initialize ourself. (Should this go in ProxyProperty?) + listdomain = self.GetDomain('proxy_list') + if listdomain: + if listdomain.GetClassName() != 'vtkSMProxyListDomain': + raise ValueError, "Found a 'proxy_list' domain on an InputProperty that is not a ProxyListDomain." + pm = ProxyManager() + group = "pq_helper_proxies." + proxy.GetGlobalIDAsString() + if listdomain.GetNumberOfProxies() == 0: + for i in xrange(listdomain.GetNumberOfProxyTypes()): + igroup = listdomain.GetProxyGroup(i) + name = listdomain.GetProxyName(i) + iproxy = CreateProxy(igroup, name) + listdomain.AddProxy(iproxy) + pm.RegisterProxy(group, proxy.GetPropertyName(smproperty), iproxy) + listdomain.SetDefaultValues(self.SMProperty) + + def GetAvailable(self): + """If this proxy has a list domain, then this function returns the + strings you can use to select from the domain. If there is no such + list domain, the returned list is empty.""" + listdomain = self.GetDomain('proxy_list') + retval = [] + if listdomain: + for i in xrange(listdomain.GetNumberOfProxies()): + proxy = listdomain.GetProxy(i) + retval.append(proxy.GetXMLLabel()) + return retval + + Available = property(GetAvailable, None, None, + """This read only property is a list of strings you can + use to select from the list domain. If there is no + such list domain, the array is empty.""") + + def __iter__(self): + """Implementation of the sequence API""" + return GenericIterator(self) + + def __len__(self): + """Returns the number of elements.""" + return self.SMProperty.GetNumberOfProxies() + + def remove(self, proxy): + """Removes the first occurence of the proxy from the property.""" + self.SMProperty.RemoveProxy(proxy.SMProxy) + self._UpdateProperty() + + def __setitem__(self, idx, value): + """Given a list or tuple of values, sets a slice of values [min, max)""" + if isinstance(idx, slice): + indices = idx.indices(len(self)) + for i, j in zip(range(*indices), value): + self.SMProperty.SetProxy(i, j.SMProxy) + self._UpdateProperty() + elif idx >= len(self) or idx < 0: + raise IndexError + else: + self.SMProperty.SetProxy(idx, value.SMProxy) + self._UpdateProperty() + + def __delitem__(self,idx): + """Removes the element idx""" + if isinstance(idx, slice): + indices = idx.indices(len(self)) + # Collect the elements to delete to a new list first. + # Otherwise indices are screwed up during the actual + # remove loop. + toremove = [] + for i in range(*indices): + toremove.append(self[i]) + for i in toremove: + self.SMProperty.RemoveProxy(i.SMProxy) + self._UpdateProperty() + elif idx >= len(self) or idx < 0: + raise IndexError + else: + self.SMProperty.RemoveProxy(self[idx].SMProxy) + self._UpdateProperty() + + def __getitem__(self, idx): + """Returns the range [min, max) of elements. Raises an IndexError + exception if an argument is out of bounds.""" + if isinstance(idx, slice): + indices = idx.indices(len(self)) + retVal = [] + for i in range(*indices): + retVal.append(_getPyProxy(self.SMProperty.GetProxy(i))) + return retVal + elif idx >= len(self) or idx < 0: + raise IndexError + return _getPyProxy(self.SMProperty.GetProxy(idx)) + + def __getattr__(self, name): + "Unknown attribute requests get forwarded to SMProperty." + return getattr(self.SMProperty, name) + + def index(self, proxy): + idx = 0 + for px in self: + ## VSV: == + if proxy.IsSame(px): + return idx + idx += 1 + raise ValueError("proxy is not in the list.") + + def append(self, proxy): + "Appends the given proxy to the property values." + self.SMProperty.AddProxy(proxy.SMProxy) + self._UpdateProperty() + + def GetData(self): + "Returns all elements as either a list or a single value." + property = self.SMProperty + if property.GetRepeatable() or property.GetNumberOfProxies() > 1: + return self[0:len(self)] + else: + if property.GetNumberOfProxies() > 0: + return _getPyProxy(property.GetProxy(0)) + return None + + def SetData(self, values): + """Allows setting of all values at once. Requires a single value, + a tuple or list.""" + if isinstance(values, str): + position = -1 + try: + position = self.Available.index(values) + except: + raise ValueError, values + " is not a valid object in the domain." + values = self.GetDomain('proxy_list').GetProxy(position) + if not isinstance(values, tuple) and \ + not isinstance(values, list): + values = (values,) + self.SMProperty.RemoveAllProxies() + for value in values: + if isinstance(value, Proxy): + value_proxy = value.SMProxy + else: + value_proxy = value + self.SMProperty.AddProxy(value_proxy) + self._UpdateProperty() + + def Clear(self): + "Removes all elements." + self.SMProperty.RemoveAllProxies() + self._UpdateProperty() + +class InputProperty(ProxyProperty): + """An InputProperty allows making pipeline connections. You can set either + a source proxy or an OutputProperty to an input property: + + > property[0] = proxy + or + > property[0] = OuputPort(proxy, 1) + + > property.append(proxy) + or + > property.append(OutputPort(proxy, 0)) + """ + def __setitem__(self, idx, value): + """Given a list or tuple of values, sets a slice of values [min, max)""" + if isinstance(idx, slice): + indices = idx.indices(len(self)) + for i, j in zip(range(*indices), value): + op = value[i-min] + self.SMProperty.SetInputConnection(i, op.SMProxy, op.Port) + self._UpdateProperty() + elif idx >= len(self) or idx < 0: + raise IndexError + else: + self.SMProperty.SetInputConnection(idx, value.SMProxy, value.Port) + self._UpdateProperty() + + def __getitem__(self, idx): + """Returns the range [min, max) of elements. Raises an IndexError + exception if an argument is out of bounds.""" + if isinstance(idx, slice): + indices = idx.indices(len(self)) + retVal = [] + for i in range(*indices): + port = None + if self.SMProperty.GetProxy(i): + port = OutputPort(_getPyProxy(self.SMProperty.GetProxy(i)),\ + self.SMProperty.GetOutputPortForConnection(i)) + retVal.append(port) + return retVal + elif idx >= len(self) or idx < 0: + raise IndexError + return OutputPort(_getPyProxy(self.SMProperty.GetProxy(idx)),\ + self.SMProperty.GetOutputPortForConnection(idx)) + + def append(self, value): + """Appends the given proxy to the property values. + Accepts Proxy or OutputPort objects.""" + self.SMProperty.AddInputConnection(value.SMProxy, value.Port) + self._UpdateProperty() + + def GetData(self): + """Returns all elements as either a list of OutputPort objects or + a single OutputPort object.""" + property = self.SMProperty + if property.GetRepeatable() or property.GetNumberOfProxies() > 1: + return self[0:len(self)] + else: + if property.GetNumberOfProxies() > 0: + return OutputPort(_getPyProxy(property.GetProxy(0)),\ + self.SMProperty.GetOutputPortForConnection(0)) + return None + + def SetData(self, values): + """Allows setting of all values at once. Requires a single value, + a tuple or list. Accepts Proxy or OutputPort objects.""" + if isinstance(values, str): + ProxyProperty.SetData(self, values) + return + if not isinstance(values, tuple) and \ + not isinstance(values, list): + values = (values,) + self.SMProperty.RemoveAllProxies() + for value in values: + if value: + self.SMProperty.AddInputConnection(value.SMProxy, value.Port) + self._UpdateProperty() + + def _UpdateProperty(self): + "Pushes the value of this property to the server." + ProxyProperty._UpdateProperty(self) + iter = PropertyIterator(self.Proxy) + for prop in iter: + if isinstance(prop, ArraySelectionProperty): + prop.UpdateDefault() + + +class DataInformation(object): + """DataInformation is a contained for meta-data associated with an + output data. + + DataInformation is a python wrapper around a vtkPVDataInformation. + In addition to proving all methods of a vtkPVDataInformation, it provides + a few convenience methods. + + Please note that some of the methods accessible through the DataInformation + class are not listed by help() because the DataInformation objects forward + unresolved attributes to the underlying object. To get the full list, + see also dir(proxy.DataInformation). + See also the doxygen based documentation of the vtkPVDataInformation C++ + class. + """ + def __init__(self, dataInformation, proxy, idx): + """Default constructor. Requires a vtkPVDataInformation, a source proxy + and an output port id.""" + self.DataInformation = dataInformation + self.Proxy = proxy + self.Idx = idx + + def Update(self): + """****Deprecated**** There is no reason anymore to use this method + explicitly, it is called automatically when one gets any value from the + data information object. + Update the data information if necessary. Note that this + does not cause execution of the underlying object. In certain + cases, you may have to call UpdatePipeline() on the proxy.""" + if self.Proxy: + self.Proxy.GetDataInformation(self.Idx) + + def GetDataSetType(self): + """Returns the dataset type as defined in vtkDataObjectTypes.""" + self.Update() + if not self.DataInformation: + raise RuntimeError, "No data information is available" + if self.DataInformation.GetCompositeDataSetType() > -1: + return self.DataInformation.GetCompositeDataSetType() + return self.DataInformation.GetDataSetType() + + def GetDataSetTypeAsString(self): + """Returns the dataset type as a user-friendly string. This is + not the same as the enumaration used by VTK""" + return vtk.vtkDataObjectTypes.GetClassNameFromTypeId(self.GetDataSetType()) + + def __getattr__(self, name): + """Forwards unknown attribute requests to the underlying + vtkPVInformation.""" + if not self.DataInformation: + raise AttributeError("class has no attribute %s" % name) + return None + self.Update() + return getattr(self.DataInformation, name) + +class ArrayInformation(object): + """Meta-information associated with an array. Use the Name + attribute to get the array name. + + Please note that some of the methods accessible through the ArrayInformation + class are not listed by help() because the ArrayInformation objects forward + unresolved attributes to the underlying object. + See the doxygen based documentation of the vtkPVArrayInformation C++ + class for a full list. + """ + def __init__(self, proxy, field, name): + self.Proxy = proxy + self.FieldData = field + self.Name = name + + def __getattr__(self, name): + """Forward unknown methods to vtkPVArrayInformation""" + array = self.FieldData.GetFieldData().GetArrayInformation(self.Name) + if not array: return None + return getattr(array, name) + + def __repr__(self): + """Returns a user-friendly representation string.""" + return "Array: " + self.Name + + def GetRange(self, component=0): + """Given a component, returns its value range as a tuple of 2 values.""" + array = self.FieldData.GetFieldData().GetArrayInformation(self.Name) + range = array.GetComponentRange(component) + return (range[0], range[1]) + +class FieldDataInformationIterator(object): + """Iterator for FieldDataInformation""" + + def __init__(self, info, items=False): + self.FieldDataInformation = info + self.index = 0 + self.items = items + + def __iter__(self): + return self + + def next(self): + if self.index >= self.FieldDataInformation.GetNumberOfArrays(): + raise StopIteration + + self.index += 1 + ai = self.FieldDataInformation[self.index-1] + if self.items: + return (ai.GetName(), ai) + else: + return ai + + +class FieldDataInformation(object): + """Meta-data for a field of an output object (point data, cell data etc...). + Provides easy access to the arrays using the slice interface: + > narrays = len(field_info) + > for i in range(narrays): + > array_info = field_info[i] + + Full slice interface is supported: + > arrays = field_info[0:5:3] + where arrays is a list. + + Array access by name is also possible: + > array_info = field_info['Temperature'] + + The number of arrays can also be accessed using the NumberOfArrays + property. + """ + def __init__(self, proxy, idx, field): + self.Proxy = proxy + self.OutputPort = idx + self.FieldData = field + + def GetFieldData(self): + """Convenience method to get the underlying + vtkPVDataSetAttributesInformation""" + return getattr(self.Proxy.GetDataInformation(self.OutputPort), "Get%sInformation" % self.FieldData)() + + def GetNumberOfArrays(self): + """Returns the number of arrays.""" + self.Proxy.UpdatePipeline() + return self.GetFieldData().GetNumberOfArrays() + + def GetArray(self, idx): + """Given an index or a string, returns an array information. + Raises IndexError if the index is out of bounds.""" + self.Proxy.UpdatePipeline() + if not self.GetFieldData().GetArrayInformation(idx): + return None + if isinstance(idx, str): + return ArrayInformation(self.Proxy, self, idx) + elif idx >= len(self) or idx < 0: + raise IndexError + return ArrayInformation(self.Proxy, self, self.GetFieldData().GetArrayInformation(idx).GetName()) + + def __len__(self): + """Returns the number of arrays.""" + return self.GetNumberOfArrays() + + def __getitem__(self, idx): + """Implements the [] operator. Accepts an array name.""" + if isinstance(idx, slice): + indices = idx.indices(self.GetNumberOfArrays()) + retVal = [] + for i in range(*indices): + retVal.append(self.GetArray(i)) + return retVal + return self.GetArray(idx) + + def keys(self): + """Implementation of the dictionary API""" + kys = [] + narrays = self.GetNumberOfArrays() + for i in range(narrays): + kys.append(self.GetArray(i).GetName()) + return kys + + def values(self): + """Implementation of the dictionary API""" + vals = [] + narrays = self.GetNumberOfArrays() + for i in range(narrays): + vals.append(self.GetArray(i)) + return vals + + def iteritems(self): + """Implementation of the dictionary API""" + return FieldDataInformationIterator(self, True) + + def items(self): + """Implementation of the dictionary API""" + itms = [] + narrays = self.GetNumberOfArrays() + for i in range(narrays): + ai = self.GetArray(i) + itms.append((ai.GetName(), ai)) + return itms + + def has_key(self, key): + """Implementation of the dictionary API""" + if self.GetArray(key): + return True + return False + + def __iter__(self): + """Implementation of the dictionary API""" + return FieldDataInformationIterator(self) + + def __getattr__(self, name): + """Forwards unknown attributes to the underlying + vtkPVDataSetAttributesInformation""" + array = self.GetArray(name) + if array: return array + raise AttributeError("class has no attribute %s" % name) + return None + + NumberOfArrays = property(GetNumberOfArrays, None, None, "Returns the number of arrays.") + +def OutputPort(proxy, outputPort=0): + if not Proxy: + return None + if isinstance(outputPort, str): + outputPort = proxy.GetOutputPortIndex(outputPort) + if outputPort >= proxy.GetNumberOfOutputPorts(): + return None + if proxy.Port == outputPort: + return proxy + newinstance = _getPyProxy(proxy.SMProxy, outputPort) + newinstance.Port = outputPort + newinstance._Proxy__Properties = proxy._Proxy__Properties + return newinstance + +class ProxyManager(object): + """When running scripts from the python shell in the ParaView application, + registering proxies with the proxy manager is the only mechanism to + notify the graphical user interface (GUI) that a proxy + exists. Therefore, unless a proxy is registered, it will not show up in + the user interface. Also, the proxy manager is the only way to get + access to proxies created using the GUI. Proxies created using the GUI + are automatically registered under an appropriate group (sources, + filters, representations and views). To get access to these objects, + you can use proxyManager.GetProxy(group, name). The name is the same + as the name shown in the pipeline browser. + + This class is a python wrapper for vtkSMProxyManager. Note that the + underlying vtkSMProxyManager is a singleton. All instances of this + class will refer to the same object. In addition to all methods provided by + vtkSMProxyManager (all unknown attribute requests are forwarded + to the vtkSMProxyManager), this class provides several convenience + methods. + + Please note that some of the methods accessible through the ProxyManager + class are not listed by help() because the ProxyManager objects forwards + unresolved attributes to the underlying object. To get the full list, + see also dir(proxy.SMProxyManager). See also the doxygen based documentation + of the vtkSMProxyManager C++ class. + """ + + def __init__(self, session=None): + """Constructor. Assigned self.SMProxyManager to + vtkSMProxyManager.GetProxyManager().""" + global ActiveConnection + if not session: + session = ActiveConnection.Session + self.SMProxyManager = session.GetSessionProxyManager() + + def RegisterProxy(self, group, name, aProxy): + """Registers a proxy (either SMProxy or proxy) with the + server manager""" + if isinstance(aProxy, Proxy): + self.SMProxyManager.RegisterProxy(group, name, aProxy.SMProxy) + else: + self.SMProxyManager.RegisterProxy(group, name, aProxy) + + def NewProxy(self, group, name): + """Creates a new proxy of given group and name and returns an SMProxy. + Note that this is a server manager object. You should normally create + proxies using the class objects. For example: + obj = servermanager.sources.SphereSource()""" + if not self.SMProxyManager: + return None + aProxy = self.SMProxyManager.NewProxy(group, name, "NULL") + if not aProxy: + return None + aProxy.UnRegister(None) + return aProxy + + def GetProxy(self, group, name): + """Returns a Proxy registered under a group and name""" + if not self.SMProxyManager: + return None + aProxy = self.SMProxyManager.GetProxy(group, name) + if not aProxy: + return None + return _getPyProxy(aProxy) + + def GetPrototypeProxy(self, group, name): + """Returns a prototype proxy given a group and name. This is an + SMProxy. This is a low-level method. You should not normally + have to call it.""" + if not self.SMProxyManager: + return None + aProxy = self.SMProxyManager.GetPrototypeProxy(group, name) + if not aProxy: + return None + return aProxy + + def GetProxiesInGroup(self, groupname): + """Returns a map of proxies in a particular group.""" + proxies = {} + iter = self.NewGroupIterator(groupname) + for aProxy in iter: + proxies[(iter.GetKey(), aProxy.GetGlobalIDAsString())] = aProxy + return proxies + + def UnRegisterProxy(self, groupname, proxyname, aProxy): + """Unregisters a proxy.""" + if not self.SMProxyManager: + return + if aProxy != None and isinstance(aProxy,Proxy): + aProxy = aProxy.SMProxy + if aProxy: + self.SMProxyManager.UnRegisterProxy(groupname, proxyname, aProxy) + + def GetProxies(self, groupname, proxyname): + """Returns all proxies registered under the given group with the + given name. Note that it is possible to register more than one + proxy with the same name in the same group. Because the proxies + are different, there is no conflict. Use this method instead of + GetProxy() if you know that there are more than one proxy registered + with this name.""" + if not self.SMProxyManager: + return [] + collection = vtk.vtkCollection() + result = [] + self.SMProxyManager.GetProxies(groupname, proxyname, collection) + for i in range(0, collection.GetNumberOfItems()): + aProxy = _getPyProxy(collection.GetItemAsObject(i)) + if aProxy: + result.append(aProxy) + + return result + + def __iter__(self): + """Returns a new ProxyIterator.""" + iter = ProxyIterator() + iter.Begin() + return iter + + def NewGroupIterator(self, group_name): + """Returns a ProxyIterator for a group. The resulting object + can be used to traverse the proxies that are in the given + group.""" + iter = self.__iter__() + iter.SetModeToOneGroup() + iter.Begin(group_name) + return iter + + def NewDefinitionIterator(self, groupname=None): + """Returns an iterator that can be used to iterate over + all groups and types of proxies that the proxy manager + can create.""" + iter = None + if groupname != None: + iter = ProxyDefinitionIterator(self.GetProxyDefinitionManager().NewSingleGroupIterator(groupname,0)) + else: + iter = ProxyDefinitionIterator(self.GetProxyDefinitionManager().NewIterator(0)) + + return iter + + def __ConvertArgumentsAndCall(self, *args): + newArgs = [] + for arg in args: + if issubclass(type(arg), Proxy) or isinstance(arg, Proxy): + newArgs.append(arg.SMProxy) + else: + newArgs.append(arg) + func = getattr(self.SMProxyManager, self.__LastAttrName) + retVal = func(*newArgs) + if type(retVal) is type(self.SMProxyManager) and retVal.IsA("vtkSMProxy"): + return _getPyProxy(retVal) + else: + return retVal + + def __getattr__(self, name): + """Returns attribute from the ProxyManager""" + try: + pmAttr = getattr(self.SMProxyManager, name) + self.__LastAttrName = name + return self.__ConvertArgumentsAndCall + except: + pass + return getattr(self.SMProxyManager, name) + + def LoadState(self, filename, loader = None): + self.SMProxyManager.LoadXMLState(filename, loader) + + def SaveState(self, filename): + self.SMProxyManager.SaveXMLState(filename) + +class PropertyIterator(object): + """Wrapper for a vtkSMPropertyIterator class to satisfy + the python iterator protocol. Note that the list of + properties can also be obtained from the class object's + dictionary. + See the doxygen documentation for vtkSMPropertyIterator C++ + class for details. + """ + + def __init__(self, aProxy): + self.SMIterator = aProxy.NewPropertyIterator() + if self.SMIterator: + self.SMIterator.UnRegister(None) + self.SMIterator.Begin() + self.Key = None + self.PropertyLabel = None + self.Proxy = aProxy + + def __iter__(self): + return self + + def next(self): + if not self.SMIterator: + raise StopIteration + + if self.SMIterator.IsAtEnd(): + self.Key = None + raise StopIteration + self.Key = self.SMIterator.GetKey() + self.PropertyLabel = self.SMIterator.GetPropertyLabel() + self.SMIterator.Next() + return self.Proxy.GetProperty(self.Key) + + def GetProxy(self): + """Returns the proxy for the property last returned by the call to + 'next()'""" + return self.Proxy + + def GetKey(self): + """Returns the key for the property last returned by the call to + 'next()' """ + return self.Key + + def GetProperty(self): + """Returns the property last returned by the call to 'next()' """ + return self.Proxy.GetProperty(self.Key) + + def __getattr__(self, name): + """returns attributes from the vtkSMPropertyIterator.""" + return getattr(self.SMIterator, name) + +class ProxyDefinitionIterator(object): + """Wrapper for a vtkPVProxyDefinitionIterator class to satisfy + the python iterator protocol. + See the doxygen documentation of the vtkPVProxyDefinitionIterator + C++ class for more information.""" + def __init__(self, iter): + self.SMIterator = iter + if self.SMIterator: + self.SMIterator.UnRegister(None) + self.SMIterator.InitTraversal() + self.Group = None + self.Key = None + + def __iter__(self): + return self + + def next(self): + if self.SMIterator.IsDoneWithTraversal(): + self.Group = None + self.Key = None + raise StopIteration + self.Group = self.SMIterator.GetGroupName() + self.Key = self.SMIterator.GetProxyName() + self.SMIterator.GoToNextItem() + return {"group": self.Group, "key":self.Key } + + def GetProxyName(self): + """Returns the key for the proxy definition last returned by the call + to 'next()' """ + return self.Key + + def GetGroup(self): + """Returns the group for the proxy definition last returned by the + call to 'next()' """ + return self.Group + + def __getattr__(self, name): + """returns attributes from the vtkPVProxyDefinitionIterator.""" + return getattr(self.SMIterator, name) + + +class ProxyIterator(object): + """Wrapper for a vtkSMProxyIterator class to satisfy the + python iterator protocol. + See the doxygen documentation of vtkSMProxyIterator C++ class for + more information. + """ + def __init__(self): + self.SMIterator = vtkSMProxyIterator() + self.SMIterator.SetSession(ActiveConnection.Session) + self.SMIterator.Begin() + self.AProxy = None + self.Group = None + self.Key = None + + def __iter__(self): + return self + + def next(self): + if self.SMIterator.IsAtEnd(): + self.AProxy = None + self.Group = None + self.Key = None + raise StopIteration + return None + self.AProxy = _getPyProxy(self.SMIterator.GetProxy()) + self.Group = self.SMIterator.GetGroup() + self.Key = self.SMIterator.GetKey() + self.SMIterator.Next() + return self.AProxy + + def GetProxy(self): + """Returns the proxy last returned by the call to 'next()'""" + return self.AProxy + + def GetKey(self): + """Returns the key for the proxy last returned by the call to + 'next()' """ + return self.Key + + def GetGroup(self): + """Returns the group for the proxy last returned by the call to + 'next()' """ + return self.Group + + def __getattr__(self, name): + """returns attributes from the vtkSMProxyIterator.""" + return getattr(self.SMIterator, name) + +# Caution: Observers must be global methods otherwise we run into memory +# leak when the interpreter get reset from the C++ layer. +def _update_definitions(caller, event): + updateModules(ActiveConnection.Modules) + +class Connection(object): + """ + This is a python representation for a session/connection. + """ + def __init__(self, connectionId, session): + """Default constructor. Creates a Connection with the given + ID, all other data members initialized to None.""" + global MultiServerConnections + global ActiveConnection + self.ID = connectionId + self.Session = session + self.Modules = PVModule() + self.Alive = True + self.DefinitionObserverTag = 0 + self.CustomDefinitionObserverTag = 0 + if MultiServerConnections == None and ActiveConnection: + raise RuntimeError, "Concurrent connections not supported!" + if MultiServerConnections != None and not self in MultiServerConnections: + MultiServerConnections.append(self) + ActiveConnection = self + __InitAfterConnect__(self) + __exposeActiveModules__() + + def __eq__(self, other): + "Returns true if the connection ids are the same." + return (self.ID == other.ID) + + def __repr__(self): + """User friendly string representation""" + return "Connection (%s) [%d]" % (self.Session.GetURI(), self.ID) + + def GetURI(self): + """Get URI of the connection""" + return self.Session.GetURI() + + def IsRemote(self): + """Returns True if the connection to a remote server, False if + it is local (built-in)""" + if self.Session.IsA("vtkSMSessionClient"): + return True + return False + + def GetNumberOfDataPartitions(self): + """Returns the number of partitions on the data server for this + connection""" + return self.Session.GetServerInformation().GetNumberOfProcesses() + + def AttachDefinitionUpdater(self): + """Attach observer to automatically update modules when needed.""" + # VTN: Observers are not supported + # ProxyDefinitionsUpdated = 2000 +## self.DefinitionObserverTag = self.Session.GetProxyDefinitionManager().AddObserver(2000, _update_definitions) + # CompoundProxyDefinitionsUpdated = 2001 +## self.CustomDefinitionObserverTag = self.Session.GetProxyDefinitionManager().AddObserver(2001, _update_definitions) + pass + + def close(self): + if self.DefinitionObserverTag: + self.Session.GetProxyDefinitionManager().RemoveObserver(self.DefinitionObserverTag) + self.Session.GetProxyDefinitionManager().RemoveObserver(self.CustomDefinitionObserverTag) + self.Session = None + self.Modules = None + self.Alive = False + + def __del__(self): + if self.Alive: + self.close() + +def SaveState(filename): + """Given a state filename, saves the state of objects registered + with the proxy manager.""" + pm = ProxyManager() + pm.SaveState(filename) + +def LoadState(filename, connection=None): + """Given a state filename and an optional connection, loads the server + manager state.""" + if not connection: + connection = ActiveConnection + if not connection: + raise RuntimeError, "Cannot load state without a connection" + pm = ProxyManager() + pm.LoadState(filename, None) + views = GetRenderViews() + for view in views: + # Make sure that the client window size matches the + # ViewSize property. In paraview, the GUI takes care + # of this. + if view.GetClassName() == "vtkSMIceTDesktopRenderViewProxy": + view.GetRenderWindow().SetSize(view.ViewSize[0], \ + view.ViewSize[1]) + +def InitFromGUI(): + """ + Method used to initialize the Python Shell from the ParaView GUI. + """ + global fromGUI, ActiveConnection +# if not fromGUI: +# print "from paraview.simple import *" + fromGUI = True + # ToggleProgressPrinting() ### FIXME COLLABORATION + enableMultiServer(vtkProcessModule.GetProcessModule().GetMultipleSessionsSupport()) + iter = vtkProcessModule.GetProcessModule().NewSessionIterator(); + iter.InitTraversal() + ActiveConnection = None + activeSession = vtkSMProxyManager.GetProxyManager().GetActiveSession() + tmpActiveConnection = None + while not iter.IsDoneWithTraversal(): + c = Connection(iter.GetCurrentSessionId(), iter.GetCurrentSession()) + if c.Session == activeSession: + tmpActiveConnection = c + iter.GoToNextItem() + iter.UnRegister(None) + if tmpActiveConnection: + ActiveConnection = tmpActiveConnection + +def Connect(ds_host=None, ds_port=11111, rs_host=None, rs_port=22221): + """ + Use this function call to create a new session. On success, + it returns a vtkSMSession object that abstracts the connection. + Otherwise, it returns None. + There are several ways in which this function can be called: + * When called with no arguments, it creates a new session + to the built-in server on the client itself. + * When called with ds_host and ds_port arguments, it + attempts to connect to a server(data and render server on the same server) + on the indicated host:port. + * When called with ds_host, ds_port, rs_host, rs_port, it + creates a new connection to the data server on ds_host:ds_port and to the + render server on rs_host: rs_port. + """ + if ds_host == None: + session = vtkSMSession() + elif rs_host == None: + session = vtkSMSessionClient() + session.Connect("cs://%s:%d" % (ds_host, ds_port)) + else: + session = vtkSMSessionClient() + session.Connect("cdsrs://%s:%d/%s:%d" % (ds_host, ds_port, rs_host, rs_port)) + id = vtkProcessModule.GetProcessModule().RegisterSession(session) + connection = Connection(id, session) + return connection + +def ReverseConnect(port=11111): + """ + Use this function call to create a new session. On success, + it returns a Session object that abstracts the connection. + Otherwise, it returns None. + In reverse connection mode, the client waits for a connection + from the server (client has to be started first). The server + then connects to the client (run pvserver with -rc and -ch + option). + The optional port specified the port to listen to. + """ + session = vtkSMSessionClient() + session.Connect("csrc://hostname:" + port) + id = vtkProcessModule.GetProcessModule().RegisterSession(session) + connection = Connection(id, session) + return connection + +def Disconnect(session=None): + """Disconnects the connection. Make sure to clear the proxy manager + first.""" + global ActiveConnection + global MultiServerConnections + global fromGUI + if fromGUI: + # Let the UI know that we want to disconnect + ActiveConnection.Session.InvokeEvent('ExitEvent') + return + if ActiveConnection and (not session or session == ActiveConnection.Session): + session = ActiveConnection.Session + if MultiServerConnections: + MultiServerConnections.remove(ActiveConnection) + ActiveConnection.close() + ActiveConnection = None + switchActiveConnection() + else: + ActiveConnection.close() + ActiveConnection = None + elif MultiServerConnections: + for connection in MultiServerConnections: + if connection.Session == session: + connection.close() + MultiServerConnections.remove(connection) + if session: + vtkProcessModule.GetProcessModule().UnRegisterSession(session) + return + +def CreateProxy(xml_group, xml_name, session=None): + """Creates a proxy. If session is set, the proxy's session is + set accordingly. If session is None, the current Session is used, if + present. You should not have to use method normally. Instantiate the + appropriate class from the appropriate module, for example: + sph = servermanager.sources.SphereSource()""" + global ActiveConnection + if not session: + session = ActiveConnection.Session + if not session: + raise RuntimeError, "Cannot create objects without a session." + pxm = ProxyManager(session) + return pxm.NewProxy(xml_group, xml_name) + +def GetRenderView(connection=None): + """Return the render view in use. If more than one render view is in + use, return the first one.""" + + render_module = None + for aProxy in ProxyManager(): + if aProxy.IsA("vtkSMRenderViewProxy"): + render_module = aProxy + break + return render_module + +def GetRenderViews(connection=None): + """Returns the set of all render views.""" + render_modules = [] + for aProxy in ProxyManager(): + if aProxy.IsA("vtkSMRenderViewProxy"): + render_modules.append(aProxy) + return render_modules + +def GetContextViews(connection=None): + """Returns the set of all context views.""" + context_modules = [] + for aProxy in ProxyManager(): + if aProxy.IsA("vtkSMContextViewProxy"): + context_modules.append(aProxy) + return context_modules + +def CreateRenderView(session=None, **extraArgs): + """Creates a render window on the particular session. If session + is not specified, then the active session is used, if available. + + This method can also be used to initialize properties by passing + keyword arguments where the key is the name of the property. In addition + registrationGroup and registrationName (optional) can be specified (as + keyword arguments) to automatically register the proxy with the proxy + manager.""" + return _create_view("RenderView", session, **extraArgs) + +def _create_view(view_xml_name, session=None, **extraArgs): + """Creates a view on the particular session. If session + is not specified, then the active session is used, if available. + This method can also be used to initialize properties by passing + keyword arguments where the key is the name of the property.""" + if not session: + session = ActiveConnection.Session + if not session: + raise RuntimeError, "Cannot create view without session." + pxm = ProxyManager() + view_module = None + if view_xml_name: + view_module = CreateProxy("views", view_xml_name, session) + if not view_module: + return None + extraArgs['proxy'] = view_module + python_proxy_name = _make_name_valid(view_module.GetXMLName()) + proxy = rendering.__dict__[python_proxy_name](**extraArgs) + return proxy + +def GetRepresentation(aProxy, view): + for rep in view.Representations: + #VSV: == + try: isRep = rep.Input.IsSame(aProxy) + except: isRep = False + if isRep: return rep + return None + +def CreateRepresentation(aProxy, view, **extraArgs): + """Creates a representation for the proxy and adds it to the render + module. + + This method can also be used to initialize properties by passing + keyword arguments where the key is the name of the property.In addition + registrationGroup and registrationName (optional) can be specified (as + keyword arguments) to automatically register the proxy with the proxy + manager. + + This method tries to create the best possible representation for the given + proxy in the given view. Additionally, the user can specify proxyName + (optional) to create a representation of a particular type.""" + + global rendering + if not aProxy: + raise RuntimeError, "proxy argument cannot be None." + if not view: + raise RuntimeError, "view argument cannot be None." + if "proxyName" in extraArgs: + display = CreateProxy("representations", extraArgs['proxyName'], None) + del extraArgs['proxyName'] + else: + display = view.SMProxy.CreateDefaultRepresentation(aProxy.SMProxy, 0) + if display: + display.UnRegister(None) + if not display: + return None + extraArgs['proxy'] = display + proxy = rendering.__dict__[display.GetXMLName()](**extraArgs) + proxy.Input = aProxy + proxy.UpdateVTKObjects() + view.Representations.append(proxy) + return proxy + +class _ModuleLoader(object): + def find_module(self, fullname, path=None): + if vtkPVPythonModule.HasModule(fullname): + return self + else: + return None + def load_module(self, fullname): + import imp + moduleInfo = vtkPVPythonModule.GetModule(fullname) + if not moduleInfo: + raise ImportError + module = sys.modules.setdefault(fullname, imp.new_module(fullname)) + module.__file__ = "<%s>" % moduleInfo.GetFullName() + module.__loader__ = self + if moduleInfo.GetIsPackage: + module.__path__ = moduleInfo.GetFullName() + code = compile(moduleInfo.GetSource(), module.__file__, 'exec') + exec code in module.__dict__ + return module + +def LoadXML(xmlstring): + """DEPRECATED. Given a server manager XML as a string, parse and process it.""" + raise RuntimeError, "Deprecated. Use LoadPlugin(...) instead." + + +def LoadPlugin(filename, remote=True, connection=None): + """ Given a filename and a session (optional, otherwise uses + ActiveConnection), loads a plugin. It then updates the sources, + filters and rendering modules.""" + + if not connection: + connection = ActiveConnection + if not connection: + raise RuntimeError, "Cannot load a plugin without a connection." + plm = vtkSMProxyManager.GetProxyManager().GetPluginManager() + + if remote: + status = plm.LoadRemotePlugin(filename, connection.Session) + else: + status = plm.LoadLocalPlugin(filename) + + # shouldn't the extension check happend before attempting to load the plugin? + if not status: + raise RuntimeError, "Problem loading plugin %s" % (filename) + else: + # we should never have to call this. The modules should update automatically. + updateModules(connection.Modules) + + +def Fetch(input, arg1=None, arg2=None, idx=0): + """ + A convenience method that moves data from the server to the client, + optionally performing some operation on the data as it moves. + The input argument is the name of the (proxy for a) source or filter + whose output is needed on the client. + + You can use Fetch to do three things: + + If arg1 is None (the default) then all of the data is brought to the client. + In parallel runs an appropriate append Filter merges the + data on each processor into one data object. The filter chosen will be + vtkAppendPolyData for vtkPolyData, vtkAppendRectilinearGrid for + vtkRectilinearGrid, vtkMultiBlockDataGroupFilter for vtkCompositeData, + and vtkAppendFilter for anything else. + + If arg1 is an integer then one particular processor's output is brought to + the client. In serial runs the arg is ignored. If you have a filter that + computes results in parallel and brings them to the root node, then set + arg to be 0. + + If arg1 and arg2 are a algorithms, for example vtkMinMax, the algorithm + will be applied to the data to obtain some result. Here arg1 will be + applied pre-gather and arg2 will be applied post-gather. In parallel + runs the algorithm will be run on each processor to make intermediate + results and then again on the root processor over all of the + intermediate results to create a global result. + + Optional argument idx is used to specify the output port number to fetch the + data from. Default is port 0. + """ + + import types + + reducer = filters.ReductionFilter(Input=OutputPort(input,idx)) + + #create the pipeline that reduces and transmits the data + if arg1 == None: + cdinfo = input.GetDataInformation(idx).GetCompositeDataInformation() + if cdinfo.GetDataIsComposite(): + print "use composite data append" + reducer.PostGatherHelperName = "vtkMultiBlockDataGroupFilter" + + elif input.GetDataInformation(idx).GetDataClassName() == "vtkPolyData": + print "use append poly data filter" + reducer.PostGatherHelperName = "vtkAppendPolyData" + + elif input.GetDataInformation(idx).GetDataClassName() == "vtkRectilinearGrid": + print "use append rectilinear grid filter" + reducer.PostGatherHelperName = "vtkAppendRectilinearGrid" + + elif input.GetDataInformation(idx).IsA("vtkDataSet"): + print "use unstructured append filter" + reducer.PostGatherHelperName = "vtkAppendFilter" + + elif type(arg1) is types.IntType: + reducer.PassThrough = arg1 + + else: + reducer.PreGatherHelper = arg1 + reducer.PostGatherHelper = arg2 + + # reduce + reducer.UpdatePipeline() + dataInfo = reducer.GetDataInformation(0) + dataType = dataInfo.GetDataSetType() + if dataInfo.GetCompositeDataSetType() > 0: + dataType = dataInfo.GetCompositeDataSetType() + + fetcher = filters.ClientServerMoveData(Input=reducer) + fetcher.OutputDataType = dataType + fetcher.WholeExtent = dataInfo.GetExtent()[:] + #fetch + fetcher.UpdatePipeline() + + op = fetcher.GetClientSideObject().GetOutputDataObject(0) + opc = op.NewInstance() + opc.ShallowCopy(op) + opc.UnRegister(None) + return opc + +def AnimateReader(reader, view, filename=None): + """This is a utility function that, given a reader and a view + animates over all time steps of the reader. If the optional + filename is provided, a movie is created (type depends on the + extension of the filename.""" + if not reader: + raise RuntimeError, "No reader was specified, cannot animate." + if not view: + raise RuntimeError, "No view was specified, cannot animate." + # Create an animation scene + scene = animation.AnimationScene() + + # We need to have the reader and the view registered with + # the time keeper. This is how the scene gets its time values. + try: + tk = ProxyManager().GetProxiesInGroup("timekeeper").values()[0] + scene.TimeKeeper = tk + except IndexError: + tk = misc.TimeKeeper() + scene.TimeKeeper = tk + + if not reader in tk.TimeSources: + tk.TimeSources.append(reader) + if not view in tk.Views: + tk.Views.append(view) + + + # with 1 view + scene.ViewModules = [view] + # Update the reader to get the time information + reader.UpdatePipelineInformation() + # Animate from 1st time step to last + scene.StartTime = reader.TimestepValues.GetData()[0] + scene.EndTime = reader.TimestepValues.GetData()[-1] + + # Each frame will correspond to a time step + scene.PlayMode = 2 #Snap To Timesteps + + # Create a special animation cue for time. + cue = animation.TimeAnimationCue() + cue.AnimatedProxy = view + cue.AnimatedPropertyName = "ViewTime" + scene.Cues = [cue] + + if filename: + writer = vtkSMAnimationSceneImageWriter() + writer.SetFileName(filename) + writer.SetFrameRate(1) + writer.SetAnimationScene(scene.SMProxy) + + # Now save the animation. + if not writer.Save(): + raise RuntimeError, "Saving of animation failed!" + else: + scene.Play() + return scene + +def GetProgressPrintingIsEnabled(): + return progressObserverTag is not None + +def SetProgressPrintingEnabled(value): + """Is not supported because of not supported observers""" + pass + +def ToggleProgressPrinting(): + """Turn on/off printing of progress. See SetProgressPrintingEnabled.""" + SetProgressPrintingEnabled(not GetProgressPrintingIsEnabled()) + +def Finalize(): + """Although not required, this can be called at exit to cleanup.""" + global progressObserverTag + # Make sure to remove the observer + if progressObserverTag: + ToggleProgressPrinting() + vtkInitializationHelper.Finalize() + +# Internal methods + +def _getPyProxy(smproxy, outputPort=0): + """Returns a python wrapper for a server manager proxy. This method + first checks if there is already such an object by looking in the + _pyproxies group and returns it if found. Otherwise, it creates a + new one. Proxies register themselves in _pyproxies upon creation.""" + if not smproxy: + return None + if (smproxy, outputPort) in _pyproxies: + return _pyproxies[(smproxy, outputPort)]() + + xmlName = smproxy.GetXMLName() + if smproxy.GetXMLLabel(): + xmlName = smproxy.GetXMLLabel() + classForProxy = _findClassForProxy(_make_name_valid(xmlName), smproxy.GetXMLGroup()) + if classForProxy: + retVal = classForProxy(proxy=smproxy, port=outputPort) + else: + retVal = Proxy(proxy=smproxy, port=outputPort) + return retVal + +def _makeUpdateCameraMethod(rv): + """ This internal method is used to create observer methods """ + if not hasattr(rv(), "BlockUpdateCamera"): + rv().add_attribute("BlockUpdateCamera", False) + def UpdateCamera(obj, string): + if not rv().BlockUpdateCamera: + # used to avoid some nasty recursion that occurs when interacting in + # the GUI. + rv().BlockUpdateCamera = True + rv().SynchronizeCameraProperties() + rv().BlockUpdateCamera = False + return UpdateCamera + +def _createInitialize(group, name): + """Internal method to create an Initialize() method for the sub-classes + of Proxy""" + pgroup = group + pname = name + def aInitialize(self, connection=None, update=True): + if not connection: + connection = ActiveConnection + if not connection: + raise RuntimeError,\ + 'Cannot create a proxy without a session.' + if not connection.Session.GetProxyDefinitionManager().HasDefinition(pgroup, pname): + error_msg = "The connection does not provide any definition for %s." % pname + raise RuntimeError, error_msg + self.InitializeFromProxy(\ + CreateProxy(pgroup, pname, connection.Session), update) + return aInitialize + +def _createGetProperty(pName): + """Internal method to create a GetXXX() method where XXX == pName.""" + propName = pName + def getProperty(self): + return self.GetPropertyValue(propName) + return getProperty + +def _createSetProperty(pName): + """Internal method to create a SetXXX() method where XXX == pName.""" + propName = pName + def setProperty(self, value): + return self.SetPropertyWithName(propName, value) + return setProperty + +def _findClassForProxy(xmlName, xmlGroup): + """Given the xmlName for a proxy, returns a Proxy class. Note + that if there are duplicates, the first one is returned.""" + global sources, filters, writers, rendering, animation, implicit_functions,\ + piecewise_functions, extended_sources, misc + if not xmlName: + return None + if xmlGroup == "sources": + return sources.__dict__[xmlName] + elif xmlGroup == "filters": + return filters.__dict__[xmlName] + elif xmlGroup == "implicit_functions": + return implicit_functions.__dict__[xmlName] + elif xmlGroup == "piecewise_functions": + return piecewise_functions.__dict__[xmlName] + elif xmlGroup == "writers": + return writers.__dict__[xmlName] + elif xmlGroup == "extended_sources": + return extended_sources.__dict__[xmlName] + elif xmlName in rendering.__dict__: + return rendering.__dict__[xmlName] + elif xmlName in animation.__dict__: + return animation.__dict__[xmlName] + elif xmlName in misc.__dict__: + return misc.__dict__[xmlName] + else: + return None + +def _printProgress(caller, event): + """The default event handler for progress. Prints algorithm + name and 1 '.' per 10% progress.""" + global currentAlgorithm, currentProgress + + pm = vtkProcessModule.GetProcessModule() + progress = pm.GetLastProgress() / 10 + # If we got a 100% as the first thing, ignore + # This is to get around the fact that some vtk + # algorithms report 100% more than once (which is + # a bug) + if not currentAlgorithm and progress == 10: + return + alg = pm.GetLastProgressName() + if alg != currentAlgorithm and alg: + if currentAlgorithm: + while currentProgress <= 10: + import sys + sys.stdout.write(".") + currentProgress += 1 + print "]" + currentProgress = 0 + print alg, ": [ ", + currentAlgorithm = alg + while currentProgress <= progress: + import sys + sys.stdout.write(".") + #sys.stdout.write("%d " % pm.GetLastProgress()) + currentProgress += 1 + if progress == 10: + print "]" + currentAlgorithm = None + currentProgress = 0 + +def updateModules(m): + """Called when a plugin is loaded, this method updates + the proxy class object in all known modules.""" + + createModule("sources", m.sources) + createModule("filters", m.filters) + createModule("writers", m.writers) + createModule("representations", m.rendering) + createModule("views", m.rendering) + createModule("lookup_tables", m.rendering) + createModule("textures", m.rendering) + createModule('cameramanipulators', m.rendering) + createModule("animation", m.animation) + createModule("misc", m.misc) + createModule('animation_keyframes', m.animation) + createModule('implicit_functions', m.implicit_functions) + createModule('piecewise_functions', m.piecewise_functions) + createModule("extended_sources", m.extended_sources) + createModule("incremental_point_locators", m.misc) + +def _createModules(m): + """Called when the module is loaded, this creates sub- + modules for all know proxy groups.""" + + m.sources = createModule('sources') + m.filters = createModule('filters') + m.writers = createModule('writers') + m.rendering = createModule('representations') + createModule('views', m.rendering) + createModule("lookup_tables", m.rendering) + createModule("textures", m.rendering) + createModule('cameramanipulators', m.rendering) + m.animation = createModule('animation') + createModule('animation_keyframes', m.animation) + m.implicit_functions = createModule('implicit_functions') + m.piecewise_functions = createModule('piecewise_functions') + m.extended_sources = createModule("extended_sources") + m.misc = createModule("misc") + createModule("incremental_point_locators", m.misc) + +class PVModule(object): + pass + +def _make_name_valid(name): + """Make a string into a valid Python variable name.""" + if not name: + return None + import string + valid_chars = "_%s%s" % (string.ascii_letters, string.digits) + name = str().join([c for c in name if c in valid_chars]) + if not name[0].isalpha(): + name = 'a' + name + return name + +def createModule(groupName, mdl=None): + """Populates a module with proxy classes defined in the given group. + If mdl is not specified, it also creates the module""" + global ActiveConnection + + if not ActiveConnection: + raise RuntimeError, "Please connect to a server using \"Connect\"" + + pxm = ProxyManager() + # Use prototypes to find all proxy types. + pxm.InstantiateGroupPrototypes(groupName) + + debug = False + if not mdl: + debug = True + mdl = PVModule() + definitionIter = pxm.NewDefinitionIterator(groupName) + for i in definitionIter: + proxyName = i['key'] + proto = pxm.GetPrototypeProxy(groupName, proxyName) + if not proto: + print "Error while loading %s/%s %s"%(groupName, i['group'], proxyName) + continue + pname = proxyName + if proto.GetXMLLabel(): + pname = proto.GetXMLLabel() + pname = _make_name_valid(pname) + if not pname: + continue + if pname in mdl.__dict__: + if debug: + print "Warning: %s is being overwritten. This may point to an issue in the ParaView configuration files" % pname + cdict = {} + # Create an Initialize() method for this sub-class. + cdict['Initialize'] = _createInitialize(groupName, proxyName) + iter = PropertyIterator(proto) + # Add all properties as python properties. + for prop in iter: + propName = iter.GetKey() + if (prop.GetInformationOnly() and propName != "TimestepValues" ) \ + or prop.GetIsInternal(): + continue + names = [propName] + names = [iter.PropertyLabel] + + propDoc = None + if prop.GetDocumentation(): + propDoc = prop.GetDocumentation().GetDescription() + for name in names: + name = _make_name_valid(name) + if name: + cdict[name] = property(_createGetProperty(propName), + _createSetProperty(propName), + None, + propDoc) + # Add the documentation as the class __doc__ + if proto.GetDocumentation() and \ + proto.GetDocumentation().GetDescription(): + doc = proto.GetDocumentation().GetDescription() + else: + doc = Proxy.__doc__ + cdict['__doc__'] = doc + # Create the new type + if proto.GetXMLName() == "ExodusIIReader": + superclasses = (ExodusIIReaderProxy,) + elif proto.IsA("vtkSMSourceProxy"): + superclasses = (SourceProxy,) + elif proto.IsA("vtkSMViewLayoutProxy"): + superclasses = (ViewLayoutProxy,) + else: + superclasses = (Proxy,) + + cobj = type(pname, superclasses, cdict) + # Add it to the modules dictionary + mdl.__dict__[pname] = cobj + return mdl + + +def __determineGroup(proxy): + """Internal method""" + if not proxy: + return None + xmlgroup = proxy.GetXMLGroup() + xmlname = proxy.GetXMLName() + if xmlgroup == "sources": + if xmlname in ["BlockSelectionSource", + "FrustumSelectionSource", + "GlobalIDSelectionSource", + "PedigreeIDSelectionSource", + "IDSelectionSource", + "CompositeDataIDSelectionSource", + "HierarchicalDataIDSelectionSource", + "ThresholdSelectionSource", + "LocationSelectionSource"]: + return "selection_sources" + return "sources" + elif xmlgroup == "filters": + return "sources" + elif xmlgroup == "representations": + if xmlname == "ScalarBarWidgetRepresentation": + return "scalar_bars" + return "representations" + elif xmlgroup == "animation_keyframes": + return "animation" + return xmlgroup + +__nameCounter = {} +def __determineName(proxy, group): + global __nameCounter + name = _make_name_valid(proxy.GetXMLLabel()) + if not name: + return None + if not __nameCounter.has_key(name): + __nameCounter[name] = 1 + val = 1 + else: + __nameCounter[name] += 1 + val = __nameCounter[name] + return "%s%d" % (name, val) + +def __getName(proxy, group): + pxm = ProxyManager(proxy.GetSession()) + if isinstance(proxy, Proxy): + proxy = proxy.SMProxy + return pxm.GetProxyName(group, proxy) + +class MissingRegistrationInformation(Exception): + """Exception for missing registration information. Raised when a name or group + is not specified or when a group cannot be deduced.""" + pass + +class MissingProxy(Exception): + """Exception fired when the requested proxy is missing.""" + pass + +def Register(proxy, **extraArgs): + """Registers a proxy with the proxy manager. If no 'registrationGroup' is + specified, then the group is inferred from the type of the proxy. + 'registrationName' may be specified to register with a particular name + otherwise a default name will be created.""" + # TODO: handle duplicate registration + if "registrationGroup" in extraArgs: + registrationGroup = extraArgs["registrationGroup"] + else: + registrationGroup = __determineGroup(proxy) + + if "registrationName" in extraArgs: + registrationName = extraArgs["registrationName"] + else: + registrationName = __determineName(proxy, registrationGroup) + if registrationGroup and registrationName: + pxm = ProxyManager() + pxm.RegisterProxy(registrationGroup, registrationName, proxy) + else: + raise MissingRegistrationInformation, "Registration error %s %s." % (registrationGroup, registrationName) + return (registrationGroup, registrationName) + +def UnRegister(proxy, **extraArgs): + """UnRegisters proxies registered using Register().""" + if "registrationGroup" in extraArgs: + registrationGroup = extraArgs["registrationGroup"] + else: + registrationGroup = __determineGroup(proxy) + + if "registrationName" in extraArgs: + registrationName = extraArgs["registrationName"] + else: + registrationName = __getName(proxy, registrationGroup) + + if registrationGroup and registrationName: + pxm = ProxyManager() + pxm.UnRegisterProxy(registrationGroup, registrationName, proxy) + else: + raise RuntimeError, "UnRegistration error." + return (registrationGroup, registrationName) + +def demo1(): + """This simple demonstration creates a sphere, renders it and delivers + it to the client using Fetch. It returns a tuple of (data, render + view)""" + if not ActiveConnection: + Connect() + ss = sources.Sphere(Radius=2, ThetaResolution=32) + shr = filters.Shrink(Input=OutputPort(ss,0)) + cs = sources.Cone() + app = filters.AppendDatasets() + app.Input = [shr, cs] + rv = CreateRenderView() + rep = CreateRepresentation(app, rv) + rv.ResetCamera() + rv.StillRender() + data = Fetch(ss) + + return (data, rv) + +def demo2(fname="/Users/berk/Work/ParaViewData/Data/disk_out_ref.ex2"): + """This method demonstrates the user of a reader, representation and + view. It also demonstrates how meta-data can be obtained using proxies. + Make sure to pass the full path to an exodus file. Also note that certain + parameters are hard-coded for disk_out_ref.ex2 which can be found + in ParaViewData. This method returns the render view.""" + if not ActiveConnection: + Connect() + # Create the exodus reader and specify a file name + reader = sources.ExodusIIReader(FileName=fname) + # Get the list of point arrays. + arraySelection = reader.PointVariables + print arraySelection.Available + # Select all arrays + arraySelection.SetData(arraySelection.Available) + + # Next create a default render view appropriate for the session type. + rv = CreateRenderView() + # Create the matching representation + rep = CreateRepresentation(reader, rv) + rep.Representation = 1 # Wireframe + # Black background is not pretty + rv.Background = [0.4, 0.4, 0.6] + rv.StillRender() + # Reset the camera to include the whole thing + rv.ResetCamera() + rv.StillRender() + # Change the elevation of the camera. See VTK documentation of vtkCamera + # for camera parameters. + c = rv.GetActiveCamera() + c.Elevation(45) + rv.StillRender() + # Now that the reader execute, let's get some information about it's + # output. + pdi = reader[0].PointData + # This prints a list of all read point data arrays as well as their + # value ranges. + print 'Number of point arrays:', len(pdi) + for i in range(len(pdi)): + ai = pdi[i] + print "----------------" + print "Array:", i, ai.Name, ":" + numComps = ai.GetNumberOfComponents() + print "Number of components:", numComps + for j in range(numComps): + print "Range:", ai.GetRange(j) + # White is boring. Let's color the geometry using a variable. + # First create a lookup table. This object controls how scalar + # values are mapped to colors. See VTK documentation for + # details. + lt = rendering.PVLookupTable() + # Assign it to the representation + rep.LookupTable = lt + # Color by point array called Pres + rep.ColorAttributeType = 0 # point data + rep.ColorArrayName = "Pres" + # Add to RGB points. These are tuples of 4 values. First one is + # the scalar values, the other 3 the RGB values. This list has + # 2 points: Pres: 0.00678, color: blue, Pres: 0.0288, color: red + lt.RGBPoints = [0.00678, 0, 0, 1, 0.0288, 1, 0, 0] + lt.ColorSpace = 1 # HSV + rv.StillRender() + return rv + +def demo3(): + """This method demonstrates the use of servermanager with numpy as + well as pylab for plotting. It creates an artificial data sources, + probes it with a line, delivers the result to the client using Fetch + and plots it using pylab. This demo requires numpy and pylab installed. + It returns a tuple of (data, render view).""" + import paraview.numpy_support + import pylab + + if not ActiveConnection: + Connect() + # Create a synthetic data source + source = sources.Wavelet() + # Let's get some information about the data. First, for the + # source to execute + source.UpdatePipeline() + + di = source.GetDataInformation() + print "Data type:", di.GetPrettyDataTypeString() + print "Extent:", di.GetExtent() + print "Array name:", \ + source[0].PointData[0].Name + + rv = CreateRenderView() + + rep1 = CreateRepresentation(source, rv) + rep1.Representation = 3 # outline + + # Let's apply a contour filter + cf = filters.Contour(Input=source, ContourValues=[200]) + + # Select the array to contour by + #cf.SelectInputScalars = 'RTData' + + rep2 = CreateRepresentation(cf, rv) + + rv.Background = (0.4, 0.4, 0.6) + # Reset the camera to include the whole thing + rv.StillRender() + rv.ResetCamera() + rv.StillRender() + + # Now, let's probe the data + probe = filters.ResampleWithDataset(Input=source) + # with a line + line = sources.Line(Resolution=60) + # that spans the dataset + bounds = di.GetBounds() + print "Bounds: ", bounds + line.Point1 = bounds[0:6:2] + line.Point2 = bounds[1:6:2] + + probe.Source = line + + # Render with the line + rep3 = CreateRepresentation(line, rv) + rv.StillRender() + + # Now deliver it to the client. Remember, this is for small data. + data = Fetch(probe) + # Convert it to a numpy array + data = paraview.numpy_support.vtk_to_numpy( + data.GetPointData().GetArray("RTData")) + # Plot it using matplotlib + pylab.plot(data) + pylab.show() + + return (data, rv, probe) + +def demo4(fname="/Users/berk/Work/ParaViewData/Data/can.ex2"): + """This method demonstrates the user of AnimateReader for + creating animations.""" + if not ActiveConnection: + Connect() + reader = sources.ExodusIIReader(FileName=fname) + view = CreateRenderView() + repr = CreateRepresentation(reader, view) + view.StillRender() + view.ResetCamera() + view.StillRender() + c = view.GetActiveCamera() + c.Elevation(95) + return AnimateReader(reader, view) + + +def demo5(): + """ Simple sphere animation""" + if not ActiveConnection: + Connect() + sphere = sources.Sphere() + view = CreateRenderView() + repr = CreateRepresentation(sphere, view) + + view.StillRender() + view.ResetCamera() + view.StillRender() + + # Create an animation scene + scene = animation.AnimationScene() + # Add 1 view + scene.ViewModules = [view] + + # Create a cue to animate the StartTheta property + cue = animation.KeyFrameAnimationCue() + cue.AnimatedProxy = sphere + cue.AnimatedPropertyName = "StartTheta" + # Add it to the scene's cues + scene.Cues = [cue] + + # Create 2 keyframes for the StartTheta track + keyf0 = animation.CompositeKeyFrame() + keyf0.Type = 2 # Set keyframe interpolation type to Ramp. + # At time = 0, value = 0 + keyf0.KeyTime = 0 + keyf0.KeyValues= [0] + + keyf1 = animation.CompositeKeyFrame() + # At time = 1.0, value = 200 + keyf1.KeyTime = 1.0 + keyf1.KeyValues= [200] + + # Add keyframes. + cue.KeyFrames = [keyf0, keyf1] + + scene.Play() + return scene + +ASSOCIATIONS = { 'POINTS' : 0, 'CELLS' : 1, 'VERTICES' : 4, 'EDGES' : 5, 'ROWS' : 6} + +# Users can set the active connection which will be used by API +# to create proxies etc when no connection argument is passed. +# Connect() automatically sets this if it is not already set. +ActiveConnection = None + +# Fields for multi-server support +MultiServerConnections = None + +# API for multi-server support +def enableMultiServer(multiServer=True): + """This method enable the current servermanager to support several + connections. Once we enable the multi-server support, the user can create + as many connection as he want and switch from one to another in order to + create and manage proxy.""" + global MultiServerConnections, ActiveConnection + if not multiServer and MultiServerConnections: + raise RuntimeError, "Once we enable Multi-Server support we can not get back" + MultiServerConnections = [] + if ActiveConnection: + MultiServerConnections.append(ActiveConnection) + +def switchActiveConnection(newActiveConnection=None): + """Switch active connection to be the provided one or if none just pick the + other one""" + global MultiServerConnections, ActiveConnection + if MultiServerConnections == None: + raise RuntimeError, "enableMultiServer() must be called before" + + # Manage the case when no connection is provided + if newActiveConnection: + ActiveConnection = newActiveConnection + __exposeActiveModules__() + # Update active session for ParaView + if vtkSMProxyManager.GetProxyManager().GetActiveSession() != ActiveConnection.Session: + vtkSMProxyManager.GetProxyManager().SetActiveSession(ActiveConnection.Session) + return ActiveConnection + else: + for connection in MultiServerConnections: + if connection != ActiveConnection: + ActiveConnection = connection + __exposeActiveModules__() + # Update active session for ParaView + if vtkSMProxyManager.GetProxyManager().GetActiveSession() != ActiveConnection.Session: + vtkSMProxyManager.GetProxyManager().SetActiveSession(ActiveConnection.Session) + return ActiveConnection + return None + +# Needs to be called when paraview module is loaded from python instead +# of pvpython, pvbatch or GUI. +if not vtkProcessModule.GetProcessModule(): +# pvoptions = None Not applicable for SALOME Python console +# if paraview.options.batch: +# pvoptions = vtkPVOptions(); +# pvoptions.SetProcessType(0x40) +# if paraview.options.symmetric: +# pvoptions.SetSymmetricMPIMode(True) + vtkInitializationHelper.Initialize(sys.executable, + vtkProcessModule.PROCESS_CLIENT, pvoptions) + +# Initialize progress printing. Can be turned off by calling +# ToggleProgressPrinting() again. +progressObserverTag = None +currentAlgorithm = False +currentProgress = 0 +fromGUI = False +ToggleProgressPrinting() + +_pyproxies = {} + +# Create needed sub-modules +# We can no longer create modules, unless we have connected to a server. +# _createModules() + +# Set up our custom importer (if possible) +loader = _ModuleLoader() +sys.meta_path.append(loader) + +def __InitAfterConnect__(connection): + """ + This function is called everytime after a server connection is made. + Since the ProxyManager and all proxy definitions are changed every time a + new connection is made, we re-create all the modules + """ + _createModules(connection.Modules) + ## VSV fromFilter is alwais False for SALOME because it can't be changed from ParaView code + #if not paraview.fromFilter: + # fromFilter is set when this module is imported from the programmable + # filter +# global _defUpdater +# _defUpdater = __DefinitionUpdater() + connection.AttachDefinitionUpdater() + pass + +def __exposeActiveModules__(): + """Update servermanager submodules to point to the current + ActiveConnection.Modules.*""" + # Expose all active module to the current servermanager module + if ActiveConnection: + for m in [mName for mName in dir(ActiveConnection.Modules) if mName[0] != '_' ]: + exec "global %s;%s = ActiveConnection.Modules.%s" % (m,m,m) + +# Definitions for working in SALOME GUI mode +#aParams = myParavis.GetConnectionParameters() +#ActiveConnection = Connect() +##Connection(aParams[0]) +#ActiveConnection.SetHost(aParams[1], aParams[2], aParams[3], aParams[4], aParams[5]) +#ToggleProgressPrinting() +#fromGUI = True + +InitFromGUI() + +if hasattr(sys, "ps1"): + # session is interactive. + print vtkSMProxyManager.GetParaViewSourceVersion(); + +def GetConnectionFromId(id): + for connection in MultiServerConnections: + if connection.ID == id: + return connection + return None + +def GetConnectionFromSession(session): + for connection in MultiServerConnections: + if connection.Session == session: + return connection + return None + +def GetConnectionAt(index): + return MultiServerConnections[index] + +def GetNumberOfConnections(): + return len(MultiServerConnections) + +#VTN: Problem during execution +#atexit.register(vtkPythonProgrammableFilter.DeleteGlobalPythonInterpretor) diff --git a/src/PV_SWIG/presentations.py b/src/PV_SWIG/presentations.py index 5169a60d..bf1fac34 100644 --- a/src/PV_SWIG/presentations.py +++ b/src/PV_SWIG/presentations.py @@ -53,6 +53,7 @@ GAP_COEFFICIENT = 0.0001 # Globals _current_bar = None +_med_field_sep = '@@][@@' # Enumerations @@ -97,11 +98,11 @@ class EntityType: NODE = 0 CELL = 1 - _type2name = {NODE: 'OnPoint', - CELL: 'OnCell'} + _type2name = {NODE: 'P1', + CELL: 'P0'} - _name2type = {'OnPoint': NODE, - 'OnCell': CELL} + _name2type = {'P1': NODE, + 'P0': CELL} _type2pvtype = {NODE: 'POINT_DATA', CELL: 'CELL_DATA'} @@ -171,6 +172,42 @@ class GaussType: # Auxiliary functions + +def get_field_mesh_name(full_field_name): + """Return mesh name of the field by its full name.""" + aList = full_field_name.split('/') + if len(aList) >= 2 : + field_name = full_field_name.split('/')[1] + return field_name + + +def get_field_entity(full_field_name): + """Return entity type of the field by its full name.""" + aList = full_field_name.split(_med_field_sep) + if len(aList) == 2 : + entity_name = full_field_name.split(_med_field_sep)[-1] + entity = EntityType.get_type(entity_name) + return entity + + +def get_field_short_name(full_field_name): + """Return short name of the field by its full name.""" + aList = full_field_name.split('/') + if len(aList) == 4 : + short_name_with_type = full_field_name.split('/')[-1] + short_name = short_name_with_type.split(_med_field_sep)[0] + return short_name + + +def find_mesh_full_name(proxy, short_mesh_name): + """Return full mesh path by short mesh name, if found""" + proxy.UpdatePipeline() + all_mesh_names = get_mesh_full_names(proxy) + for name in all_mesh_names: + if short_mesh_name == get_field_short_name(name): + return name + + def process_prs_for_test(prs, view, picture_name, show_bar=True): """Show presentation and record snapshot image. @@ -243,9 +280,13 @@ def hide_all(view, to_remove=False): def display_only(prs, view=None): """Display only the given presentation in the view.""" - hide_all(view) - if (hasattr(prs, 'Visibility') and prs.Visibility != 1): - prs.Visibility = 1 + if not view: + view = pvs.GetRenderView() + + rep_list = view.Representations + for rep in rep_list: + if hasattr(rep, 'Visibility'): + rep.Visibility = (rep == prs) pvs.Render(view=view) @@ -328,6 +369,7 @@ def get_data_range(proxy, entity, field_name, vector_mode='Magnitude', Data range as [min, max] """ + proxy.UpdatePipeline() entity_data_info = None field_data = proxy.GetFieldDataInformation() @@ -360,6 +402,7 @@ def get_data_range(proxy, entity, field_name, vector_mode='Magnitude', def get_bounds(proxy): """Get bounds of the proxy in 3D.""" + proxy.UpdatePipeline() dataInfo = proxy.GetDataInformation() bounds_info = dataInfo.GetBounds() return bounds_info @@ -367,24 +410,28 @@ def get_bounds(proxy): def get_x_range(proxy): """Get X range of the proxy bounds in 3D.""" + proxy.UpdatePipeline() bounds_info = get_bounds(proxy) return bounds_info[0:2] def get_y_range(proxy): """Get Y range of the proxy bounds in 3D.""" + proxy.UpdatePipeline() bounds_info = get_bounds(proxy) return bounds_info[2:4] def get_z_range(proxy): """Get Z range of the proxy bounds in 3D.""" + proxy.UpdatePipeline() bounds_info = get_bounds(proxy) return bounds_info[4:6] def is_planar_input(proxy): """Check if the given input is planar.""" + proxy.UpdatePipeline() bounds_info = get_bounds(proxy) if (abs(bounds_info[0] - bounds_info[1]) <= FLT_MIN or @@ -397,6 +444,7 @@ def is_planar_input(proxy): def is_data_on_cells(proxy, field_name): """Check the existence of a field on cells with the given name.""" + proxy.UpdatePipeline() cell_data_info = proxy.GetCellDataInformation() return (field_name in cell_data_info.keys()) @@ -409,6 +457,7 @@ def is_empty(proxy): False: otherwise """ + proxy.UpdatePipeline() data_info = proxy.GetDataInformation() nb_cells = data_info.GetNumberOfCells() @@ -419,6 +468,7 @@ def is_empty(proxy): def get_orientation(proxy): """Get the optimum cutting plane orientation for Plot 3D.""" + proxy.UpdatePipeline() orientation = Orientation.XY bounds = get_bounds(proxy) @@ -590,14 +640,17 @@ def get_contours(scalar_range, nb_contours): def get_nb_components(proxy, entity, field_name): """Return number of components for the field.""" + proxy.UpdatePipeline() entity_data_info = None field_data = proxy.GetFieldDataInformation() if field_name in field_data.keys(): entity_data_info = field_data elif entity == EntityType.CELL: + select_cells_with_data(proxy, on_cells=[field_name]) entity_data_info = proxy.GetCellDataInformation() elif entity == EntityType.NODE: + select_cells_with_data(proxy, on_points=[field_name]) entity_data_info = proxy.GetPointDataInformation() nb_comp = None @@ -643,6 +696,7 @@ def get_scale_factor(proxy): def get_default_scale(prs_type, proxy, entity, field_name): """Get default scale factor.""" + proxy.UpdatePipeline() data_range = get_data_range(proxy, entity, field_name) if prs_type == PrsTypeEnum.DEFORMEDSHAPE: @@ -670,6 +724,7 @@ def get_calc_magnitude(proxy, array_entity, array_name): the calculator object. """ + proxy.UpdatePipeline() calculator = None # Transform vector array to scalar array if possible @@ -704,6 +759,7 @@ def get_add_component_calc(proxy, array_entity, array_name): the calculator object. """ + proxy.UpdatePipeline() calculator = None nb_components = get_nb_components(proxy, array_entity, array_name) @@ -727,14 +783,13 @@ def select_all_cells(proxy): Used in creation of mesh/submesh presentation. """ - ### Old API all_cell_types = proxy.CellTypes.Available - all_cell_types = proxy.Entity.Available - ### Old API proxy.CellTypes = all_cell_types - proxy.Entity = all_cell_types proxy.UpdatePipeline() + extractCT = pvs.ExtractCellType() + extractCT.AllGeoTypes = extractCT.GetProperty("GeoTypesInfo")[::2] + extractCT.UpdatePipelineInformation() -def select_cells_with_data(proxy, on_points=None, on_cells=None): +def select_cells_with_data(proxy, on_points=[], on_cells=[], on_gauss=[]): """Select cell types with data. Only cell types with data for the given fields will be selected. @@ -742,8 +797,36 @@ def select_cells_with_data(proxy, on_points=None, on_cells=None): types with data for even one field (from available) will be selected. """ - if not hasattr(proxy, 'Entity'): + if not proxy.GetProperty("FieldsTreeInfo"): return + + proxy.UpdatePipeline() + if not hasattr(proxy, 'Entity'): + fields_info = proxy.GetProperty("FieldsTreeInfo")[::2] + arr_name_with_dis=[elt.split("/")[-1] for elt in fields_info] + + proxy.AllArrays = [] + proxy.UpdatePipeline() + + fields = [] + for name in on_gauss: + fields.append(name+_med_field_sep+'GAUSS') + for name in on_cells: + fields.append(name+_med_field_sep+'P0') + for name in on_points: + fields.append(name+_med_field_sep+'P1') + + field_list = [] + for name in fields: + if arr_name_with_dis.count(name) > 0: + index = arr_name_with_dis.index(name) + field_list.append(fields_info[index]) + + proxy.AllArrays = field_list + proxy.UpdatePipeline() + return len(field_list) != 0 + + # TODO: VTN. Looks like this code is out of date. #all_cell_types = proxy.CellTypes.Available all_cell_types = proxy.Entity.Available @@ -786,63 +869,9 @@ def select_cells_with_data(proxy, on_points=None, on_cells=None): proxy.Entity = cell_types_on proxy.UpdatePipeline() - -def extract_groups_for_field(proxy, field_name, field_entity, force=False): - """Exctract only groups which have the field. - - Arguments: - proxy: the pipeline object, containig data - field_name: the field name - field_entity: the field entity - force: if True - ExtractGroup object will be created in any case - - Returns: - ExtractGroup object: if not all groups have the field or - the force argument is true - The initial proxy: if no groups had been filtered. - - """ - source = proxy - - # Remember the state - initial_groups = list(proxy.Groups) - - # Get data information for the field entity - entity_data_info = None - field_data = proxy.GetFieldDataInformation() - - if field_name in field_data.keys(): - entity_data_info = field_data - elif field_entity == EntityType.CELL: - entity_data_info = proxy.GetCellDataInformation() - elif field_entity == EntityType.NODE: - entity_data_info = proxy.GetPointDataInformation() - - # Collect groups for extraction - groups_to_extract = [] - - for group in initial_groups: - proxy.Groups = [group] - proxy.UpdatePipeline() - if field_name in entity_data_info.keys(): - groups_to_extract.append(group) - - # Restore state - proxy.Groups = initial_groups - proxy.UpdatePipeline() - - # Extract groups if necessary - if force or (len(groups_to_extract) < len(initial_groups)): - extract_group = pvs.ExtractGroup(proxy) - extract_group.Groups = groups_to_extract - extract_group.UpdatePipeline() - source = extract_group - - return source - - -def if_possible(proxy, field_name, entity, prs_type): +def if_possible(proxy, field_name, entity, prs_type, extrGrps=None): """Check if the presentation creation is possible on the given field.""" + proxy.UpdatePipeline() result = True if (prs_type == PrsTypeEnum.DEFORMEDSHAPE or prs_type == PrsTypeEnum.DEFORMEDSHAPESCALARMAP or @@ -854,7 +883,7 @@ def if_possible(proxy, field_name, entity, prs_type): result = (entity == EntityType.CELL or field_name in proxy.QuadraturePointArrays.Available) elif (prs_type == PrsTypeEnum.MESH): - result = len(get_group_names(proxy, field_name, entity)) > 0 + result = len(get_group_names(extrGrps)) > 0 return result @@ -952,40 +981,28 @@ def get_group_entity(full_group_name): def get_group_short_name(full_group_name): """Return short name of the group by its full name.""" - aList = full_group_name.split('/') - if len(aList) >= 4 : - short_name = full_group_name.split('/')[3] - return short_name + short_name = re.sub('^GRP_', '', full_group_name) + return short_name -def get_mesh_names(proxy): +def get_mesh_full_names(proxy): """Return all mesh names in the given proxy as a set.""" - groups = proxy.Groups.Available - mesh_names = set([get_group_mesh_name(item) for item in groups]) - - return mesh_names + proxy.UpdatePipeline() + fields = proxy.GetProperty("FieldsTreeInfo")[::2] + mesh_full_names = set([item for item in fields if get_field_mesh_name(item) == get_field_short_name(item)]) + return mesh_full_names -def get_group_names(proxy, mesh_name, entity, wo_nogroups=False): - """Return full names of all groups of the given entity type - from the mesh with the given name as a list. +def get_group_names(extrGrps): + """Return full names of all groups of the given 'ExtractGroup' filter object. """ - groups = proxy.Groups.Available - - condition = lambda item: (get_group_mesh_name(item) == mesh_name and - get_group_entity(item) == entity) - group_names = [item for item in groups if condition(item)] - - if wo_nogroups: - # Remove "No_Group" group - not_no_group = lambda item: get_group_short_name(item) != "No_Group" - group_names = filter(not_no_group, group_names) - + group_names = filter(lambda x:x[:4]=="GRP_",list(extrGrps.GetProperty("GroupsFlagsInfo")[::2])) return group_names def get_time(proxy, timestamp_nb): """Get time value by timestamp number.""" + proxy.UpdatePipeline() # Check timestamp number timestamps = [] @@ -994,12 +1011,15 @@ def get_time(proxy, timestamp_nb): elif (hasattr(proxy.Input, 'TimestepValues')): timestamps = proxy.Input.TimestepValues.GetData() - if ((timestamp_nb - 1) not in xrange(len(timestamps))): + length = len(timestamps) + if (timestamp_nb > 0 and (timestamp_nb - 1) not in xrange(length) ) or (timestamp_nb < 0 and -timestamp_nb > length): raise ValueError("Timestamp number is out of range: " + str(timestamp_nb)) # Return time value - return timestamps[timestamp_nb - 1] - + if timestamp_nb > 0: + return timestamps[timestamp_nb - 1] + else: + return timestamps[timestamp_nb] def create_prs(prs_type, proxy, field_entity, field_name, timestamp_nb): """Auxiliary function. @@ -1009,6 +1029,7 @@ def create_prs(prs_type, proxy, field_entity, field_name, timestamp_nb): Set the presentation properties like visu.CreatePrsForResult() do. """ + proxy.UpdatePipeline() prs = None if prs_type == PrsTypeEnum.SCALARMAP: @@ -1060,6 +1081,7 @@ def ScalarMapOnField(proxy, entity, field_name, timestamp_nb, Scalar Map as representation object. """ + proxy.UpdatePipeline() # We don't need mesh parts with no data on them if entity == EntityType.NODE: select_cells_with_data(proxy, on_points=[field_name]) @@ -1077,12 +1099,8 @@ def ScalarMapOnField(proxy, entity, field_name, timestamp_nb, pvs.GetRenderView().ViewTime = time_value pvs.UpdatePipeline(time_value, proxy) - # Extract only groups with data for the field - new_proxy = extract_groups_for_field(proxy, field_name, entity, - force=True) - # Get Scalar Map representation object - scalarmap = pvs.GetRepresentation(new_proxy) + scalarmap = pvs.GetRepresentation(proxy) # Get lookup table lookup_table = get_lookup_table(field_name, nb_components, vector_mode) @@ -1134,6 +1152,12 @@ def CutPlanesOnField(proxy, entity, field_name, timestamp_nb, Cut Planes as representation object. """ + proxy.UpdatePipeline() + if entity == EntityType.NODE: + select_cells_with_data(proxy, on_points=[field_name]) + else: + select_cells_with_data(proxy, on_cells=[field_name]) + # Check vector mode nb_components = get_nb_components(proxy, entity, field_name) check_vector_mode(vector_mode, nb_components) @@ -1224,6 +1248,12 @@ def CutLinesOnField(proxy, entity, field_name, timestamp_nb, (Cut Lines as representation object, list of 'PlotOverLine') otherwise """ + proxy.UpdatePipeline() + if entity == EntityType.NODE: + select_cells_with_data(proxy, on_points=[field_name]) + else: + select_cells_with_data(proxy, on_cells=[field_name]) + # Check vector mode nb_components = get_nb_components(proxy, entity, field_name) check_vector_mode(vector_mode, nb_components) @@ -1346,6 +1376,12 @@ def CutSegmentOnField(proxy, entity, field_name, timestamp_nb, Cut Segment as 3D representation object. """ + proxy.UpdatePipeline() + if entity == EntityType.NODE: + select_cells_with_data(proxy, on_points=[field_name]) + else: + select_cells_with_data(proxy, on_cells=[field_name]) + # Check vector mode nb_components = get_nb_components(proxy, entity, field_name) check_vector_mode(vector_mode, nb_components) @@ -1414,6 +1450,12 @@ def VectorsOnField(proxy, entity, field_name, timestamp_nb, Vectors as representation object. """ + proxy.UpdatePipeline() + if entity == EntityType.NODE: + select_cells_with_data(proxy, on_points=[field_name]) + else: + select_cells_with_data(proxy, on_cells=[field_name]) + # Check vector mode nb_components = get_nb_components(proxy, entity, field_name) check_vector_mode(vector_mode, nb_components) @@ -1426,8 +1468,7 @@ def VectorsOnField(proxy, entity, field_name, timestamp_nb, pvs.UpdatePipeline(time_value, proxy) # Extract only groups with data for the field - new_proxy = extract_groups_for_field(proxy, field_name, entity) - source = new_proxy + source = proxy # Cell centers if is_data_on_cells(proxy, field_name): @@ -1470,7 +1511,7 @@ def VectorsOnField(proxy, entity, field_name, timestamp_nb, glyph.SetScaleFactor = scale_factor else: def_scale = get_default_scale(PrsTypeEnum.DEFORMEDSHAPE, - new_proxy, entity, field_name) + proxy, entity, field_name) glyph.SetScaleFactor = def_scale glyph.UpdatePipeline() @@ -1528,6 +1569,7 @@ def DeformedShapeOnField(proxy, entity, field_name, Defromed Shape as representation object. """ + proxy.UpdatePipeline() # We don't need mesh parts with no data on them if entity == EntityType.NODE: select_cells_with_data(proxy, on_points=[field_name]) @@ -1545,11 +1587,8 @@ def DeformedShapeOnField(proxy, entity, field_name, pvs.GetRenderView().ViewTime = time_value pvs.UpdatePipeline(time_value, proxy) - # Extract only groups with data for the field - new_proxy = extract_groups_for_field(proxy, field_name, entity) - # Do merge - source = pvs.MergeBlocks(new_proxy) + source = pvs.MergeBlocks(proxy) # Cell data to point data if is_data_on_cells(proxy, field_name): @@ -1628,6 +1667,7 @@ def DeformedShapeAndScalarMapOnField(proxy, entity, field_name, Defromed Shape And Scalar Map as representation object. """ + proxy.UpdatePipeline() # We don't need mesh parts with no data on them on_points = [] on_cells = [] @@ -1643,10 +1683,12 @@ def DeformedShapeAndScalarMapOnField(proxy, entity, field_name, else: on_cells.append(scalar_field_name) + nb_components = get_nb_components(proxy, entity, field_name) + + # Select fields select_cells_with_data(proxy, on_points, on_cells) # Check vector mode - nb_components = get_nb_components(proxy, entity, field_name) check_vector_mode(vector_mode, nb_components) # Get time value @@ -1663,11 +1705,8 @@ def DeformedShapeAndScalarMapOnField(proxy, entity, field_name, scalar_field_entity = entity scalar_field = field_name - # Extract only groups with data for the field - new_proxy = extract_groups_for_field(proxy, field_name, entity) - # Do merge - source = pvs.MergeBlocks(new_proxy) + source = pvs.MergeBlocks(proxy) # Cell data to point data if is_data_on_cells(proxy, field_name): @@ -1689,7 +1728,7 @@ def DeformedShapeAndScalarMapOnField(proxy, entity, field_name, warp_vector.ScaleFactor = scale_factor else: def_scale = get_default_scale(PrsTypeEnum.DEFORMEDSHAPE, - new_proxy, entity, field_name) + proxy, entity, field_name) warp_vector.ScaleFactor = def_scale # Get Defromed Shape And Scalar Map representation object @@ -1753,6 +1792,7 @@ def Plot3DOnField(proxy, entity, field_name, timestamp_nb, Plot 3D as representation object. """ + proxy.UpdatePipeline() # We don't need mesh parts with no data on them if entity == EntityType.NODE: select_cells_with_data(proxy, on_points=[field_name]) @@ -1770,11 +1810,8 @@ def Plot3DOnField(proxy, entity, field_name, timestamp_nb, pvs.GetRenderView().ViewTime = time_value pvs.UpdatePipeline(time_value, proxy) - # Extract only groups with data for the field - new_proxy = extract_groups_for_field(proxy, field_name, entity) - # Do merge - merge_blocks = pvs.MergeBlocks(new_proxy) + merge_blocks = pvs.MergeBlocks(proxy) merge_blocks.UpdatePipeline() poly_data = None @@ -1913,6 +1950,7 @@ def IsoSurfacesOnField(proxy, entity, field_name, timestamp_nb, Iso Surfaces as representation object. """ + proxy.UpdatePipeline() # We don't need mesh parts with no data on them if entity == EntityType.NODE: select_cells_with_data(proxy, on_points=[field_name]) @@ -1930,11 +1968,8 @@ def IsoSurfacesOnField(proxy, entity, field_name, timestamp_nb, pvs.GetRenderView().ViewTime = time_value pvs.UpdatePipeline(time_value, proxy) - # Extract only groups with data for the field - new_proxy = extract_groups_for_field(proxy, field_name, entity) - # Do merge - source = pvs.MergeBlocks(new_proxy) + source = pvs.MergeBlocks(proxy) # Transform cell data into point data if necessary if is_data_on_cells(proxy, field_name): @@ -2035,11 +2070,14 @@ def GaussPointsOnField(proxy, entity, field_name, Gauss Points as representation object. """ + proxy.UpdatePipeline() # We don't need mesh parts with no data on them - if entity == EntityType.NODE: - select_cells_with_data(proxy, on_points=[field_name]) - else: - select_cells_with_data(proxy, on_cells=[field_name]) + on_gauss = select_cells_with_data(proxy, on_gauss=[field_name]) + if not on_gauss: + if entity == EntityType.NODE: + select_cells_with_data(proxy, on_points=[field_name]) + else: + select_cells_with_data(proxy, on_cells=[field_name]) # Check vector mode nb_components = get_nb_components(proxy, entity, field_name) @@ -2052,16 +2090,12 @@ def GaussPointsOnField(proxy, entity, field_name, pvs.GetRenderView().ViewTime = time_value proxy.UpdatePipeline(time=time_value) - # Extract only groups with data for the field - source = extract_groups_for_field(proxy, field_name, entity) - - # Quadrature point arrays - qp_arrays = proxy.QuadraturePointArrays.Available + source = proxy # If no quadrature point array is passed, use cell centers - if field_name in qp_arrays: + if on_gauss: generate_qp = pvs.GenerateQuadraturePoints(source) - generate_qp.SelectSourceArray = ['CELLS', 'ELGA_Offset'] + generate_qp.QuadratureSchemeDef = ['CELLS', 'ELGA@0'] source = generate_qp else: # Cell centers @@ -2209,6 +2243,11 @@ def GaussPointsOnField1(proxy, entity, field_name, Gauss Points as representation object. """ + proxy.UpdatePipeline() + select_cells_with_data(proxy, on_gauss=[field_name]) + + nb_components = get_nb_components(proxy, entity, field_name) + # Get time value time_value = get_time(proxy, timestamp_nb) @@ -2224,14 +2263,6 @@ def GaussPointsOnField1(proxy, entity, field_name, gausspnt = pvs.GetRepresentation(source) # Get lookup table - entity_data_info = None - point_data_info = source.GetPointDataInformation() - if field_name in point_data_info.keys(): - entity_data_info = point_data_info - else: - entity_data_info = source.GetCellDataInformation() - nb_components = entity_data_info[field_name].GetNumberOfComponents() - lookup_table = get_lookup_table(field_name, nb_components, vector_mode) # Set field range if necessary @@ -2334,6 +2365,7 @@ def StreamLinesOnField(proxy, entity, field_name, timestamp_nb, Stream Lines as representation object. """ + proxy.UpdatePipeline() # We don't need mesh parts with no data on them if entity == EntityType.NODE: select_cells_with_data(proxy, on_points=[field_name]) @@ -2351,11 +2383,8 @@ def StreamLinesOnField(proxy, entity, field_name, timestamp_nb, pvs.GetRenderView().ViewTime = time_value pvs.UpdatePipeline(time_value, proxy) - # Extract only groups with data for the field - new_proxy = extract_groups_for_field(proxy, field_name, entity) - # Do merge - source = pvs.MergeBlocks(new_proxy) + source = pvs.MergeBlocks(proxy) # Cell data to point data if is_data_on_cells(proxy, field_name): @@ -2390,7 +2419,7 @@ def StreamLinesOnField(proxy, entity, field_name, timestamp_nb, lookup_table = get_lookup_table(field_name, nb_components, vector_mode) # Set field range if necessary - data_range = get_data_range(new_proxy, entity, + data_range = get_data_range(proxy, entity, field_name, vector_mode) lookup_table.LockScalarRange = 1 lookup_table.RGBPoints = [data_range[0], 0, 0, 1, data_range[1], 1, 0, 0] @@ -2418,21 +2447,25 @@ def MeshOnEntity(proxy, mesh_name, entity): Arguments: proxy -- the pipeline object, containig data - mesh_name -- the mesh name - entity -- the entity type + mesh_name -- the full or short name of mesh field Returns: Submesh as representation object of the given source. """ - # Select all cell types - select_all_cells(proxy) - - # Get subset of groups on the given entity - subset = get_group_names(proxy, mesh_name, entity) - - # Select only groups of the given entity type - proxy.Groups = subset + proxy.UpdatePipeline() + mesh_full_name = None + aList = mesh_name.split('/') + if len(aList) >= 2: + mesh_full_name = mesh_name + else: + mesh_full_name = find_mesh_full_name(proxy, mesh_name) + if not mesh_full_name: + raise RuntimeError, "The given mesh name was not found" + # Select only the given mesh + proxy.AllArrays = [] + proxy.UpdatePipeline() + proxy.AllArrays = [mesh_full_name] proxy.UpdatePipeline() # Get representation object if the submesh is not empty @@ -2445,42 +2478,42 @@ def MeshOnEntity(proxy, mesh_name, entity): return prs -def MeshOnGroup(proxy, group_name): +def MeshOnGroup(proxy, extrGroups, group_name): """Creates submesh on the group. Arguments: proxy -- the pipeline object, containig data group_name -- the full group name + extrGroups -- all extracted groups object Returns: Representation object of the given source with single group selected. """ - # Select all cell types - select_all_cells(proxy) - - # Select only the group with the given name - one_group = [group_name] - proxy.Groups = one_group proxy.UpdatePipeline() + # Deselect all groups + extrGroups.AllGroups = [] + extrGroups.UpdatePipelineInformation() + # Select only the group with the given name + extrGroups.AllGroups = [group_name] + extrGroups.UpdatePipelineInformation() # Get representation object if the submesh is not empty prs = None # Check if the group was set - if proxy.Groups.GetData() == one_group: - group_entity = get_group_entity(group_name) + if len(extrGroups.AllGroups) == 1 and \ + extrGroups.AllGroups[0] == group_name: # Check if the submesh is not empty - nb_items = 0 - if group_entity == EntityType.NODE: - nb_items = proxy.GetDataInformation().GetNumberOfPoints() - elif group_entity == EntityType.CELL: - nb_items = proxy.GetDataInformation().GetNumberOfCells() - - if nb_items: - prs = pvs.GetRepresentation(proxy) + nb_points = proxy.GetDataInformation().GetNumberOfPoints() + nb_cells = proxy.GetDataInformation().GetNumberOfCells() + + if nb_points or nb_cells: +# prs = pvs.GetRepresentation(proxy) + prs = pvs.Show() prs.ColorArrayName = '' + display_only(prs) return prs @@ -2503,8 +2536,7 @@ def CreatePrsForFile(paravis_instance, file_name, prs_types, print "Import " + file_name.split(os.sep)[-1] + "..." try: - paravis_instance.ImportFile(file_name) - proxy = pvs.GetActiveSource() + proxy = pvs.MEDReader(FileName=file_name) if proxy is None: print "FAILED" else: @@ -2520,7 +2552,6 @@ def CreatePrsForFile(paravis_instance, file_name, prs_types, CreatePrsForProxy(proxy, view, prs_types, picture_dir, picture_ext) - def CreatePrsForProxy(proxy, view, prs_types, picture_dir, picture_ext): """Build presentations of the given types for all fields of the proxy. @@ -2535,10 +2566,9 @@ def CreatePrsForProxy(proxy, view, prs_types, picture_dir, picture_ext): picture_ext: graphics files extension (determines file type) """ + proxy.UpdatePipeline() # List of the field names - field_names = list(proxy.PointArrays.GetData()) - nb_on_nodes = len(field_names) - field_names.extend(proxy.CellArrays.GetData()) + fields_info = proxy.GetProperty("FieldsTreeInfo")[::2] # Add path separator to the end of picture path if necessery if not picture_dir.endswith(os.sep): @@ -2546,77 +2576,60 @@ def CreatePrsForProxy(proxy, view, prs_types, picture_dir, picture_ext): # Mesh Presentation if PrsTypeEnum.MESH in prs_types: - # Create Mesh presentation. Build all possible submeshes. - - # Remember the current state - groups = list(proxy.Groups) - # Iterate on meshes - mesh_names = get_mesh_names(proxy) + mesh_names = get_mesh_full_names(proxy) for mesh_name in mesh_names: - # Build mesh on nodes and cells - for entity in (EntityType.NODE, EntityType.CELL): - entity_name = EntityType.get_name(entity) - if if_possible(proxy, mesh_name, entity, PrsTypeEnum.MESH): - print "Creating submesh on " + entity_name + " for '" + mesh_name + "' mesh... " - prs = MeshOnEntity(proxy, mesh_name, entity) - if prs is None: - print "FAILED" - continue - else: - print "OK" - # Construct image file name - pic_name = picture_dir + mesh_name + "_" + entity_name + "." + picture_ext - - # Show and dump the presentation into a graphics file - process_prs_for_test(prs, view, pic_name, False) - - # Build submesh on all groups of the mesh - mesh_groups = get_group_names(proxy, mesh_name, - entity, wo_nogroups=True) - for group in mesh_groups: - print "Creating submesh on group " + group + "... " - prs = MeshOnGroup(proxy, group) + # Build mesh field presentation + print "Creating submesh for '" + get_field_short_name(mesh_name) + "' mesh... " + prs = MeshOnEntity(proxy, mesh_name, None) + if prs is None: + print "FAILED" + continue + else: + print "OK" + # Construct image file name + pic_name = picture_dir + get_field_short_name(mesh_name) + "." + picture_ext + + # Show and dump the presentation into a graphics file + process_prs_for_test(prs, view, pic_name, False) + + # Create Mesh presentation. Build all groups. + extGrp = pvs.ExtractGroup() + extGrp.UpdatePipelineInformation() + if if_possible(proxy, None, None, PrsTypeEnum.MESH, extGrp): + for group in get_group_names(extGrp): + print "Creating submesh on group " + get_group_short_name(group) + "... " + prs = MeshOnGroup(proxy, extGrp, group) if prs is None: print "FAILED" continue else: print "OK" # Construct image file name - pic_name = picture_dir + group.replace('/', '_') + "." + picture_ext - + pic_name = picture_dir + get_group_short_name(group) + "." + picture_ext + # Show and dump the presentation into a graphics file process_prs_for_test(prs, view, pic_name, False) - # Restore the state - proxy.Groups = groups - proxy.UpdatePipeline() - # Presentations on fields - for (i, field_name) in enumerate(field_names): + for field in fields_info: + field_name = get_field_short_name(field) + # Ignore mesh presentation + if field_name == get_field_mesh_name(field): + continue + field_entity = get_field_entity(field) + # Clear fields selection state + proxy.AllArrays = [] + proxy.UpdatePipeline() # Select only the current field: # necessary for getting the right timestamps - cell_arrays = proxy.CellArrays.GetData() - point_arrays = proxy.PointArrays.GetData() - field_entity = None - if (i >= nb_on_nodes): - field_entity = EntityType.CELL - proxy.PointArrays.DeselectAll() - proxy.CellArrays = [field_name] - else: - field_entity = EntityType.NODE - proxy.CellArrays.DeselectAll() - proxy.PointArrays = [field_name] + proxy.AllArrays = field + proxy.UpdatePipeline() # Get timestamps - proxy.UpdatePipelineInformation() + entity_data_info = proxy.GetCellDataInformation() timestamps = proxy.TimestepValues.GetData() - # Restore fields selection state - proxy.CellArrays = cell_arrays - proxy.PointArrays = point_arrays - proxy.UpdatePipelineInformation() - for prs_type in prs_types: # Ignore mesh presentation if prs_type == PrsTypeEnum.MESH: @@ -2634,6 +2647,12 @@ def CreatePrsForProxy(proxy, view, prs_types, picture_dir, picture_ext): for timestamp_nb in xrange(1, len(timestamps) + 1): time = timestamps[timestamp_nb - 1] + if (time == 0.0): + scalar_range = get_data_range(proxy, field_entity, + field_name, cut_off=True) + # exclude time stamps with null lenght of scalar range + if (scalar_range[0] == scalar_range[1]): + continue print "Creating " + prs_name + " on " + field_name + ", time = " + str(time) + "... " prs = create_prs(prs_type, proxy, field_entity, field_name, timestamp_nb) @@ -2648,3 +2667,4 @@ def CreatePrsForProxy(proxy, view, prs_types, picture_dir, picture_ext): # Show and dump the presentation into a graphics file process_prs_for_test(prs, view, pic_name) + return diff --git a/src/PV_SWIG/pvsimple.py b/src/PV_SWIG/pvsimple.py index 73a8aad1..6b474725 100644 --- a/src/PV_SWIG/pvsimple.py +++ b/src/PV_SWIG/pvsimple.py @@ -17,27 +17,1157 @@ # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # -r""" This module is a direct forward to the initial 'simple' module of ParaView. -On top of that it also establishes a connection to a valid PVServer whose address -is provided by the PARAVIS engine. +r"""simple is a module for using paraview server manager in Python. It +provides a simple convenience layer to functionality provided by the +C++ classes wrapped to Python as well as the servermanager module. + +A simple example: + from paraview.simple import * + + # Create a new sphere proxy on the active connection and register it + # in the sources group. + sphere = Sphere(ThetaResolution=16, PhiResolution=32) + + # Apply a shrink filter + shrink = Shrink(sphere) + + # Turn the visiblity of the shrink object on. + Show(shrink) + + # Render the scene + Render() """ -from paraview.simple import * -import paravis ## Triggers the "FindOrLoadCompo(PARAVIS)" - -def SalomeConnectToPVServer(): - print "Connecting to PVServer ..." - try: - server_url = paravis.StartOrRetrievePVServerURL() - Connect(server_url) - except Exception as e: - print "*******************************************" - print "*******************************************" - print "Could not connect to a running PVServer!" - print "*******************************************" - print "*******************************************" - raise e - print "Connected!" - -# Automatically connect to the right PVServer: -SalomeConnectToPVServer() +import paravisSM + +servermanager = paravisSM + +def enableMultiServer(): + servermanager.enableMultiServer() + +def switchActiveConnection(newActiveConnection=None, ns=None): + if not ns: + ns = globals() + _remove_functions(ns) + servermanager.switchActiveConnection(newActiveConnection) + _add_functions(ns) + +def Disconnect(ns=None, force=True): + if servermanager.ActiveConnection and (force or servermanager.MultiServerConnections == None): + if ns: + _remove_functions(ns) + _remove_functions(globals()) + if not servermanager.fromGUI: + servermanager.ProxyManager().DisableStateUpdateNotification() + servermanager.ProxyManager().UnRegisterProxies() + active_objects.view = None + active_objects.source = None + servermanager.Disconnect() + if not servermanager.fromGUI: + import gc + gc.collect() + +def Connect(ds_host=None, ds_port=11111, rs_host=None, rs_port=11111): + """Creates a connection to a server. Example usage: + > Connect("amber") # Connect to a single server at default port + > Connect("amber", 12345) # Connect to a single server at port 12345 + > Connect("amber", 11111, "vis_cluster", 11111) # connect to data server, render server pair""" + Disconnect(globals(), False) + connection = servermanager.Connect(ds_host, ds_port, rs_host, rs_port) + _add_functions(globals()) + + servermanager.ProxyManager().DisableStateUpdateNotification() + servermanager.ProxyManager().UpdateFromRemote() + tk = servermanager.ProxyManager().GetProxy("timekeeper", "TimeKeeper") + if not tk: + try: + tk = servermanager.misc.TimeKeeper() + servermanager.ProxyManager().RegisterProxy("timekeeper", "TimeKeeper", tk) + except AttributeError: + print "Error: Could not create TimeKeeper" + + scene = servermanager.ProxyManager().GetProxy("animation", "AnimationScene") + if not scene: + try: + scene = AnimationScene() + scene.TimeKeeper = tk + except NameError: + print "Error: Could not create AnimationScene" + + servermanager.ProxyManager().EnableStateUpdateNotification() + servermanager.ProxyManager().TriggerStateUpdate() + + return connection + +def ReverseConnect(port=11111): + """Create a reverse connection to a server. Listens on port and waits for + an incoming connection from the server.""" + Disconnect(globals(), False) + connection = servermanager.ReverseConnect(port) + _add_functions(globals()) + + servermanager.ProxyManager().DisableStateUpdateNotification() + servermanager.ProxyManager().UpdateFromRemote() + tk = servermanager.ProxyManager().GetProxy("timekeeper", "TimeKeeper") + if not tk: + tk = servermanager.misc.TimeKeeper() + servermanager.ProxyManager().RegisterProxy("timekeeper", "TimeKeeper", tk) + + scene = servermanager.ProxyManager().GetProxy("animation", "AnimationScene") + if not scene: + scene = AnimationScene() + scene.TimeKeeper = tk + + servermanager.ProxyManager().EnableStateUpdateNotification() + servermanager.ProxyManager().TriggerStateUpdate() + + return connection + +def _create_view(view_xml_name): + "Creates and returns a 3D render view." + view = servermanager._create_view(view_xml_name) + servermanager.ProxyManager().RegisterProxy("views", \ + "my_view%d" % _funcs_internals.view_counter, view) + active_objects.view = view + _funcs_internals.view_counter += 1 + + tk = servermanager.ProxyManager().GetProxiesInGroup("timekeeper").values()[0] + views = tk.Views + if not view in views: + views.append(view) + try: + scene = GetAnimationScene() + if not view in scene.ViewModules: + scene.ViewModules.append(view) + except servermanager.MissingProxy: + pass + return view + +def CreateRenderView(): + return _create_view("RenderView") + +def CreateXYPlotView(): + return _create_view("XYChartView") + +def CreateBarChartView(): + return _create_view("XYBarChartView") + +def CreateComparativeRenderView(): + return _create_view("ComparativeRenderView") + +def CreateComparativeXYPlotView(): + return _create_view("ComparativeXYPlotView") + +def CreateComparativeBarChartView(): + return _create_view("ComparativeBarChartView") + +def CreateParallelCoordinatesChartView(): + return _create_view("ParallelCoordinatesChartView") + +def Create2DRenderView(): + return _create_view("2DRenderView") + +def OpenDataFile(filename, **extraArgs): + """Creates a reader to read the give file, if possible. + This uses extension matching to determine the best reader possible. + If a reader cannot be identified, then this returns None.""" + session = servermanager.ActiveConnection.Session + reader_factor = servermanager.vtkSMProxyManager.GetProxyManager().GetReaderFactory() + if reader_factor.GetNumberOfRegisteredPrototypes() == 0: + reader_factor.RegisterPrototypes(session, "sources") + first_file = filename + if type(filename) == list: + first_file = filename[0] + if not reader_factor.TestFileReadability(first_file, session): + msg = "File not readable: %s " % first_file + raise RuntimeError, msg + if not reader_factor.CanReadFile(first_file, session): + msg = "File not readable. No reader found for '%s' " % first_file + raise RuntimeError, msg + prototype = servermanager.ProxyManager().GetPrototypeProxy( + reader_factor.GetReaderGroup(), reader_factor.GetReaderName()) + # [ABN]: bug fix for Christian VW (temporary - pvsimple should disappear soon) + from paraview import make_name_valid # make_name_valid is not in paravisSM + xml_name = make_name_valid(prototype.GetXMLLabel()) + reader_func = _create_func(xml_name, servermanager.sources) + if prototype.GetProperty("FileNames"): + reader = reader_func(FileNames=filename, **extraArgs) + else : + reader = reader_func(FileName=filename, **extraArgs) + return reader + +def CreateWriter(filename, proxy=None, **extraArgs): + """Creates a writer that can write the data produced by the source proxy in + the given file format (identified by the extension). If no source is + provided, then the active source is used. This doesn't actually write the + data, it simply creates the writer and returns it.""" + if not filename: + raise RuntimeError, "filename must be specified" + session = servermanager.ActiveConnection.Session + writer_factory = servermanager.vtkSMProxyManager.GetProxyManager().GetWriterFactory() + if writer_factory.GetNumberOfRegisteredPrototypes() == 0: + writer_factory.RegisterPrototypes(session, "writers") + if not proxy: + proxy = GetActiveSource() + if not proxy: + raise RuntimeError, "Could not locate source to write" + writer_proxy = writer_factory.CreateWriter(filename, proxy.SMProxy, proxy.Port) + return servermanager._getPyProxy(writer_proxy) + +def GetRenderView(): + """Returns the active view if there is one. Else creates and returns a new view.""" + view = active_objects.view + if not view: + # it's possible that there's no active view, but a render view exists. + # If so, locate that and return it (before trying to create a new one). + view = servermanager.GetRenderView() + if not view: + view = CreateRenderView() + return view + +def GetRenderViews(): + """Returns all render views as a list.""" + return servermanager.GetRenderViews() + +def GetRepresentation(proxy=None, view=None): + """Given a pipeline object and view, returns the corresponding representation object. + If pipeline object and view are not specified, active objects are used.""" + if not view: + view = active_objects.view + if not proxy: + proxy = active_objects.source + rep = servermanager.GetRepresentation(proxy, view) + if not rep: + rep = servermanager.CreateRepresentation(proxy, view) + servermanager.ProxyManager().RegisterProxy("representations", \ + "my_representation%d" % _funcs_internals.rep_counter, rep) + _funcs_internals.rep_counter += 1 + return rep + +def GetDisplayProperties(proxy=None, view=None): + """Given a pipeline object and view, returns the corresponding representation object. + If pipeline object and/or view are not specified, active objects are used.""" + return GetRepresentation(proxy, view) + +def Show(proxy=None, view=None, **params): + """Turns the visibility of a given pipeline object on in the given view. + If pipeline object and/or view are not specified, active objects are used.""" + if proxy == None: + proxy = GetActiveSource() + if proxy == None: + raise RuntimeError, "Show() needs a proxy argument or that an active source is set." + if not view and not active_objects.view: + CreateRenderView() + rep = GetDisplayProperties(proxy, view) + if rep == None: + raise RuntimeError, "Could not create a representation object for proxy %s" % proxy.GetXMLLabel() + for param in params.keys(): + setattr(rep, param, params[param]) + rep.Visibility = 1 + return rep + +def Hide(proxy=None, view=None): + """Turns the visibility of a given pipeline object off in the given view. + If pipeline object and/or view are not specified, active objects are used.""" + rep = GetDisplayProperties(proxy, view) + rep.Visibility = 0 + +def Render(view=None): + """Renders the given view (default value is active view)""" + if not view: + view = active_objects.view + view.StillRender() + if _funcs_internals.first_render: + # Not all views have a ResetCamera method + try: + view.ResetCamera() + view.StillRender() + except AttributeError: pass + _funcs_internals.first_render = False + return view + +def ResetCamera(view=None): + """Resets the settings of the camera to preserver orientation but include + the whole scene. If an argument is not provided, the active view is + used.""" + if not view: + view = active_objects.view + if hasattr(view, "ResetCamera"): + view.ResetCamera() + if hasattr(view, "ResetDisplay"): + view.ResetDisplay() + Render(view) + +def _DisableFirstRenderCameraReset(): + """Disable the first render camera reset. Normally a ResetCamera is called + automatically when Render is called for the first time after importing + this module.""" + _funcs_internals.first_render = False + +def SetProperties(proxy=None, **params): + """Sets one or more properties of the given pipeline object. If an argument + is not provided, the active source is used. Pass a list of property_name=value + pairs to this function to set property values. For example: + SetProperties(Center=[1, 2, 3], Radius=3.5) + """ + if not proxy: + proxy = active_objects.source + for param in params.keys(): + if not hasattr(proxy, param): + raise AttributeError("object has no property %s" % param) + setattr(proxy, param, params[param]) + +def GetProperty(*arguments, **keywords): + """Get one property of the given pipeline object. If keywords are used, + you can set the proxy and the name of the property that you want to get + like in the following example : + GetProperty({proxy=sphere, name="Radius"}) + If it's arguments that are used, then you have two case: + - if only one argument is used that argument will be + the property name. + - if two arguments are used then the first one will be + the proxy and the second one the property name. + Several example are given below: + GetProperty({name="Radius"}) + GetProperty({proxy=sphereProxy, name="Radius"}) + GetProperty( sphereProxy, "Radius" ) + GetProperty( "Radius" ) + """ + name = None + proxy = None + for key in keywords: + if key == "name": + name = keywords[key] + if key == "proxy": + proxy = keywords[key] + if len(arguments) == 1 : + name = arguments[0] + if len(arguments) == 2 : + proxy = arguments[0] + name = arguments[1] + if not name: + raise RuntimeError, "Expecting at least a property name as input. Otherwise keyword could be used to set 'proxy' and property 'name'" + if not proxy: + proxy = active_objects.source + return proxy.GetProperty(name) + +def SetDisplayProperties(proxy=None, view=None, **params): + """Sets one or more display properties of the given pipeline object. If an argument + is not provided, the active source is used. Pass a list of property_name=value + pairs to this function to set property values. For example: + SetProperties(Color=[1, 0, 0], LineWidth=2) + """ + rep = GetDisplayProperties(proxy, view) + SetProperties(rep, **params) + +def SetViewProperties(view=None, **params): + """Sets one or more properties of the given view. If an argument + is not provided, the active view is used. Pass a list of property_name=value + pairs to this function to set property values. For example: + SetProperties(Background=[1, 0, 0], UseImmediateMode=0) + """ + if not view: + view = active_objects.view + SetProperties(view, **params) + +def RenameSource(newName, proxy=None): + """Renames the given source. If the given proxy is not registered + in the sources group this method will have no effect. If no source is + provided, the active source is used.""" + if not proxy: + proxy = active_objects.source + pxm = servermanager.ProxyManager() + oldName = pxm.GetProxyName("sources", proxy) + if oldName: + pxm.RegisterProxy("sources", newName, proxy) + pxm.UnRegisterProxy("sources", oldName, proxy) + +def FindSource(name): + return servermanager.ProxyManager().GetProxy("sources", name) + +def GetSources(): + """Given the name of a source, return its Python object.""" + return servermanager.ProxyManager().GetProxiesInGroup("sources") + +def GetRepresentations(): + """Returns all representations (display properties).""" + return servermanager.ProxyManager().GetProxiesInGroup("representations") + +def UpdatePipeline(time=None, proxy=None): + """Updates (executes) the given pipeline object for the given time as + necessary (i.e. if it did not already execute). If no source is provided, + the active source is used instead.""" + if not proxy: + proxy = active_objects.source + if time: + proxy.UpdatePipeline(time) + else: + proxy.UpdatePipeline() + +def Delete(proxy=None): + """Deletes the given pipeline object or the active source if no argument + is specified.""" + if not proxy: + proxy = active_objects.source + # Unregister any helper proxies stored by a vtkSMProxyListDomain + for prop in proxy: + listdomain = prop.GetDomain('proxy_list') + if listdomain: + if listdomain.GetClassName() != 'vtkSMProxyListDomain': + continue + group = "pq_helper_proxies." + proxy.GetGlobalIDAsString() + for i in xrange(listdomain.GetNumberOfProxies()): + pm = servermanager.ProxyManager() + iproxy = listdomain.GetProxy(i) + name = pm.GetProxyName(group, iproxy) + if iproxy and name: + pm.UnRegisterProxy(group, name, iproxy) + + # Remove source/view from time keeper + tk = servermanager.ProxyManager().GetProxiesInGroup("timekeeper").values()[0] + if isinstance(proxy, servermanager.SourceProxy): + try: + idx = tk.TimeSources.index(proxy) + del tk.TimeSources[idx] + except ValueError: + pass + else: + try: + idx = tk.Views.index(proxy) + del tk.Views[idx] + except ValueError: + pass + servermanager.UnRegister(proxy) + + # If this is a representation, remove it from all views. + if proxy.SMProxy.IsA("vtkSMRepresentationProxy") or \ + proxy.SMProxy.IsA("vtkSMNewWidgetRepresentationProxy"): + for view in GetRenderViews(): + view.Representations.remove(proxy) + # If this is a source, remove the representation iff it has no consumers + # Also change the active source if necessary + elif proxy.SMProxy.IsA("vtkSMSourceProxy"): + sources = servermanager.ProxyManager().GetProxiesInGroup("sources") + for i in range(proxy.GetNumberOfConsumers()): + if proxy.GetConsumerProxy(i) in sources: + raise RuntimeError("Source has consumers. It cannot be deleted " + + "until all consumers are deleted.") + #VSV:== + if proxy.IsSame(GetActiveSource()): + if hasattr(proxy, "Input") and proxy.Input: + if isinstance(proxy.Input, servermanager.Proxy): + SetActiveSource(proxy.Input) + else: + SetActiveSource(proxy.Input[0]) + else: SetActiveSource(None) + for rep in GetRepresentations().values(): + #VSV:== + if rep.Input.IsSame(proxy): + Delete(rep) + # Change the active view if necessary + elif proxy.SMProxy.IsA("vtkSMRenderViewProxy"): + ##VSV:== + if proxy.IsSame(GetActiveView()): + if len(GetRenderViews()) > 0: + SetActiveView(GetRenderViews()[0]) + else: + SetActiveView(None) + +def CreateLookupTable(**params): + """Create and return a lookup table. Optionally, parameters can be given + to assign to the lookup table. + """ + lt = servermanager.rendering.PVLookupTable() + servermanager.Register(lt) + SetProperties(lt, **params) + return lt + +def CreatePiecewiseFunction(**params): + """Create and return a piecewise function. Optionally, parameters can be + given to assign to the piecewise function. + """ + pfunc = servermanager.piecewise_functions.PiecewiseFunction() + servermanager.Register(pfunc) + SetProperties(pfunc, **params) + return pfunc + +def GetLookupTableForArray(arrayname, num_components, **params): + """Used to get an existing lookuptable for a array or to create one if none + exists. Keyword arguments can be passed in to initialize the LUT if a new + one is created.""" + proxyName = "%d.%s.PVLookupTable" % (int(num_components), arrayname) + lut = servermanager.ProxyManager().GetProxy("lookup_tables", proxyName) + if lut: + return lut + # No LUT exists for this array, create a new one. + # TODO: Change this to go a LookupTableManager that is shared with the GUI, + # so that the GUI and python end up create same type of LUTs. For now, + # python will create a Blue-Red LUT, unless overridden by params. + lut = servermanager.rendering.PVLookupTable( + ColorSpace="HSV", RGBPoints=[0, 0, 0, 1, 1, 1, 0, 0]) + SetProperties(lut, **params) + servermanager.Register(lut, registrationName=proxyName) + return lut + +def CreateScalarBar(**params): + """Create and return a scalar bar widget. The returned widget may + be added to a render view by appending it to the view's representations + The widget must have a valid lookup table before it is added to a view. + It is possible to pass the lookup table (and other properties) as arguments + to this method: + + lt = MakeBlueToRedLt(3.5, 7.5) + bar = CreateScalarBar(LookupTable=lt, Title="Velocity") + GetRenderView().Representations.append(bar) + + By default the returned widget is selectable and resizable. + """ + sb = servermanager.rendering.ScalarBarWidgetRepresentation() + servermanager.Register(sb) + sb.Selectable = 1 + sb.Resizable = 1 + sb.Enabled = 1 + sb.Title = "Scalars" + SetProperties(sb, **params) + return sb + +# TODO: Change this to take the array name and number of components. Register +# the lt under the name ncomp.array_name +def MakeBlueToRedLT(min, max): + # Define RGB points. These are tuples of 4 values. First one is + # the scalar values, the other 3 the RGB values. + rgbPoints = [min, 0, 0, 1, max, 1, 0, 0] + return CreateLookupTable(RGBPoints=rgbPoints, ColorSpace="HSV") + +def _find_writer(filename): + """Internal function.""" + extension = None + parts = filename.split('.') + if len(parts) > 1: + extension = parts[-1] + else: + raise RuntimeError, "Filename has no extension, please specify a write" + + if extension == 'png': + return 'vtkPNGWriter' + elif extension == 'bmp': + return 'vtkBMPWriter' + elif extension == 'ppm': + return 'vtkPNMWriter' + elif extension == 'tif' or extension == 'tiff': + return 'vtkTIFFWriter' + elif extension == 'jpg' or extension == 'jpeg': + return 'vtkJPEGWriter' + else: + raise RuntimeError, "Cannot infer filetype from extension:", extension + +def AddCameraLink(viewProxy, viewProxyOther, linkName): + """Create a camera link between two view proxies. A name must be given + so that the link can be referred to by name. If a link with the given + name already exists it will be removed first.""" + if not viewProxyOther: viewProxyOther = GetActiveView() + link = servermanager.vtkSMCameraLink() + link.AddLinkedProxy(viewProxy.SMProxy, 1) + link.AddLinkedProxy(viewProxyOther.SMProxy, 2) + link.AddLinkedProxy(viewProxyOther.SMProxy, 1) + link.AddLinkedProxy(viewProxy.SMProxy, 2) + RemoveCameraLink(linkName) + servermanager.ProxyManager().RegisterLink(linkName, link) + +def RemoveCameraLink(linkName): + """Remove a camera link with the given name.""" + servermanager.ProxyManager().UnRegisterLink(linkName) + +def WriteImage(filename, view=None, **params): + """Saves the given view (or the active one if none is given) as an + image. Optionally, you can specify the writer and the magnification + using the Writer and Magnification named arguments. For example: + WriteImage("foo.mypng", aview, Writer=vtkPNGWriter, Magnification=2) + If no writer is provided, the type is determined from the file extension. + Currently supported extensions are png, bmp, ppm, tif, tiff, jpg and jpeg. + The writer is a VTK class that is capable of writing images. + Magnification is used to determine the size of the written image. The size + is obtained by multiplying the size of the view with the magnification. + Rendering may be done using tiling to obtain the correct size without + resizing the view.""" + if not view: + view = active_objects.view + writer = None + if params.has_key('Writer'): + writer = params['Writer'] + mag = 1 + if params.has_key('Magnification'): + mag = int(params['Magnification']) + if not writer: + writer = _find_writer(filename) + view.WriteImage(filename, writer, mag) + +def AnimateReader(reader=None, view=None, filename=None): + """This is a utility function that, given a reader and a view + animates over all time steps of the reader. If the optional + filename is provided, a movie is created (type depends on the + extension of the filename.""" + if not reader: + reader = active_objects.source + if not view: + view = active_objects.view + + return servermanager.AnimateReader(reader, view, filename) + + +def _create_func(key, module): + """Internal function.""" + + def CreateObject(*input, **params): + """This function creates a new proxy. For pipeline objects that accept inputs, + all non-keyword arguments are assumed to be inputs. All keyword arguments are + assumed to be property,value pairs and are passed to the new proxy.""" + + # Instantiate the actual object from the given module. + px = module.__dict__[key]() + + # Make sure non-keyword arguments are valid + for inp in input: + if inp != None and not isinstance(inp, servermanager.Proxy): + if px.GetProperty("Input") != None: + raise RuntimeError, "Expecting a proxy as input." + else: + raise RuntimeError, "This function does not accept non-keyword arguments." + + # Assign inputs + if px.GetProperty("Input") != None: + if len(input) > 0: + px.Input = input + else: + # If no input is specified, try the active pipeline object + if px.GetProperty("Input").GetRepeatable() and active_objects.get_selected_sources(): + px.Input = active_objects.get_selected_sources() + elif active_objects.source: + px.Input = active_objects.source + else: + if len(input) > 0: + raise RuntimeError, "This function does not expect an input." + + registrationName = None + for nameParam in ['registrationName', 'guiName']: + if nameParam in params: + registrationName = params[nameParam] + del params[nameParam] + + # Pass all the named arguments as property,value pairs + for param in params.keys(): + setattr(px, param, params[param]) + + try: + # Register the proxy with the proxy manager. + if registrationName: + group, name = servermanager.Register(px, registrationName=registrationName) + else: + group, name = servermanager.Register(px) + + + # Register pipeline objects with the time keeper. This is used to extract time values + # from sources. NOTE: This should really be in the servermanager controller layer. + if group == "sources": + has_tk = True + try: + tk = servermanager.ProxyManager().GetProxiesInGroup("timekeeper").values()[0] + except IndexError: + has_tk = False + if has_tk: + sources = tk.TimeSources + if not px in sources: + sources.append(px) + + active_objects.source = px + except servermanager.MissingRegistrationInformation: + pass + + return px + + return CreateObject + +def _create_doc(new, old): + """Internal function.""" + import string + res = "" + for doc in (new, old): + ts = [] + strpd = doc.split('\n') + for s in strpd: + ts.append(s.lstrip()) + res += string.join(ts) + res += '\n' + return res + +def _func_name_valid(name): + """Internal function.""" + valid = True + for c in name: + if c == '(' or c ==')': + valid = False + break + return valid + +def _add_functions(g): + activeModule = servermanager.ActiveConnection.Modules + for m in [activeModule.filters, activeModule.sources, + activeModule.writers, activeModule.animation]: + dt = m.__dict__ + for key in dt.keys(): + cl = dt[key] + if not isinstance(cl, str): + if not key in g and _func_name_valid(key): + g[key] = _create_func(key, m) + exec "g[key].__doc__ = _create_doc(m.%s.__doc__, g[key].__doc__)" % key + +def _remove_functions(g): + list = [] + if servermanager.ActiveConnection: + list = [m for m in dir(servermanager.ActiveConnection.Modules) if m[0] != '_'] + + for m in list: + dt = servermanager.ActiveConnection.Modules.__dict__[m].__dict__ + for key in dt.keys(): + cl = dt[key] + if not isinstance(cl, str) and g.has_key(key): + g.pop(key) + #print "remove %s function" % key + +def GetActiveView(): + """Returns the active view.""" + return active_objects.view + +def SetActiveView(view): + """Sets the active view.""" + active_objects.view = view + +def GetActiveSource(): + """Returns the active source.""" + return active_objects.source + +def SetActiveSource(source): + """Sets the active source.""" + active_objects.source = source + +def GetActiveCamera(): + """Returns the active camera for the active view. The returned object + is an instance of vtkCamera.""" + return GetActiveView().GetActiveCamera() + +def GetAnimationScene(): + """Returns the application-wide animation scene. ParaView has only one + global animation scene. This method provides access to that. Users are + free to create additional animation scenes directly, but those scenes + won't be shown in the ParaView GUI.""" + animation_proxies = servermanager.ProxyManager().GetProxiesInGroup("animation") + scene = None + for aProxy in animation_proxies.values(): + if aProxy.GetXMLName() == "AnimationScene": + scene = aProxy + break + if not scene: + raise servermanager.MissingProxy, "Could not locate global AnimationScene." + return scene + +def WriteAnimation(filename, **params): + """Writes the current animation as a file. Optionally one can specify + arguments that qualify the saved animation files as keyword arguments. + Accepted options are as follows: + * Magnification (integer) : set the maginification factor for the saved + animation. + * Quality (0 [worst] or 1 or 2 [best]) : set the quality of the generated + movie (if applicable). + * Subsampling (integer) : setting whether the movie encoder should use + subsampling of the chrome planes or not, if applicable. Since the human + eye is more sensitive to brightness than color variations, subsampling + can be useful to reduce the bitrate. Default value is 0. + * BackgroundColor (3-tuple of doubles) : set the RGB background color to + use to fill empty spaces in the image. + * FrameRate (double): set the frame rate (if applicable).""" + scene = GetAnimationScene() + # ensures that the TimeKeeper track is created. + GetTimeTrack() + iw = servermanager.vtkSMAnimationSceneImageWriter() + iw.SetAnimationScene(scene.SMProxy) + iw.SetFileName(filename) + if params.has_key("Magnification"): + iw.SetMagnification(int(params["Magnification"])) + if params.has_key("Quality"): + iw.SetQuality(int(params["Quality"])) + if params.has_key("Subsampling"): + iw.SetSubsampling(int(params["Subsampling"])) + if params.has_key("BackgroundColor"): + iw.SetBackgroundColor(params["BackgroundColor"]) + if params.has_key("FrameRate"): + iw.SetFrameRate(float(params["FrameRate"])) + iw.Save() + +def _GetRepresentationAnimationHelper(sourceproxy): + """Internal method that returns the representation animation helper for a + source proxy. It creates a new one if none exists.""" + # ascertain that proxy is a source proxy + if not sourceproxy in GetSources().values(): + return None + for proxy in servermanager.ProxyManager(): + if proxy.GetXMLName() == "RepresentationAnimationHelper" and\ + proxy.GetProperty("Source").IsProxyAdded(sourceproxy.SMProxy): + return proxy + # create a new helper + proxy = servermanager.misc.RepresentationAnimationHelper( + Source=sourceproxy) + servermanager.ProxyManager().RegisterProxy( + "pq_helper_proxies.%s" % sourceproxy.GetGlobalIDAsString(), + "RepresentationAnimationHelper", proxy) + return proxy + +def GetAnimationTrack(propertyname_or_property, index=None, proxy=None): + """Returns an animation cue for the property. If one doesn't exist then a + new one will be created. + Typical usage: + track = GetAnimationTrack("Center", 0, sphere) or + track = GetAnimationTrack(sphere.GetProperty("Radius")) or + + # this returns the track to animate visibility of the active source in + # all views. + track = GetAnimationTrack("Visibility") + + For animating properties on implicit planes etc., use the following + signatures: + track = GetAnimationTrack(slice.SliceType.GetProperty("Origin"), 0) or + track = GetAnimationTrack("Origin", 0, slice.SliceType) + + """ + if not proxy: + proxy = GetActiveSource() + if not isinstance(proxy, servermanager.Proxy): + raise TypeError, "proxy must be a servermanager.Proxy instance" + if isinstance(propertyname_or_property, str): + propertyname = propertyname_or_property + elif isinstance(propertyname_or_property, servermanager.Property): + prop = propertyname_or_property + propertyname = prop.Name + proxy = prop.Proxy + else: + raise TypeError, "propertyname_or_property must be a string or servermanager.Property" + + # To handle the case where the property is actually a "display" property, in + # which case we are actually animating the "RepresentationAnimationHelper" + # associated with the source. + if propertyname in ["Visibility", "Opacity"]: + proxy = _GetRepresentationAnimationHelper(proxy) + if not proxy or not proxy.GetProperty(propertyname): + raise AttributeError, "Failed to locate property %s" % propertyname + + scene = GetAnimationScene() + for cue in scene.Cues: + try: + if cue.AnimatedProxy.IsSame(proxy) and\ + cue.AnimatedPropertyName == propertyname: + if index == None or index.IsSame(cue.AnimatedElement): ##index == cue.AnimatedElement: + return cue + except AttributeError: + pass + + # matching animation track wasn't found, create a new one. + cue = KeyFrameAnimationCue() + cue.AnimatedProxy = proxy + cue.AnimatedPropertyName = propertyname + if index != None: + cue.AnimatedElement = index + scene.Cues.append(cue) + return cue + +def GetCameraTrack(view=None): + """Returns the camera animation track for the given view. If no view is + specified, active view will be used. If no exisiting camera animation track + is found, a new one will be created.""" + if not view: + view = GetActiveView() + if not view: + raise ValueError, "No view specified" + scene = GetAnimationScene() + for cue in scene.Cues: + if cue.AnimatedProxy.IsSame(view) and\ + cue.GetXMLName() == "CameraAnimationCue": + return cue + # no cue was found, create a new one. + cue = CameraAnimationCue() + cue.AnimatedProxy = view + scene.Cues.append(cue) + return cue + +def GetTimeTrack(): + """Returns the animation track used to control the time requested from all + readers/filters during playback. + This is the "TimeKeeper - Time" track shown in ParaView's 'Animation View'. + If none exists, a new one will be created.""" + scene = GetAnimationScene() + tk = scene.TimeKeeper + for cue in scene.Cues: + if cue.GetXMLName() == "TimeAnimationCue" and cue.AnimatedProxy.IsSame(tk)\ + and cue.AnimatedPropertyName == "Time": + return cue + # no cue was found, create a new one. + cue = TimeAnimationCue() + cue.AnimatedProxy = tk + cue.AnimatedPropertyName = "Time" + scene.Cues.append(cue) + return cue + +def LoadXML(xmlstring, ns=None): + """Given a server manager XML as a string, parse and process it. + If you loaded the simple module with from paraview.simple import *, + make sure to pass globals() as the second arguments: + LoadXML(xmlstring, globals()) + Otherwise, the new functions will not appear in the global namespace.""" + if not ns: + ns = globals() + servermanager.LoadXML(xmlstring) + _add_functions(ns) + +def LoadPlugin(filename, remote=True, ns=None): + """Loads a ParaView plugin and updates this module with new constructors + if any. The remote argument (default to True) is to specify whether + the plugin will be loaded on client (remote=False) or on server (remote=True). + If you loaded the simple module with from paraview.simple import *, + make sure to pass globals() as an argument: + LoadPlugin("myplugin", False, globals()), to load on client; + LoadPlugin("myplugin", True, globals()), to load on server; + LoadPlugin("myplugin", ns=globals()), to load on server. + Otherwise, the new functions will not appear in the global namespace.""" + + if not ns: + ns = globals() + servermanager.LoadPlugin(filename, remote) + _add_functions(ns) + +def LoadDistributedPlugin(pluginname, remote=True, ns=None): + """Loads a plugin that's distributed with the executable. This uses the + information known about plugins distributed with ParaView to locate the + shared library for the plugin to load. Raises a RuntimeError if the plugin + was not found.""" + if not servermanager.ActiveConnection: + raise RuntimeError, "Cannot load a plugin without a session." + plm = servermanager.vtkSMProxyManager.GetProxyManager().GetPluginManager() + if remote: + session = servermanager.ActiveConnection.Session + info = plm.GetRemoteInformation(session) + else: + info = plm.GetLocalInformation() + for cc in range(0, info.GetNumberOfPlugins()): + if info.GetPluginName(cc) == pluginname: + return LoadPlugin(info.GetPluginFileName(cc), remote, ns) + raise RuntimeError, "Plugin '%s' not found" % pluginname + +def GetLayouts(): + """Returns the layout proxies on the active session. + Layout proxies are used to place views in a grid.""" + return servermanager.ProxyManager().GetProxiesInGroup("layouts") + +def GetLayout(view=None): + """Return the layout containing the give view, if any. + If no view is specified, active view is used. + """ + if not view: + view = GetActiveView() + if not view: + raise RuntimeError, "No active view was found." + layouts = GetLayouts() + for layout in layouts.values(): + if layout.GetViewLocation(view) != -1: + return layout + return None + + +def SelectCells(query=None, proxy=None): + """Select cells satisfying the query. If query is None, then all cells are + selected. If proxy is None, then the active source is used.""" + if not proxy: + proxy = GetActiveSource() + if not proxy: + raise RuntimeError, "No active source was found." + + if not query: + # This ends up being true for all cells. + query = "id >= 0" + + # Note, selSource is not registered with the proxy manager. + selSource = servermanager.sources.SelectionQuerySource() + selSource.FieldType = "CELL" + selSource.QueryString = str(query) + proxy.SMProxy.SetSelectionInput(proxy.Port, selSource.SMProxy, 0) + return selSource + +def ClearSelection(proxy=None): + """Clears the selection on the active source.""" + if not proxy: + proxy = GetActiveSource() + if not proxy: + raise RuntimeError, "No active source was found." + proxy.SMProxy.SetSelectionInput(proxy.Port, None, 0) + +class ActiveObjects(object): + """This class manages the active objects (source and view). The active + objects are shared between Python and the user interface. This class + is for internal use. Use the Set/Get methods for setting and getting + active objects.""" + def __get_selection_model(self, name, session=None): + "Internal method." + if session and not servermanager.ActiveConnection.Session.IsSame(session): + raise RuntimeError, "Try to set an active object with invalid active connection." + pxm = servermanager.ProxyManager(session) + model = pxm.GetSelectionModel(name) + if not model: + model = servermanager.vtkSMProxySelectionModel() + pxm.RegisterSelectionModel(name, model) + return model + + def set_view(self, view): + "Sets the active view." + active_view_model = self.__get_selection_model("ActiveView") + if view: + active_view_model = self.__get_selection_model("ActiveView", view.GetSession()) + active_view_model.SetCurrentProxy(view.SMProxy, 0) + else: + active_view_model = self.__get_selection_model("ActiveView") + active_view_model.SetCurrentProxy(None, 0) + + def get_view(self): + "Returns the active view." + return servermanager._getPyProxy( + self.__get_selection_model("ActiveView").GetCurrentProxy()) + + def set_source(self, source): + "Sets the active source." + active_sources_model = self.__get_selection_model("ActiveSources") + if source: + # 3 == CLEAR_AND_SELECT + active_sources_model = self.__get_selection_model("ActiveSources", source.GetSession()) + active_sources_model.SetCurrentProxy(source.SMProxy, 3) + else: + active_sources_model = self.__get_selection_model("ActiveSources") + active_sources_model.SetCurrentProxy(None, 3) + + def __convert_proxy(self, px): + "Internal method." + if not px: + return None + if px.IsA("vtkSMSourceProxy"): + return servermanager._getPyProxy(px) + else: + return servermanager.OutputPort( + servermanager._getPyProxy(px.GetSourceProxy()), + px.GetPortIndex()) + + def get_source(self): + "Returns the active source." + return self.__convert_proxy( + self.__get_selection_model("ActiveSources").GetCurrentProxy()) + + def get_selected_sources(self): + "Returns the set of sources selected in the pipeline browser." + model = self.__get_selection_model("ActiveSources") + proxies = [] + for i in xrange(model.GetNumberOfSelectedProxies()): + proxies.append(self.__convert_proxy(model.GetSelectedProxy(i))) + return proxies + + view = property(get_view, set_view) + source = property(get_source, set_source) + +class _funcs_internals: + """Internal class.""" + first_render = True + view_counter = 0 + rep_counter = 0 + +def demo1(): + """Simple demo that create the following pipeline + sphere - shrink - \ + - append + cone - / + """ + # Create a sphere of radius = 2, theta res. = 32 + # This object becomes the active source. + ss = Sphere(Radius=2, ThetaResolution=32) + # Apply the shrink filter. The Input property is optional. If Input + # is not specified, the filter is applied to the active source. + shr = Shrink(Input=ss) + # Create a cone source. + cs = Cone() + # Append cone and shrink + app = AppendDatasets() + app.Input = [shr, cs] + # Show the output of the append filter. The argument is optional + # as the app filter is now the active object. + Show(app) + # Render the default view. + Render() + +def demo2(fname="/Users/berk/Work/ParaView/ParaViewData/Data/disk_out_ref.ex2"): + """This demo shows the use of readers, data information and display + properties.""" + + # Create the exodus reader and specify a file name + reader = ExodusIIReader(FileName=fname) + # Get the list of point arrays. + avail = reader.PointVariables.Available + print avail + # Select all arrays + reader.PointVariables = avail + + # Turn on the visibility of the reader + Show(reader) + # Set representation to wireframe + SetDisplayProperties(Representation = "Wireframe") + # Black background is not pretty + SetViewProperties(Background = [0.4, 0.4, 0.6]) + Render() + # Change the elevation of the camera. See VTK documentation of vtkCamera + # for camera parameters. + # NOTE: THIS WILL BE SIMPLER + GetActiveCamera().Elevation(45) + Render() + # Now that the reader executed, let's get some information about it's + # output. + pdi = reader[0].PointData + # This prints a list of all read point data arrays as well as their + # value ranges. + print 'Number of point arrays:', len(pdi) + for i in range(len(pdi)): + ai = pdi[i] + print "----------------" + print "Array:", i, " ", ai.Name, ":" + numComps = ai.GetNumberOfComponents() + print "Number of components:", numComps + for j in range(numComps): + print "Range:", ai.GetRange(j) + # White is boring. Let's color the geometry using a variable. + # First create a lookup table. This object controls how scalar + # values are mapped to colors. See VTK documentation for + # details. + # Map min (0.00678) to blue, max (0.0288) to red + SetDisplayProperties(LookupTable = MakeBlueToRedLT(0.00678, 0.0288)) + # Color by point array called Pres + SetDisplayProperties(ColorAttributeType = "POINT_DATA") + SetDisplayProperties(ColorArrayName = "Pres") + Render() + +def PrintTrace(): + print paravisSM.myParavis.GetTrace() + +def SaveTrace(fileName): + paravisSM.myParavis.SaveTrace(fileName) + + +if not servermanager.ActiveConnection: + Connect() +else: + _add_functions(globals()) + +def ImportFile(theFileName): + paravisSM.ImportFile(theFileName) + +active_objects = ActiveObjects() +active_objects.view = GetRenderView() diff --git a/src/PV_SWIG/VTKWrapping/servermanager.diff b/src/PV_SWIG/servermanager.diff similarity index 100% rename from src/PV_SWIG/VTKWrapping/servermanager.diff rename to src/PV_SWIG/servermanager.diff diff --git a/src/PV_SWIG/VTKWrapping/simple.diff b/src/PV_SWIG/simple.diff similarity index 100% rename from src/PV_SWIG/VTKWrapping/simple.diff rename to src/PV_SWIG/simple.diff -- 2.39.2