mirror of
https://github.com/OpenFOAM/ThirdParty-6.git
synced 2025-12-08 06:57:43 +00:00
ParaView-5.0.1: Added the source-tree to ThirdParty-dev and patched as described in the README file
Resolves bug-report http://bugs.openfoam.org/view.php?id=2098
This commit is contained in:
13
ParaView-5.0.1/Web/Python/CMakeLists.txt
Normal file
13
ParaView-5.0.1/Web/Python/CMakeLists.txt
Normal file
@ -0,0 +1,13 @@
|
||||
include(vtkModuleMacrosPython)
|
||||
|
||||
# The RELATIVE make vtk_module_python_package() preserve the vtk/module package
|
||||
# structure when building/installing. Otherwise, we'd just get the "web"
|
||||
# package.
|
||||
vtk_module_python_package(${vtk-module} "paraview/web"
|
||||
RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
|
||||
# copy some default sources and proxies for ParaViewWeb
|
||||
set(ParaViewPython_BINARY_DIR "${VTK_BUILD_PYTHON_MODULE_DIR}/paraview/web")
|
||||
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/defaultProxies.json"
|
||||
DESTINATION "${ParaViewPython_BINARY_DIR}"
|
||||
USE_SOURCE_PERMISSIONS)
|
||||
49
ParaView-5.0.1/Web/Python/WAMP2_RENAME.txt
Normal file
49
ParaView-5.0.1/Web/Python/WAMP2_RENAME.txt
Normal file
@ -0,0 +1,49 @@
|
||||
# RpcName: addRuler pv.widgets.ruler.add
|
||||
# RpcName: addSource pv.pipeline.manager.proxy.add
|
||||
# RpcName: clearAll pv.test.reset
|
||||
# RpcName: colorBy pv.color.manager.color.by
|
||||
# RpcName: connect pv.remote.connect
|
||||
# RpcName: createWidgetRepresentation pv.widgets.representation.create
|
||||
# RpcName: deleteSource pv.pipeline.manager.proxy.delete
|
||||
# RpcName: endSelection pv.selection.end
|
||||
# RpcName: exportData pv.export.data
|
||||
# RpcName: getColoringInfo pv.test.color.info.get
|
||||
# RpcName: getDatabase pv.data.prober.database.json
|
||||
# RpcName: getDatabaseAsHTML pv.data.prober.database.html
|
||||
# RpcName: getLutDataRange pv.pipeline.manager.lut.range.get
|
||||
# RpcName: getPipeline pv.pipeline.manager.pipeline.get
|
||||
# RpcName: getProbeData pv.data.prober.probe.data
|
||||
# RpcName: getScalarBarVisibilities pv.color.manager.scalarbar.visibility.get
|
||||
# RpcName: getSceneMetaData viewport.webgl.metadata
|
||||
# RpcName: getWebGLData viewport.webgl.data
|
||||
# RpcName: goToNext pv.data.prober.time.next
|
||||
# RpcName: goToPrev pv.data.prober.time.previous
|
||||
# RpcName: listColorMapNames pv.color.manager.list.preset
|
||||
# RpcName: listFiles pv.files.list
|
||||
# RpcName: listFilters pv.filters.list
|
||||
# RpcName: listServerDirectory file.server.directory.list
|
||||
# RpcName: loadData pv.data.prober.load.data
|
||||
# RpcName: loadDatasets pv.data.prober.load.dataset
|
||||
# RpcName: loadState pv.loader.state
|
||||
# RpcName: mouseInteraction viewport.mouse.interaction
|
||||
# RpcName: openFile pv.pipeline.manager.file.open
|
||||
# RpcName: openFileFromPath pv.file.loader.open.file
|
||||
# RpcName: openRelativeFile pv.pipeline.manager.file.ropen
|
||||
# RpcName: pushState pv.pipeline.manager.proxy.update
|
||||
# RpcName: pvDisconnect pv.remote.disconnect
|
||||
# RpcName: reloadPipeline pv.pipeline.manager.reload
|
||||
# RpcName: rescaleTransferFunction pv.color.manager.rescale.transfer.function
|
||||
# RpcName: resetCamera viewport.camera.reset
|
||||
# RpcName: reverseConnect pv.remote.reverse.connect
|
||||
# RpcName: selectColorMap pv.color.manager.select.preset
|
||||
# RpcName: setLutDataRange pv.pipeline.manager.lut.range.update
|
||||
# RpcName: setScalarBarVisibilities pv.color.manager.scalarbar.visibility.set
|
||||
# RpcName: startSelection pv.selection.start
|
||||
# RpcName: stillRender viewport.image.render
|
||||
# RpcName: updateCamera viewport.camera.update
|
||||
# RpcName: updateCenterAxesVisibility viewport.axes.center.visibility.update
|
||||
# RpcName: updateDisplayProperty pv.pipeline.manager.proxy.representation.update
|
||||
# RpcName: updateOrientationAxesVisibility viewport.axes.orientation.visibility.update
|
||||
# RpcName: updateScalarbarVisibility pv.pipeline.manager.scalarbar.visibility.update
|
||||
# RpcName: updateScalarRange pv.pipeline.manager.scalar.range.rescale
|
||||
# RpcName: updateTime pv.vcr.action
|
||||
34
ParaView-5.0.1/Web/Python/defaultProxies.json
Normal file
34
ParaView-5.0.1/Web/Python/defaultProxies.json
Normal file
@ -0,0 +1,34 @@
|
||||
{
|
||||
"sources": [
|
||||
{ "name": "AnnotateTime", "label": "Annotate Time" },
|
||||
{ "name": "Cone" },
|
||||
{ "name": "Sphere" },
|
||||
{ "name": "Text" },
|
||||
{ "name": "Wavelet" }
|
||||
],
|
||||
|
||||
"filters": [
|
||||
{ "name": "Calculator" },
|
||||
{ "name": "CellDatatoPointData", "label": "Cell Data To Point Data" },
|
||||
{ "name": "Clip" },
|
||||
{ "name": "Contour" },
|
||||
{ "name": "D3" },
|
||||
{ "name": "ExtractCTHParts", "label": "Extract CTH Parts" },
|
||||
{ "name": "ProcessIdScalars", "label": "Process ID Scalars" },
|
||||
{ "name": "Reflect" },
|
||||
{ "name": "Slice" },
|
||||
{ "name": "StreamTracer", "label": "Stream Tracer" },
|
||||
{ "name": "Threshold" },
|
||||
{ "name": "Transform" },
|
||||
{ "name": "Tube" },
|
||||
{ "name": "Ribbon" },
|
||||
{ "name": "WarpByScalar", "label": "Warp By Scalar" },
|
||||
{ "name": "WarpByVector", "label": "Warp By Vector" },
|
||||
{ "name": "ExtractBlock", "label": "Extract Blocks" }
|
||||
],
|
||||
|
||||
"readers": [
|
||||
{ "name": "LegacyVTKReader", "extensions": [ "vtk" ], "method": "FileNames" },
|
||||
{ "name": "Xdmf3ReaderS", "extensions": [ "xmf", "xdmf" ] }
|
||||
]
|
||||
}
|
||||
4
ParaView-5.0.1/Web/Python/module.cmake
Normal file
4
ParaView-5.0.1/Web/Python/module.cmake
Normal file
@ -0,0 +1,4 @@
|
||||
vtk_module(vtkParaViewWebPython
|
||||
DEPENDS
|
||||
AutobahnPython
|
||||
EXCLUDE_FROM_WRAPPING)
|
||||
0
ParaView-5.0.1/Web/Python/paraview/web/__init__.py
Normal file
0
ParaView-5.0.1/Web/Python/paraview/web/__init__.py
Normal file
227
ParaView-5.0.1/Web/Python/paraview/web/decorators.py
Normal file
227
ParaView-5.0.1/Web/Python/paraview/web/decorators.py
Normal file
@ -0,0 +1,227 @@
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# Handle BooleanDomain
|
||||
#--------------------------------------------------------------------------
|
||||
def booleanDomainDecorator(props, xmlProps, uiProps, domain):
|
||||
uiProps['widget'] = 'checkbox'
|
||||
uiProps['type'] = 'int'
|
||||
return True
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# Handle EnumerationDomain
|
||||
#--------------------------------------------------------------------------
|
||||
def enumerationDomainDecorator(props, xmlProps, uiProps, domain):
|
||||
uiProps['widget'] = 'list-1'
|
||||
uiProps['type'] = 'int'
|
||||
|
||||
valMap = {}
|
||||
for entryNum in range(domain.GetNumberOfEntries()):
|
||||
valMap[domain.GetEntryText(entryNum)] = domain.GetEntryValue(entryNum)
|
||||
|
||||
uiProps['values'] = valMap
|
||||
|
||||
return True
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# Handle StringListDomain
|
||||
#--------------------------------------------------------------------------
|
||||
def stringListDomainDecorator(props, xmlProps, uiProps, domain):
|
||||
uiProps['widget'] = 'list-1'
|
||||
uiProps['type'] = 'str'
|
||||
|
||||
valuesList = []
|
||||
for idx in range(domain.GetNumberOfStrings()):
|
||||
valuesList.append(domain.GetString(idx))
|
||||
|
||||
uiProps['values'] = valuesList
|
||||
|
||||
return True
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# Handle TreeDomain
|
||||
#--------------------------------------------------------------------------
|
||||
def treeDomainDecorator(props, xmlProps, uiProps, domain):
|
||||
uiProps['type'] = 'int'
|
||||
uiProps['widget'] = 'list-n'
|
||||
|
||||
valMap = {}
|
||||
|
||||
index = 0
|
||||
stack = []
|
||||
stack.append([ domain.GetInformation(), [] ])
|
||||
|
||||
while len(stack) > 0:
|
||||
me = stack.pop()
|
||||
|
||||
dataInformation = me[0]
|
||||
accumulatedName = me[1]
|
||||
|
||||
if len(accumulatedName) > 1 and accumulatedName[0] == 'Element Blocks':
|
||||
print index,' -> ',' + '.join(accumulatedName)
|
||||
valMap[accumulatedName[-1]] = index
|
||||
|
||||
index += 1
|
||||
|
||||
infoName = None
|
||||
|
||||
if dataInformation:
|
||||
infoName = dataInformation.GetCompositeDataClassName()
|
||||
|
||||
if infoName:
|
||||
# May have children
|
||||
info = dataInformation.GetCompositeDataInformation()
|
||||
numChildren = info.GetNumberOfChildren()
|
||||
if numChildren > 0:
|
||||
for i in range(numChildren - 1, -1, -1):
|
||||
child = info.GetDataInformation(i)
|
||||
childName = info.GetName(i)
|
||||
stack.append([ child, accumulatedName + [childName] ])
|
||||
|
||||
#valMap = { 'Block 1': 2, 'Block 2': 3 }
|
||||
|
||||
uiProps['values'] = valMap
|
||||
|
||||
return True
|
||||
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# Handle ArrayListDomain
|
||||
#--------------------------------------------------------------------------
|
||||
def arrayListDomainDecorator(props, xmlProps, uiProps, domain):
|
||||
uiProps['type'] = 'str'
|
||||
uiProps['widget'] = 'list-1'
|
||||
|
||||
fieldMap = { "0": "POINTS", "1": "CELLS" }
|
||||
valuesMap = {}
|
||||
valuesList = []
|
||||
|
||||
for arnum in range(domain.GetNumberOfStrings()):
|
||||
stringName = domain.GetString(arnum)
|
||||
try:
|
||||
assocVar = domain.GetFieldAssociation(arnum)
|
||||
valuesMap[stringName] = [ fieldMap[str(assocVar)], stringName ]
|
||||
except:
|
||||
valuesList.append(stringName)
|
||||
|
||||
if len(valuesList) > 0:
|
||||
uiProps['values'] = valuesList
|
||||
else:
|
||||
uiProps['values'] = valuesMap
|
||||
|
||||
return True
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# Handle ArraySelectionDomain
|
||||
#--------------------------------------------------------------------------
|
||||
def arraySelectionDomainDecorator(props, xmlProps, uiProps, domain):
|
||||
uiProps['type'] = 'str'
|
||||
uiProps['widget'] = 'list-n'
|
||||
|
||||
valuesList = []
|
||||
|
||||
for arnum in range(domain.GetNumberOfStrings()):
|
||||
valuesList.append(domain.GetString(arnum))
|
||||
|
||||
uiProps['values'] = valuesList
|
||||
|
||||
return True
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# Handle IntRangeDomain, DoubleRangeDomain, and ArrayRangeDomain
|
||||
#--------------------------------------------------------------------------
|
||||
def numberRangeDomainDecorator(props, xmlProps, uiProps, domain):
|
||||
uiProps['widget'] = 'textfield'
|
||||
|
||||
domainClass = domain.GetClassName()
|
||||
|
||||
if domainClass.rfind('Int') >= 0:
|
||||
uiProps['type'] = 'int'
|
||||
else:
|
||||
uiProps['type'] = 'float'
|
||||
|
||||
ranges = []
|
||||
|
||||
idx = 0
|
||||
while domain.GetMinimumExists(idx) == 1 and domain.GetMaximumExists(idx) == 1:
|
||||
ranges.append({ 'min': domain.GetMinimum(idx), 'max': domain.GetMaximum(idx) })
|
||||
idx += 1
|
||||
|
||||
uiProps['range'] = ranges
|
||||
|
||||
if idx == 0:
|
||||
return False
|
||||
return True
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# Handle ProxyListDomain
|
||||
#--------------------------------------------------------------------------
|
||||
def proxyListDomainDecorator(props, xmlProps, uiProps, domain):
|
||||
uiProps['widget'] = 'list-1'
|
||||
uiProps['size'] = 1
|
||||
uiProps['type'] = 'proxy'
|
||||
values = {}
|
||||
|
||||
for i in xrange(domain.GetNumberOfProxies()):
|
||||
nextProxy = domain.GetProxy(i)
|
||||
values[nextProxy.GetXMLLabel()] = nextProxy.GetGlobalIDAsString()
|
||||
|
||||
uiProps['values'] = values
|
||||
return True
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# Decorate for PropertyWidgetDecorator hint with type="ClipScalarDecorator"
|
||||
#--------------------------------------------------------------------------
|
||||
# FIXME: Remove this when GenericDecorator goes into master
|
||||
def clipScalarDecorator(prop, uiElt, hint):
|
||||
proxy = None
|
||||
try:
|
||||
proxy = prop.SMProperty.GetParent()
|
||||
except:
|
||||
try:
|
||||
proxy = prop.GetParent()
|
||||
except:
|
||||
print 'ERROR: unable to get proxy for property ' + prop.Name
|
||||
return
|
||||
excludeAttr = hint.GetAttribute('exclude')
|
||||
if not excludeAttr or excludeAttr != '1':
|
||||
depends = proxy.GetGlobalIDAsString() + ':ClipFunction:Scalar:1'
|
||||
else:
|
||||
depends = proxy.GetGlobalIDAsString() + ':ClipFunction:Scalar:0'
|
||||
uiElt['depends'] = depends
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# Decorate for PropertyWidgetDecorator hint with type="GenericDecorator"
|
||||
#--------------------------------------------------------------------------
|
||||
def genericDecorator(prop, uiElt, hint):
|
||||
proxy = None
|
||||
try:
|
||||
proxy = prop.SMProperty.GetParent()
|
||||
except:
|
||||
try:
|
||||
proxy = prop.GetParent()
|
||||
except:
|
||||
print 'ERROR: unable to get proxy for property ' + prop.Name
|
||||
return
|
||||
|
||||
mode = hint.GetAttribute("mode")
|
||||
|
||||
# For now we just handle visbility mode
|
||||
if mode == 'visibility':
|
||||
propName = hint.GetAttribute("property")
|
||||
value = hint.GetAttribute("value")
|
||||
inverse = hint.GetAttribute("inverse")
|
||||
visibility = '1'
|
||||
|
||||
if not inverse or inverse != '1':
|
||||
visibility = '1'
|
||||
else:
|
||||
visibility = '0'
|
||||
|
||||
uiElt['depends'] = "%s:%s:%s:%s" % (proxy.GetGlobalIDAsString(), propName, value, visibility)
|
||||
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# Decorate for Widget hint with type="multi_line"
|
||||
#--------------------------------------------------------------------------
|
||||
def multiLineDecorator(prop, uiElt, hint):
|
||||
uiElt['widget'] = 'textarea'
|
||||
516
ParaView-5.0.1/Web/Python/paraview/web/helper.py
Normal file
516
ParaView-5.0.1/Web/Python/paraview/web/helper.py
Normal file
@ -0,0 +1,516 @@
|
||||
r"""web_helper is a module that provides access to functions that helps to build
|
||||
new protocols and process ParaView data structure into web friendly ones.
|
||||
"""
|
||||
|
||||
import types
|
||||
import sys
|
||||
import os
|
||||
import traceback
|
||||
|
||||
# import paraview modules.
|
||||
import paraview
|
||||
|
||||
from paraview import simple, servermanager
|
||||
from paraview.servermanager import ProxyProperty, InputProperty
|
||||
|
||||
from vtkPVServerManagerCorePython import *
|
||||
|
||||
# Needed for:
|
||||
# vtkSMPVRepresentationProxy
|
||||
from vtkPVServerManagerRenderingPython import *
|
||||
|
||||
# =============================================================================
|
||||
# Pipeline management
|
||||
# =============================================================================
|
||||
|
||||
class Pipeline:
|
||||
"""
|
||||
Define a data structure that represent a pipeline as a tree.
|
||||
This provide also methods to get the data structure for the web environment
|
||||
"""
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
def __init__(self, name):
|
||||
self.root_node = { 'name': name, 'icon': 'server', 'children': [] }
|
||||
self.parent_ids = { '0':'0' }
|
||||
self.children_ids = { '0':[] }
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
def clear(self):
|
||||
"""
|
||||
Clear the pipeline tree.
|
||||
"""
|
||||
self.root_node['children'] = []
|
||||
self.parent_ids = { '0':'0' }
|
||||
self.children_ids = { '0':[] }
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
def addNode(self, parent_id, node_id):
|
||||
"""
|
||||
Add node into the pipeline tree.
|
||||
"""
|
||||
pid = str(parent_id)
|
||||
nid = str(node_id)
|
||||
|
||||
# Add child
|
||||
if self.children_ids.has_key(pid):
|
||||
self.children_ids[pid].append(nid)
|
||||
else:
|
||||
self.children_ids[pid] = [nid]
|
||||
|
||||
# Add parent
|
||||
self.parent_ids[nid] = pid
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
def removeNode(self, id):
|
||||
"""
|
||||
Remove a node from the pipeline tree.
|
||||
"""
|
||||
nid = str(id)
|
||||
pid = self.parent_ids[nid]
|
||||
if pid:
|
||||
del self.parent_ids[nid]
|
||||
self.children_ids[pid].remove(nid)
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
def isEmpty(self):
|
||||
return len(self.parent_ids) == 1
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
def getRootNode(self, view = None):
|
||||
"""
|
||||
Create a tree structure of the pipeline with the current proxy state.
|
||||
"""
|
||||
self.root_node['children'] = []
|
||||
self.__fill_children(self.root_node, self.children_ids['0'], view)
|
||||
return self.root_node
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
def __fill_children(self, nodeToFill, childrenIds, view = None):
|
||||
for id in childrenIds:
|
||||
node = getProxyAsPipelineNode(id, view)
|
||||
nid = str(node['proxy_id'])
|
||||
|
||||
if nodeToFill.has_key('children'):
|
||||
nodeToFill['children'].append(node)
|
||||
else:
|
||||
nodeToFill['children'] = [ node ]
|
||||
|
||||
if self.children_ids.has_key(nid):
|
||||
self.__fill_children(node, self.children_ids[nid]);
|
||||
|
||||
# =============================================================================
|
||||
# Proxy management
|
||||
# =============================================================================
|
||||
|
||||
def idToProxy(id):
|
||||
"""
|
||||
Return the proxy that match the given proxy ID.
|
||||
"""
|
||||
remoteObject = simple.servermanager.ActiveConnection.Session.GetRemoteObject(int(id))
|
||||
if remoteObject:
|
||||
return simple.servermanager._getPyProxy(remoteObject)
|
||||
return None
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
def getParentProxyId(proxy):
|
||||
"""
|
||||
Return '0' if the given proxy has no Input otherwise will return
|
||||
the parent proxy id as a String.
|
||||
"""
|
||||
if proxy and proxy.GetProperty("Input"):
|
||||
parentProxy = proxy.GetProperty("Input").GetProxy(0)
|
||||
if parentProxy:
|
||||
return parentProxy.GetGlobalIDAsString()
|
||||
return '0'
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
def getProxyAsPipelineNode(id, view=None):
|
||||
"""
|
||||
Create a representation for that proxy so it can be used within a pipeline
|
||||
browser.
|
||||
"""
|
||||
pxm = servermanager.ProxyManager()
|
||||
proxy = idToProxy(id)
|
||||
rep = simple.GetDisplayProperties(proxy)
|
||||
nbActiveComp = 1
|
||||
|
||||
pointData = []
|
||||
searchArray = ('POINTS' == rep.ColorArrayName[0]) and (len(rep.ColorArrayName[1]) > 0)
|
||||
|
||||
if servermanager.ActiveConnection.GetNumberOfDataPartitions() > 1:
|
||||
info = { \
|
||||
'lutId': 'vtkProcessId_1', \
|
||||
'name': 'vtkProcessId', \
|
||||
'size': 1, \
|
||||
'range': [0, servermanager.ActiveConnection.GetNumberOfDataPartitions()-1] }
|
||||
pointData.append(info)
|
||||
|
||||
# FIXME seb
|
||||
# dataInfo = rep.GetRepresentedDataInformation()
|
||||
# pointData = dataInfo.GetPointDataInformation()
|
||||
# cellData = dataInfo.GetCellDataInformation()
|
||||
# for idx in pointData.GetNumberOfArrays():
|
||||
# info = pointData.GetArrayInformation(idx)
|
||||
# nbComponents = info.GetNumberOfComponents()
|
||||
# if searchArray and array.Name == rep.ColorArrayName:
|
||||
# nbActiveComp = nbComponents
|
||||
# rangeOn = (nbComponents == 3 if -1 else 0)
|
||||
# info = { \
|
||||
# 'lutId': info.GetName() + '_' + str(nbComponents), \
|
||||
# 'name': info.GetName, \
|
||||
# 'size': nbComponents, \
|
||||
# 'range': info.GetRange(rangeOn) }
|
||||
# pointData.append(info)
|
||||
|
||||
for array in proxy.GetPointDataInformation():
|
||||
nbComponents = array.GetNumberOfComponents()
|
||||
if searchArray and array.Name == rep.ColorArrayName[1]:
|
||||
nbActiveComp = nbComponents
|
||||
rangeOn = (nbComponents == 1 if 0 else -1)
|
||||
info = { \
|
||||
'lutId': array.Name + '_' + str(nbComponents), \
|
||||
'name': array.Name, \
|
||||
'size': nbComponents, \
|
||||
'range': array.GetRange(rangeOn) }
|
||||
pointData.append(info)
|
||||
|
||||
cellData = []
|
||||
searchArray = ('CELLS' == rep.ColorArrayName[0]) and (len(rep.ColorArrayName[1]) > 0)
|
||||
for array in proxy.GetCellDataInformation():
|
||||
nbComponents = array.GetNumberOfComponents()
|
||||
if searchArray and array.Name == rep.ColorArrayName[1]:
|
||||
nbActiveComp = nbComponents
|
||||
rangeOn = (nbComponents == 1 if 0 else -1)
|
||||
info = { \
|
||||
'lutId': array.Name + '_' + str(nbComponents), \
|
||||
'name': array.Name, \
|
||||
'size': nbComponents, \
|
||||
'range': array.GetRange(rangeOn) }
|
||||
cellData.append(info)
|
||||
|
||||
state = getProxyAsState(proxy.GetGlobalID())
|
||||
showScalarbar = 1 if view and vtkSMPVRepresentationProxy.IsScalarBarVisible(rep.SMProxy, view.SMProxy) else 0
|
||||
|
||||
repName = 'Hide'
|
||||
if rep.Visibility == 1:
|
||||
repName = rep.Representation
|
||||
|
||||
return { 'proxy_id' : proxy.GetGlobalID(), \
|
||||
'name' : pxm.GetProxyName("sources", proxy), \
|
||||
'bounds' : proxy.GetDataInformation().GetBounds(), \
|
||||
'pointData' : pointData, \
|
||||
'cellData' : cellData, \
|
||||
'activeData': str(rep.ColorArrayName[0]) + ':' + str(rep.ColorArrayName[1]), \
|
||||
'diffuseColor' : str(rep.DiffuseColor), \
|
||||
'showScalarBar' : showScalarbar, \
|
||||
'representation': repName, \
|
||||
'state' : state, \
|
||||
'children' : [] }
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
def getProxyAsState(id):
|
||||
"""
|
||||
Return a json representation of the given proxy state.
|
||||
|
||||
Example of the state of the Clip filter
|
||||
{
|
||||
proxy_id: 234,
|
||||
ClipType: {
|
||||
proxy_id: 235,
|
||||
Normal: [0,0,1],
|
||||
Origin: [0,0,0],
|
||||
InsideOut: 0
|
||||
}
|
||||
}
|
||||
"""
|
||||
proxy_id = int(id)
|
||||
proxy = idToProxy(proxy_id)
|
||||
state = { 'proxy_id': proxy_id , 'type': 'proxy', 'domains': getProxyDomains(proxy_id)}
|
||||
properties = {}
|
||||
allowedTypes = [int, float, list, str]
|
||||
if proxy:
|
||||
for property in proxy.ListProperties():
|
||||
propertyName = proxy.GetProperty(property).Name
|
||||
if propertyName in ["Refresh", "Input"] or propertyName.__contains__("Info"):
|
||||
continue
|
||||
|
||||
data = proxy.GetProperty(property).GetData()
|
||||
if type(data) in allowedTypes:
|
||||
properties[propertyName] = data
|
||||
continue
|
||||
|
||||
# Not a simple property
|
||||
# Need more investigation
|
||||
prop = proxy.GetProperty(property)
|
||||
pythonProp = servermanager._wrap_property(proxy, prop)
|
||||
proxyList = []
|
||||
try:
|
||||
proxyList = pythonProp.Available
|
||||
except:
|
||||
pass
|
||||
if len(proxyList) and prop.GetNumberOfProxies() == 1:
|
||||
listdomain = prop.GetDomain('proxy_list')
|
||||
if listdomain:
|
||||
proxyPropertyValue = prop.GetProxy(0)
|
||||
for i in xrange(listdomain.GetNumberOfProxies()):
|
||||
if listdomain.GetProxy(i) == proxyPropertyValue:
|
||||
properties[propertyName] = proxyList[i]
|
||||
# Add selected proxy in list of prop to edit
|
||||
properties[propertyName + '_internal'] = getProxyAsState(listdomain.GetProxy(i).GetGlobalID())
|
||||
|
||||
elif type(prop) == ProxyProperty:
|
||||
try:
|
||||
subProxyId = proxy.GetProperty(property).GetData().GetGlobalID()
|
||||
properties[propertyName] = getProxyAsState(subProxyId)
|
||||
except:
|
||||
print "Error on", property, propertyName
|
||||
print "Skip property: ", str(type(data))
|
||||
print data
|
||||
state['properties'] = properties;
|
||||
return state
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
def updateProxyProperties(proxy, properties):
|
||||
"""
|
||||
Loop over the properties object and update the mapping properties
|
||||
to the given proxy.
|
||||
"""
|
||||
try:
|
||||
allowedProperties = proxy.ListProperties()
|
||||
for key in properties:
|
||||
validKey = servermanager._make_name_valid(key)
|
||||
if validKey in allowedProperties:
|
||||
value = removeUnicode(properties[key])
|
||||
property = servermanager._wrap_property(proxy, proxy.GetProperty(validKey))
|
||||
if property.GetDomain('proxy_list') and len(value) == 1 and type(value[0]) == str:
|
||||
try:
|
||||
idx = property.GetAvailable().index(value[0])
|
||||
proxyToSet = servermanager._getPyProxy(property.GetDomain('proxy_list').GetProxy(idx))
|
||||
property.SetData(proxyToSet)
|
||||
except:
|
||||
traceback.print_stack()
|
||||
pass
|
||||
elif value == 'vtkProcessId':
|
||||
property.SetElement(0, value)
|
||||
else:
|
||||
property.SetData(value)
|
||||
except:
|
||||
traceback.print_stack()
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
|
||||
def removeUnicode(value):
|
||||
if type(value) == unicode:
|
||||
return str(value)
|
||||
if type(value) == list:
|
||||
result = []
|
||||
for v in value:
|
||||
result.append(removeUnicode(v))
|
||||
return result
|
||||
return value
|
||||
|
||||
# =============================================================================
|
||||
# XML and Proxy Definition for GUI generation
|
||||
# =============================================================================
|
||||
|
||||
def getProxyDomains(id):
|
||||
"""
|
||||
Return a json based structured based on the proxy XML.
|
||||
"""
|
||||
jsonDefinition = {}
|
||||
proxy = idToProxy(id)
|
||||
xmlElement = servermanager.ActiveConnection.Session.GetProxyDefinitionManager().GetCollapsedProxyDefinition(proxy.GetXMLGroup(), proxy.GetXMLName(), None)
|
||||
nbChildren = xmlElement.GetNumberOfNestedElements()
|
||||
for i in range(nbChildren):
|
||||
xmlChild = xmlElement.GetNestedElement(i)
|
||||
name = xmlChild.GetName()
|
||||
if name.__contains__('Property'):
|
||||
propName = xmlChild.GetAttribute('name')
|
||||
jsonDefinition[propName] = extractProperty(proxy, xmlChild)
|
||||
jsonDefinition[propName]['order'] = i
|
||||
|
||||
# Look for proxy properties and their domain
|
||||
orderIndex = nbChildren
|
||||
for property in proxy.ListProperties():
|
||||
if property == 'Input':
|
||||
continue
|
||||
if type(proxy.GetProperty(property)) == ProxyProperty:
|
||||
try:
|
||||
subProxyId = proxy.GetProperty(property).GetData().GetGlobalID()
|
||||
subDomain = getProxyDomains(subProxyId)
|
||||
for key in subDomain:
|
||||
jsonDefinition[key] = subDomain[key]
|
||||
jsonDefinition[key]['order'] = orderIndex
|
||||
orderIndex = orderIndex + 1
|
||||
except:
|
||||
print "(Def) Error on", property, ", skipping it..."
|
||||
#print "(Def) Skip property: ", str(type(data))
|
||||
|
||||
return jsonDefinition
|
||||
|
||||
def extractProperty(proxy, xmlPropertyElement):
|
||||
propInfo = {}
|
||||
propInfo['name'] = xmlPropertyElement.GetAttribute('name')
|
||||
propInfo['label'] = xmlPropertyElement.GetAttribute('label')
|
||||
if xmlPropertyElement.GetAttribute('number_of_elements') != None:
|
||||
propInfo['size'] = xmlPropertyElement.GetAttribute('number_of_elements')
|
||||
propInfo['type'] = xmlPropertyElement.GetName()[:-14]
|
||||
propInfo['panel_visibility'] = xmlPropertyElement.GetAttribute('panel_visibility')
|
||||
propInfo['number_of_elements'] = xmlPropertyElement.GetAttribute('number_of_elements')
|
||||
propInfo['domains'] = []
|
||||
if xmlPropertyElement.GetAttribute('default_values') != None:
|
||||
propInfo['default_values'] = xmlPropertyElement.GetAttribute('default_values')
|
||||
nbChildren = xmlPropertyElement.GetNumberOfNestedElements()
|
||||
for i in range(nbChildren):
|
||||
xmlChild = xmlPropertyElement.GetNestedElement(i)
|
||||
name = xmlChild.GetName()
|
||||
if name.__contains__('Domain'):
|
||||
propInfo['domains'].append(extractDomain(proxy, propInfo['name'], xmlChild))
|
||||
return propInfo
|
||||
|
||||
def extractDomain(proxy, propertyName, xmlDomainElement):
|
||||
domainObj = {}
|
||||
name = xmlDomainElement.GetName()
|
||||
domainObj['type'] = name[:-6]
|
||||
|
||||
# Handle Range
|
||||
if name.__contains__('RangeDomain'):
|
||||
if xmlDomainElement.GetAttribute('min') != None:
|
||||
domainObj['min'] = xmlDomainElement.GetAttribute('min')
|
||||
if xmlDomainElement.GetAttribute('max') != None:
|
||||
domainObj['max'] = xmlDomainElement.GetAttribute('max')
|
||||
|
||||
# Handle Enum
|
||||
if name.__contains__('EnumerationDomain'):
|
||||
domainObj['enum'] = []
|
||||
nbChildren = xmlDomainElement.GetNumberOfNestedElements()
|
||||
for i in range(nbChildren):
|
||||
xmlChild = xmlDomainElement.GetNestedElement(i)
|
||||
if xmlChild.GetName() == "Entry":
|
||||
domainObj['enum'].append({'text': xmlChild.GetAttribute('text'), 'value': xmlChild.GetAttribute('value')})
|
||||
|
||||
# Handle ArrayListDomain
|
||||
if name.__contains__('ArrayListDomain'):
|
||||
dataType = xmlDomainElement.GetAttribute('attribute_type')
|
||||
if dataType == 'Scalars':
|
||||
domainObj['nb_components'] = 1
|
||||
elif dataType == 'Vectors':
|
||||
domainObj['nb_components'] = 3
|
||||
else:
|
||||
domainObj['nb_components'] = -1
|
||||
|
||||
# Handle ProxyListDomain
|
||||
if name.__contains__('ProxyListDomain'):
|
||||
domainObj['list'] = proxy.GetProperty(propertyName).Available
|
||||
|
||||
# Handle Bounds
|
||||
if name.__contains__('BoundsDomain'):
|
||||
for attrName in ['default_mode', 'mode', 'scale_factor']:
|
||||
try:
|
||||
attrValue = xmlDomainElement.GetAttribute(attrName)
|
||||
if attrValue:
|
||||
domainObj[attrName] = attrValue
|
||||
except:
|
||||
pass
|
||||
|
||||
return domainObj
|
||||
|
||||
# =============================================================================
|
||||
# File Management
|
||||
# =============================================================================
|
||||
|
||||
def listFiles(pathToList):
|
||||
"""
|
||||
Create a tree structure of the given directory that will be understand by
|
||||
the pipelineBrowser widget.
|
||||
The provided path should not have a trailing '/'.
|
||||
|
||||
return {
|
||||
children: [
|
||||
{ name: 'fileName.vtk', path: '/full_path/to_file/fileName.vtk' },
|
||||
{ name: 'directoryName', path: '/full_path/to_file/directoryName', children: [] }
|
||||
]
|
||||
}
|
||||
"""
|
||||
global fileList
|
||||
if pathToList[-1] == '/':
|
||||
pathToList = pathToList[:-1]
|
||||
nodeTree = {}
|
||||
nodeTree[pathToList] = {'children': []}
|
||||
for path, directories, files in os.walk(pathToList):
|
||||
parent = nodeTree[path]
|
||||
for directory in directories:
|
||||
child = {'name': directory , 'path': (path + '/' + directory), 'children': []}
|
||||
nodeTree[path + '/' + directory] = child
|
||||
parent['children'].append(child)
|
||||
for filename in files:
|
||||
child = {'name': filename, 'path': (path + '/' + filename) }
|
||||
nodeTree[path + '/' + filename] = child
|
||||
parent['children'].append(child)
|
||||
fileList = nodeTree[pathToList]['children']
|
||||
return fileList
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Apply domains
|
||||
# =============================================================================
|
||||
|
||||
def apply_domains(parentProxy, proxy_id):
|
||||
"""
|
||||
Handle bounds domain
|
||||
"""
|
||||
proxy = idToProxy(proxy_id)
|
||||
|
||||
# Call recursively on each sub-proxy if any
|
||||
for property_name in proxy.ListProperties():
|
||||
prop = proxy.GetProperty(property_name)
|
||||
if prop.IsA('vtkSMProxyProperty'):
|
||||
try:
|
||||
if len(prop.Available) and prop.GetNumberOfProxies() == 1:
|
||||
listdomain = prop.GetDomain('proxy_list')
|
||||
if listdomain:
|
||||
for i in xrange(listdomain.GetNumberOfProxies()):
|
||||
internal_proxy = listdomain.GetProxy(i)
|
||||
apply_domains(parentProxy, internal_proxy.GetGlobalIDAsString())
|
||||
except:
|
||||
exc_type, exc_obj, exc_tb = sys.exc_info()
|
||||
print "Unexpected error:", exc_type, " line: " , exc_tb.tb_lineno
|
||||
|
||||
# Reset all properties to leverage domain capabilities
|
||||
for prop_name in proxy.ListProperties():
|
||||
try:
|
||||
prop = proxy.GetProperty(prop_name)
|
||||
iter = prop.NewDomainIterator()
|
||||
iter.Begin()
|
||||
while not iter.IsAtEnd():
|
||||
domain = iter.GetDomain()
|
||||
iter.Next()
|
||||
|
||||
try:
|
||||
if domain.IsA('vtkSMBoundsDomain'):
|
||||
domain.SetDomainValues(parentProxy.GetDataInformation().GetBounds())
|
||||
except AttributeError as attrErr:
|
||||
print 'Caught exception setting domain values in apply_domains:'
|
||||
print attrErr
|
||||
|
||||
prop.ResetToDefault()
|
||||
|
||||
# Need to UnRegister to handle the ref count from the NewDomainIterator
|
||||
iter.UnRegister(None)
|
||||
except:
|
||||
exc_type, exc_obj, exc_tb = sys.exc_info()
|
||||
print "Unexpected error:", exc_type, " line: " , exc_tb.tb_lineno
|
||||
|
||||
proxy.UpdateVTKObjects()
|
||||
307
ParaView-5.0.1/Web/Python/paraview/web/ipython.py
Normal file
307
ParaView-5.0.1/Web/Python/paraview/web/ipython.py
Normal file
@ -0,0 +1,307 @@
|
||||
r"""
|
||||
The ParaViewWeb iPython module is used as a helper to create custom
|
||||
iPython notebook profile.
|
||||
|
||||
The following sample show how the helper class can be used inside
|
||||
an iPython profile.
|
||||
|
||||
# Global python import
|
||||
import exceptions, logging, random, sys, threading, time, os
|
||||
|
||||
# Update python path to have ParaView libs
|
||||
pv_path = '/.../ParaView/build'
|
||||
sys.path.append('%s/lib' % pv_path)
|
||||
sys.path.append('%s/lib/site-packages' % pv_path)
|
||||
|
||||
# iPython import
|
||||
from IPython.display import HTML
|
||||
from IPython.parallel import Client
|
||||
import paraview
|
||||
from paraview.web import ipython as pv_ipython
|
||||
from vtk import *
|
||||
|
||||
iPythonClient = None
|
||||
paraviewHelper = pv_ipython.ParaViewIPython()
|
||||
webArguments = pv_ipython.WebArguments('/.../path-to-web-directory')
|
||||
|
||||
def _start_paraview():
|
||||
paraviewHelper.Initialize()
|
||||
paraviewHelper.SetWebProtocol(pv_ipython.IPythonProtocol, webArguments)
|
||||
return paraviewHelper.Start()
|
||||
|
||||
|
||||
def _stop_paraview():
|
||||
paraviewHelper.Finalize()
|
||||
|
||||
|
||||
def _pv_activate_dataset():
|
||||
pv_ipython.IPythonProtocol.ActivateDataSet('iPython-demo')
|
||||
|
||||
|
||||
def _push_new_timestep():
|
||||
# processing code generating new vtkDataSet
|
||||
# newDataset = ...
|
||||
pv_ipython.IPythonProtocol.RegisterDataSet('iPython-demo', newDataset)
|
||||
|
||||
|
||||
def StartParaView(height=600, path='/apps/Visualizer/'):
|
||||
global iPythonClient, paraviewHelper
|
||||
if not iPythonClient:
|
||||
iPythonClient = Client(profile='pvw')
|
||||
urls = iPythonClient[:].apply_sync(lambda:_start_paraview())
|
||||
url = ""
|
||||
for i in urls:
|
||||
if len(i) > 0:
|
||||
url = i
|
||||
return HTML("<iframe src='%s%s' width='100%%' height='%i'></iframe>"%(url, path, height))
|
||||
|
||||
|
||||
def StopParaView():
|
||||
global iPythonClient, paraviewHelper
|
||||
iPythonClient[:].apply_sync(lambda:_stop_paraview())
|
||||
|
||||
|
||||
def ActivateDataSet():
|
||||
iPythonClient[:].apply_sync(lambda:_pv_activate_dataset())
|
||||
|
||||
|
||||
def ComputeNextTimeStep():
|
||||
global iPythonClient
|
||||
if not iPythonClient:
|
||||
iPythonClient = Client(profile='pvw')
|
||||
iPythonClient[:].apply_sync(lambda:_push_new_timestep())
|
||||
|
||||
"""
|
||||
|
||||
import exceptions, traceback, logging, random, sys, threading, time, os, paraview
|
||||
|
||||
from mpi4py import MPI
|
||||
from vtk.web import server
|
||||
from paraview.vtk import *
|
||||
from vtkCommonCorePython import *
|
||||
from vtkCommonDataModelPython import *
|
||||
from vtkCommonExecutionModelPython import *
|
||||
from vtkFiltersSourcesPython import *
|
||||
from vtkParallelCorePython import *
|
||||
from vtkParaViewWebCorePython import *
|
||||
from vtkPVClientServerCoreCorePython import *
|
||||
from vtkPVServerManagerApplicationPython import *
|
||||
from vtkPVServerManagerCorePython import *
|
||||
from vtkPVVTKExtensionsCorePython import *
|
||||
from vtkWebCorePython import *
|
||||
|
||||
from paraview.web import wamp as pv_wamp
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Global variables
|
||||
#------------------------------------------------------------------------------
|
||||
logger = logging.getLogger()
|
||||
logger.setLevel(logging.ERROR)
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Global internal methods
|
||||
#------------------------------------------------------------------------------
|
||||
def _get_hostname():
|
||||
import socket
|
||||
if socket.gethostname().find('.')>=0:
|
||||
return socket.gethostname()
|
||||
else:
|
||||
return socket.gethostbyaddr(socket.gethostname())[0]
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# ParaView iPython helper class
|
||||
#------------------------------------------------------------------------------
|
||||
class ParaViewIPython(object):
|
||||
processModule = None
|
||||
globalController = None
|
||||
localController = None
|
||||
webProtocol = None
|
||||
webArguments = None
|
||||
processId = -1
|
||||
number_of_process = -1
|
||||
|
||||
def Initialize(self, log_file_path = None, logging_level = logging.DEBUG):
|
||||
if not ParaViewIPython.processModule:
|
||||
vtkInitializationHelper.Initialize("ipython-notebook", 4) # 4 is type of process
|
||||
ParaViewIPython.processModule = vtkProcessModule.GetProcessModule()
|
||||
ParaViewIPython.globalController = ParaViewIPython.processModule.GetGlobalController()
|
||||
|
||||
if MPI.COMM_WORLD.Get_size() > 1 and (ParaViewIPython.globalController is None or ParaViewIPython.globalController.IsA("vtkDummyController") == True):
|
||||
import vtkParallelMPIPython
|
||||
ParaViewIPython.globalController = vtkParallelMPIPython.vtkMPIController()
|
||||
ParaViewIPython.globalController.Initialize()
|
||||
ParaViewIPython.globalController.SetGlobalController(ParaViewIPython.globalController)
|
||||
|
||||
ParaViewIPython.processId = ParaViewIPython.globalController.GetLocalProcessId()
|
||||
ParaViewIPython.number_of_process = ParaViewIPython.globalController.GetNumberOfProcesses()
|
||||
ParaViewIPython.localController = ParaViewIPython.globalController.PartitionController(ParaViewIPython.number_of_process, ParaViewIPython.processId)
|
||||
|
||||
# must unregister if the reference count is greater than 1
|
||||
if ParaViewIPython.localController.GetReferenceCount() > 1:
|
||||
ParaViewIPython.localController.UnRegister(None)
|
||||
|
||||
ParaViewIPython.globalController.SetGlobalController(ParaViewIPython.localController)
|
||||
|
||||
if log_file_path:
|
||||
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
|
||||
fh = logging.FileHandler('%s-%s.txt' % (log_file_path, str(ParaViewIPython.processId)))
|
||||
fh.setLevel(logging_level)
|
||||
fh.setFormatter(formatter)
|
||||
logger.addHandler(fh)
|
||||
logger.info("Process %i initialized for ParaView" % os.getpid())
|
||||
logger.info("Sub-Controller: " + str(ParaViewIPython.localController.GetLocalProcessId()) + "/" + str(ParaViewIPython.localController.GetNumberOfProcesses()))
|
||||
logger.info("GlobalController: " + str(ParaViewIPython.processId) + "/" + str(ParaViewIPython.number_of_process))
|
||||
else:
|
||||
logger.info("ParaView has already been initialized. No operation was performed.")
|
||||
|
||||
def Finalize(self):
|
||||
if ParaViewIPython.processModule:
|
||||
vtkInitializationHelper.Finalize()
|
||||
ParaViewIPython.processModule = None
|
||||
|
||||
def GetProcessId(self):
|
||||
return ParaViewIPython.processId
|
||||
|
||||
def GetNumberOfProcesses(self):
|
||||
return ParaViewIPython.number_of_process
|
||||
|
||||
def __repr__(self):
|
||||
return self.__str__()
|
||||
|
||||
def __str__(self):
|
||||
return "Host: %s - Controller: %s - Rank: %d/%d" % (_get_hostname(), ParaViewIPython.localController.GetClassName(), ParaViewIPython.processId, ParaViewIPython.number_of_process)
|
||||
|
||||
def SetWebProtocol(self, protocol, arguments):
|
||||
ParaViewIPython.webProtocol = protocol
|
||||
ParaViewIPython.webArguments = arguments
|
||||
if not hasattr(ParaViewIPython.webArguments, 'port'):
|
||||
ParaViewIPython.webArguments.port = 8080
|
||||
ParaViewIPython.webProtocol.rootNode = (self.GetProcessId() == 0)
|
||||
ParaViewIPython.webProtocol.updateArguments(ParaViewIPython.webArguments)
|
||||
|
||||
@staticmethod
|
||||
def _start_satelite():
|
||||
logger.info('ParaView Satelite %d - Started' % ParaViewIPython.processId)
|
||||
sid = vtkSMSession.ConnectToSelf();
|
||||
vtkWebUtilities.ProcessRMIs()
|
||||
ParaViewIPython.processModule.UnRegisterSession(sid);
|
||||
logger.info('ParaView Satelite %d - Ended' % ParaViewIPython.processId)
|
||||
|
||||
@staticmethod
|
||||
def _start_web_server():
|
||||
server.start_webserver(options=ParaViewIPython.webArguments, protocol=ParaViewIPython.webProtocol)
|
||||
from paraview import simple
|
||||
simple.Disconnect()
|
||||
ParaViewIPython.localController.TriggerBreakRMIs()
|
||||
|
||||
@staticmethod
|
||||
def debug():
|
||||
for i in range(10):
|
||||
logger.info('In debug loop ' + str(i))
|
||||
|
||||
def Start(self):
|
||||
thread = None
|
||||
if self.GetProcessId() == 0:
|
||||
thread = threading.Thread(target=ParaViewIPython._start_web_server)
|
||||
thread.start()
|
||||
time.sleep(10)
|
||||
logger.info("WebServer thread started")
|
||||
return "http://%s:%d" % (_get_hostname(), ParaViewIPython.webArguments.port)
|
||||
else:
|
||||
thread = threading.Thread(target=ParaViewIPython._start_satelite)
|
||||
thread.start()
|
||||
logger.info("Satelite thread started")
|
||||
return ""
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# ParaView iPython protocol
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
class IPythonProtocol(pv_wamp.PVServerProtocol):
|
||||
rootNode = False
|
||||
dataDir = None
|
||||
authKey = "vtkweb-secret"
|
||||
fileToLoad = None
|
||||
producer = None
|
||||
groupRegex = "[0-9]+\\."
|
||||
excludeRegex = "^\\.|~$|^\\$"
|
||||
|
||||
@staticmethod
|
||||
def ActivateDataSet(key):
|
||||
if IPythonProtocol.rootNode and IPythonProtocol.producer:
|
||||
IPythonProtocol.producer.UpdateDataset = ''
|
||||
IPythonProtocol.producer.UpdateDataset = key
|
||||
|
||||
@staticmethod
|
||||
def RegisterDataSet(key, dataset):
|
||||
vtkDistributedTrivialProducer.SetGlobalOutput(key, dataset)
|
||||
|
||||
@staticmethod
|
||||
def updateArguments(options):
|
||||
IPythonProtocol.dataDir = options.dataDir
|
||||
IPythonProtocol.authKey = options.authKey
|
||||
IPythonProtocol.fileToLoad = options.fileToLoad
|
||||
IPythonProtocol.authKey = options.authKey
|
||||
IPythonProtocol.groupRegex = options.groupRegex
|
||||
IPythonProtocol.excludeRegex = options.excludeRegex
|
||||
|
||||
def initialize(self):
|
||||
from paraview import simple
|
||||
from paraview.web import protocols as pv_protocols
|
||||
|
||||
# Make sure ParaView is initialized
|
||||
if not simple.servermanager.ActiveConnection:
|
||||
simple.Connect()
|
||||
|
||||
if not IPythonProtocol.producer:
|
||||
IPythonProtocol.producer = simple.DistributedTrivialProducer()
|
||||
IPythonProtocol.ActivateDataSet('iPython-demo')
|
||||
simple.Show(IPythonProtocol.producer)
|
||||
simple.Render()
|
||||
|
||||
# Bring used components
|
||||
self.registerVtkWebProtocol(pv_protocols.ParaViewWebFileListing(IPythonProtocol.dataDir, "Home", IPythonProtocol.excludeRegex, IPythonProtocol.groupRegex))
|
||||
self.registerVtkWebProtocol(pv_protocols.ParaViewWebPipelineManager(IPythonProtocol.dataDir, IPythonProtocol.fileToLoad))
|
||||
self.registerVtkWebProtocol(pv_protocols.ParaViewWebMouseHandler())
|
||||
self.registerVtkWebProtocol(pv_protocols.ParaViewWebViewPort())
|
||||
self.registerVtkWebProtocol(pv_protocols.ParaViewWebViewPortImageDelivery())
|
||||
self.registerVtkWebProtocol(pv_protocols.ParaViewWebViewPortGeometryDelivery())
|
||||
self.registerVtkWebProtocol(pv_protocols.ParaViewWebTimeHandler())
|
||||
self.registerVtkWebProtocol(pv_protocols.ParaViewWebRemoteConnection())
|
||||
self.registerVtkWebProtocol(pv_protocols.ParaViewWebFileManager(IPythonProtocol.dataDir))
|
||||
|
||||
# Update authentication key to use
|
||||
self.updateSecret(IPythonProtocol.authKey)
|
||||
|
||||
def __str__(self):
|
||||
return "Root node: " + str(IPythonProtocol.rootNode)
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# ParaView iPython default arguments
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
class WebArguments(object):
|
||||
|
||||
def __init__(self, webDir = None):
|
||||
self.content = webDir
|
||||
self.port = 8080
|
||||
self.host = 'localhost'
|
||||
self.debug = 0
|
||||
self.timeout = 120
|
||||
self.nosignalhandlers = True
|
||||
self.authKey = 'vtkweb-secret'
|
||||
self.uploadDir = ""
|
||||
self.testScriptPath = ""
|
||||
self.baselineImgDir = ""
|
||||
self.useBrowser = ""
|
||||
self.tmpDirectory = ""
|
||||
self.testImgFile = ""
|
||||
self.forceFlush = False
|
||||
self.dataDir = '.'
|
||||
self.groupRegex = "[0-9]+\\."
|
||||
self.excludeRegex = "^\\.|~$|^\\$"
|
||||
self.fileToLoad = None
|
||||
|
||||
|
||||
def __str__(self):
|
||||
return "http://%s:%d/%s" % (self.host, self.port, self.content)
|
||||
2802
ParaView-5.0.1/Web/Python/paraview/web/protocols.py
Normal file
2802
ParaView-5.0.1/Web/Python/paraview/web/protocols.py
Normal file
File diff suppressed because it is too large
Load Diff
258
ParaView-5.0.1/Web/Python/paraview/web/pv_web_catalyst.py
Normal file
258
ParaView-5.0.1/Web/Python/paraview/web/pv_web_catalyst.py
Normal file
@ -0,0 +1,258 @@
|
||||
r"""
|
||||
This module is a ParaViewWeb server application.
|
||||
The following command line illustrate how to use it::
|
||||
|
||||
$ pvpython .../pv_web_catalyst.py --data-dir /.../path-to-your-data-directory
|
||||
|
||||
--data-dir is used to list that directory on the server and let the client choose a file to load.
|
||||
|
||||
Any ParaViewWeb executable script come with a set of standard arguments that
|
||||
can be overriden if need be::
|
||||
|
||||
--port 8080
|
||||
Port number on which the HTTP server will listen to.
|
||||
|
||||
--content /path-to-web-content/
|
||||
Directory that you want to server as static web content.
|
||||
By default, this variable is empty which mean that we rely on another server
|
||||
to deliver the static content and the current process only focus on the
|
||||
WebSocket connectivity of clients.
|
||||
|
||||
--authKey vtkweb-secret
|
||||
Secret key that should be provided by the client to allow it to make any
|
||||
WebSocket communication. The client will assume if none is given that the
|
||||
server expect "vtkweb-secret" as secret key.
|
||||
|
||||
"""
|
||||
|
||||
# import to process args
|
||||
import os
|
||||
import math
|
||||
|
||||
# import paraview modules.
|
||||
import paraview
|
||||
# for 4.1 compatibility till we fix ColorArrayName and ColorAttributeType usage.
|
||||
paraview.compatibility.major = 4
|
||||
paraview.compatibility.minor = 1
|
||||
from paraview import simple
|
||||
from paraview.web import wamp as pv_wamp
|
||||
from paraview.web import protocols as pv_protocols
|
||||
|
||||
from vtk.web import server
|
||||
|
||||
try:
|
||||
import argparse
|
||||
except ImportError:
|
||||
# since Python 2.6 and earlier don't have argparse, we simply provide
|
||||
# the source for the same as _argparse and we use it instead.
|
||||
from vtk.util import _argparse as argparse
|
||||
|
||||
# import annotations
|
||||
from autobahn.wamp import register as exportRpc
|
||||
|
||||
# =============================================================================
|
||||
# Handle function helpers
|
||||
# =============================================================================
|
||||
|
||||
def convert_to_float(v):
|
||||
return float(v)
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
def convert_to_float_array(v):
|
||||
return [ float(v) ]
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
def update_property(handle, value):
|
||||
property = handle['proxy'].GetProperty(handle['property'])
|
||||
if handle.has_key('convert'):
|
||||
property.SetData( handle['convert'](value) )
|
||||
else:
|
||||
property.SetData( value )
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
def create_property_handle(proxy, property_name, convert = None):
|
||||
handle = { 'proxy': proxy, 'property': property_name, 'update': update_property }
|
||||
if convert:
|
||||
handle['convert'] = convert
|
||||
return handle
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
def update_representation(handle, value):
|
||||
proxy = handle['proxy']
|
||||
if handle['color_list'].has_key(value):
|
||||
for propName in handle['color_list'][value]:
|
||||
prop = proxy.GetProperty(propName)
|
||||
if prop != None:
|
||||
prop.SetData(handle['color_list'][value][propName])
|
||||
|
||||
if handle.has_key('override_location'):
|
||||
proxy.ColorAttributeType = handle['override_location']
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
def create_representation_handle(representation_proxy, colorByList, array_location = None):
|
||||
handle = { 'proxy': representation_proxy, 'color_list': colorByList, 'update': update_representation }
|
||||
if array_location:
|
||||
handle['override_location'] = array_location
|
||||
return handle
|
||||
|
||||
# =============================================================================
|
||||
# Define a pipeline object
|
||||
# =============================================================================
|
||||
|
||||
class CatalystBasePipeline(object):
|
||||
|
||||
def __init__(self):
|
||||
self.field_data = {}
|
||||
self.handles = {}
|
||||
self.metadata = {}
|
||||
|
||||
def apply_pipeline(self, input_data, time_steps):
|
||||
'''
|
||||
Method called when data to process is ready
|
||||
'''
|
||||
self.metadata['time'] = { "default": time_steps[0], "type": "range", "values": time_steps, "label": "time", "priority": 0 }
|
||||
|
||||
def add_key(self, key, default_value, data_type, values, label, priority, handles):
|
||||
self.handles[key] = handles
|
||||
self.metadata[key] = {
|
||||
"default": default_value,
|
||||
"type": data_type,
|
||||
"values": values,
|
||||
"label": label,
|
||||
"priority": priority
|
||||
}
|
||||
|
||||
def register_data(self, fieldName, location, scalarRange, lutType):
|
||||
self.field_data[fieldName] = {
|
||||
"ColorArrayName": (location, fieldName),
|
||||
"Range": scalarRange,
|
||||
"LookupTable": self._create_lookup_table(fieldName, scalarRange, lutType),
|
||||
"ScalarOpacityFunction": self._create_piecewise_function(scalarRange)
|
||||
}
|
||||
|
||||
def update_argument(self, key, value):
|
||||
for handle in self.handles[key]:
|
||||
handle['update'](handle, value)
|
||||
|
||||
def get_metadata(self):
|
||||
return self.metadata
|
||||
|
||||
def _create_data_values(self, scalarRange, number_of_values):
|
||||
inc = float(scalarRange[1]-scalarRange[0]) / float(number_of_values)
|
||||
values = []
|
||||
for i in range(number_of_values+1):
|
||||
values.append(float(scalarRange[0] + (float(i)*inc) ))
|
||||
return values
|
||||
|
||||
def _create_lookup_table(self, name, scalarRange, lutType):
|
||||
if lutType == 'blueToRed':
|
||||
return simple.GetLookupTableForArray( name, 1, RGBPoints=[scalarRange[0], 0.231373, 0.298039, 0.752941, (scalarRange[0]+scalarRange[1])/2, 0.865003, 0.865003, 0.865003, scalarRange[1], 0.705882, 0.0156863, 0.14902], VectorMode='Magnitude', NanColor=[0.0, 0.0, 0.0], ColorSpace='Diverging', ScalarRangeInitialized=1.0, LockScalarRange=1)
|
||||
else:
|
||||
return simple.GetLookupTableForArray( name, 1, RGBPoints=[scalarRange[0], 0.0, 0.0, 1.0, scalarRange[1], 1.0, 0.0, 0.0], VectorMode='Magnitude', NanColor=[0.0, 0.0, 0.0], ColorSpace='HSV', ScalarRangeInitialized=1.0, LockScalarRange=1)
|
||||
|
||||
def _create_piecewise_function(self, scalarRange):
|
||||
return simple.CreatePiecewiseFunction( Points=[scalarRange[0], 0.0, 0.5, 0.0, scalarRange[1], 1.0, 0.5, 0.0] )
|
||||
|
||||
# =============================================================================
|
||||
# Create custom Catalyst Pipeline Manager class to handle clients requests
|
||||
# =============================================================================
|
||||
|
||||
class _PVCatalystManager(pv_wamp.PVServerProtocol):
|
||||
|
||||
dataDir = None
|
||||
authKey = "vtkweb-secret"
|
||||
plugins = None
|
||||
pipeline_handler = None
|
||||
|
||||
@staticmethod
|
||||
def add_arguments(parser):
|
||||
parser.add_argument("--data-dir", default=os.getcwd(), help="path to data directory to list", dest="path")
|
||||
parser.add_argument("--plugins", default="", help="List of fully qualified path names to plugin objects to load", dest="plugins")
|
||||
|
||||
@staticmethod
|
||||
def configure(args):
|
||||
_PVCatalystManager.authKey = args.authKey
|
||||
_PVCatalystManager.dataDir = args.path
|
||||
_PVCatalystManager.plugins = args.plugins
|
||||
|
||||
def initialize(self):
|
||||
# Bring used components
|
||||
self.registerVtkWebProtocol(pv_protocols.ParaViewWebStartupPluginLoader(_PVCatalystManager.plugins))
|
||||
self.registerVtkWebProtocol(pv_protocols.ParaViewWebMouseHandler())
|
||||
self.registerVtkWebProtocol(pv_protocols.ParaViewWebViewPort())
|
||||
self.registerVtkWebProtocol(pv_protocols.ParaViewWebViewPortImageDelivery())
|
||||
self.registerVtkWebProtocol(pv_protocols.ParaViewWebViewPortGeometryDelivery())
|
||||
|
||||
# Update authentication key to use
|
||||
self.updateSecret(_PVCatalystManager.authKey)
|
||||
|
||||
view = simple.GetRenderView()
|
||||
view.Background = [1,1,1]
|
||||
|
||||
@exportRpc("catalyst.file.open")
|
||||
def openFileFromPath(self, files):
|
||||
fileToLoad = []
|
||||
number_of_time_steps = 1
|
||||
if type(files) == list:
|
||||
number_of_time_steps = len(files)
|
||||
for file in files:
|
||||
fileToLoad.append(os.path.join(_PVCatalystManager.dataDir, file))
|
||||
else:
|
||||
fileToLoad.append(os.path.join(_PVCatalystManager.dataDir, files))
|
||||
self.time_steps = [ i for i in range(number_of_time_steps)]
|
||||
reader = simple.OpenDataFile(fileToLoad)
|
||||
if _PVCatalystManager.pipeline_handler:
|
||||
_PVCatalystManager.pipeline_handler.apply_pipeline(reader, self.time_steps)
|
||||
|
||||
@exportRpc("catalyst.pipeline.initialize")
|
||||
def initializePipeline(self, conf):
|
||||
if _PVCatalystManager.pipeline_handler and "initialize_pipeline" in dir(_PVCatalystManager.pipeline_handler):
|
||||
_PVCatalystManager.pipeline_handler.initialize_pipeline(conf)
|
||||
|
||||
|
||||
@exportRpc("catalyst.active.argument.update")
|
||||
def updateActiveArgument(self, key, value):
|
||||
if key == "time":
|
||||
simple.GetAnimationScene().TimeKeeper.Time = float(value)
|
||||
elif _PVCatalystManager.pipeline_handler:
|
||||
_PVCatalystManager.pipeline_handler.update_argument(key, value)
|
||||
|
||||
|
||||
@exportRpc("catalyst.arguments.get")
|
||||
def getArguments(self):
|
||||
if _PVCatalystManager.pipeline_handler:
|
||||
return _PVCatalystManager.pipeline_handler.get_metadata()
|
||||
else:
|
||||
return { "time": {
|
||||
"default": "0",
|
||||
"type": "range",
|
||||
"values": self.time_steps,
|
||||
"label": "time",
|
||||
"priority": 0 } }
|
||||
|
||||
# =============================================================================
|
||||
# Main: Parse args and start server
|
||||
# =============================================================================
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Create argument parser
|
||||
parser = argparse.ArgumentParser(description="ParaView/Web Pipeline Manager web-application")
|
||||
|
||||
# Add arguments
|
||||
server.add_arguments(parser)
|
||||
_PVCatalystManager.add_arguments(parser)
|
||||
|
||||
# Exctract arguments
|
||||
args = parser.parse_args()
|
||||
|
||||
# Configure our current application
|
||||
_PVCatalystManager.configure(args)
|
||||
|
||||
# Start server
|
||||
server.start_webserver(options=args, protocol=_PVCatalystManager)
|
||||
18
ParaView-5.0.1/Web/Python/paraview/web/wamp.py
Normal file
18
ParaView-5.0.1/Web/Python/paraview/web/wamp.py
Normal file
@ -0,0 +1,18 @@
|
||||
r"""paraviewweb_wamp is the paraview-specific subclass
|
||||
of vtkweb_wamp that provides the PVWeb Application
|
||||
"""
|
||||
|
||||
from vtk.web import wamp
|
||||
from vtkParaViewWebCorePython import vtkPVWebApplication
|
||||
|
||||
from paraview.web import protocols as pv_protocols
|
||||
|
||||
class PVServerProtocol(wamp.ServerProtocol):
|
||||
|
||||
def __init__(self, config):
|
||||
wamp.ServerProtocol.__init__(self, config)
|
||||
wamp.imageCapture = pv_protocols.ParaViewWebViewPortImageDelivery()
|
||||
wamp.imageCapture.setApplication(self.Application)
|
||||
|
||||
def initApplication(self):
|
||||
return vtkPVWebApplication()
|
||||
156
ParaView-5.0.1/Web/Python/paraview/web/webgl.py
Normal file
156
ParaView-5.0.1/Web/Python/paraview/web/webgl.py
Normal file
@ -0,0 +1,156 @@
|
||||
r"""
|
||||
This module provides classes to handle Rest API for WebGL piece request.
|
||||
|
||||
This module is now deprecated.
|
||||
"""
|
||||
|
||||
from twisted.web import server, resource
|
||||
from twisted.web import server, resource
|
||||
from twisted.web.error import Error
|
||||
|
||||
from paraview import simple
|
||||
from paraview.web import helper
|
||||
from vtkParaViewWebCorePython import vtkPVWebApplication
|
||||
|
||||
import exceptions
|
||||
import base64
|
||||
|
||||
pv_web_app = vtkPVWebApplication()
|
||||
|
||||
class WebGLResource(resource.Resource):
|
||||
"""
|
||||
Resource using to serve WebGL data. If supports URLs of two forms:
|
||||
- to get the meta-data as json-rpc message:
|
||||
http://.../WebGL?q=meta&vid=456
|
||||
|
||||
- to get a binary webgl object:
|
||||
http://.../WebGL?q=mesh&vid=456&id=1&part=0
|
||||
|
||||
vid : visualization view ID (GlobalID of the view Proxy)
|
||||
id : id of the object in the scene
|
||||
part: WebGL has a size limit, therefore an object can be splitted in
|
||||
several part. This is the part index.
|
||||
"""
|
||||
def _missing_parameter(self, parameter):
|
||||
raise Error(400, "Missing required parameter: %s" % parameter)
|
||||
|
||||
def _get_parameter(self, args, parameter, required=True):
|
||||
"""
|
||||
Extract a parameter value from the request args.
|
||||
:param parameter: The parameter name
|
||||
:type parameter: str
|
||||
:param required: True if the function should raise an error is the
|
||||
parameter is missing.
|
||||
:type required: bool
|
||||
"""
|
||||
value = None
|
||||
|
||||
if not parameter in args:
|
||||
if required:
|
||||
self._missing_parameter(parameter)
|
||||
else:
|
||||
values = args[parameter]
|
||||
if len(values) == 1:
|
||||
value = values[0]
|
||||
elif required:
|
||||
self._missing_parameter(parameter)
|
||||
|
||||
return value
|
||||
|
||||
def _get_view(self, vid):
|
||||
"""
|
||||
Returns the view for a given view ID, if vid is None then return the
|
||||
current active view.
|
||||
:param vid: The view ID
|
||||
:type vid: str
|
||||
"""
|
||||
def _get_active_view():
|
||||
view = simple.GetActiveView()
|
||||
if not view:
|
||||
raise Error(404, "No view provided to WebGL resource")
|
||||
return view
|
||||
|
||||
view = None
|
||||
|
||||
if vid:
|
||||
try:
|
||||
view = helper.mapIdToProxy(vid)
|
||||
except exceptions.TypeError:
|
||||
pass
|
||||
|
||||
if not view:
|
||||
view = _get_active_view()
|
||||
|
||||
return view
|
||||
|
||||
def _render_GET_mesh(self, vid, request):
|
||||
"""
|
||||
Handle GET requests to get WebGL data for a particular object.
|
||||
"""
|
||||
object_id = self._get_parameter(request.args, 'id')
|
||||
part_number = self._get_parameter(request.args, 'part', False);
|
||||
|
||||
part = 0
|
||||
if part_number:
|
||||
part = int(part_number)
|
||||
|
||||
view = self._get_view(vid)
|
||||
|
||||
# There part is offset by 1
|
||||
if part > 0:
|
||||
part = part - 1
|
||||
|
||||
data = pv_web_app.GetWebGLBinaryData(view.SMProxy, object_id, part);
|
||||
|
||||
if data:
|
||||
request.setHeader('content-type', 'application/octet-stream+webgl')
|
||||
request.setHeader('Cache-Control', 'max-age=99999');
|
||||
data = base64.b64decode(data)
|
||||
else:
|
||||
raise Error(404, "Invalid request for WebGL object")
|
||||
|
||||
return data
|
||||
|
||||
def _render_GET_meta(self, vid, request):
|
||||
"""
|
||||
Handle GET request for meta data.
|
||||
"""
|
||||
view = self._get_view(vid)
|
||||
|
||||
data = pv_web_app.GetWebGLSceneMetaData(view.SMProxy)
|
||||
|
||||
if data:
|
||||
request.setHeader('content-type', 'application/json')
|
||||
else:
|
||||
raise Error(404, "Invalid request for WebGL meta data")
|
||||
|
||||
return data
|
||||
|
||||
def render_GET(self, request):
|
||||
"""
|
||||
Handle GET requests, parse out q parameter to delegate to the correct
|
||||
internal function.
|
||||
There is two types of queries allowed:
|
||||
- to get the meta-data as json-rpc message:
|
||||
http://.../WebGL?q=meta&vid=456
|
||||
|
||||
- to get a binary webgl object:
|
||||
http://.../WebGL?q=mesh&vid=456&id=1&part=0
|
||||
|
||||
vid : visualization view ID (GlobalID of the view Proxy)
|
||||
id : id of the object in the scene
|
||||
part: WebGL has a size limit, therefore an object can be splitted in several part. This is the part index.
|
||||
"""
|
||||
try:
|
||||
q = self._get_parameter(request.args, 'q')
|
||||
vid = self._get_parameter(request.args, 'vid', False)
|
||||
|
||||
if q == 'mesh':
|
||||
return self._render_GET_mesh(vid, request)
|
||||
elif q == 'meta':
|
||||
return self._render_GET_meta(vid, request)
|
||||
else:
|
||||
raise Error(400, "Invalid query for the WebGL resource");
|
||||
except Error as err:
|
||||
request.setResponseCode(err.status)
|
||||
return err.message
|
||||
Reference in New Issue
Block a user