I’ve created a python plugin that acts as a source with two vtkPolyData outputs (spheres). The source is called “CR3BP System” and inherits the VTKPythonAlgorithmBase class
class PythonCR3BPSystemSource(VTKPythonAlgorithmBase):
I’ve added a slider bar to the GUI for a parameter “mu” that determines the placement of the two spheres. I would like to create another source called “CR3BP Traj” that reads in the “mu” parameter from the CR3BP system. How can I go about doing this?
My first idea is to create a filter with one input and define the expected input as the “CR3BP System”. I’m not sure how to do this.
Here’s my current code for the"CR3BP System" object
from vtkmodules.vtkCommonDataModel import vtkDataSet
from vtkmodules.util.vtkAlgorithm import VTKPythonAlgorithmBase
from vtkmodules.numpy_interface import dataset_adapter as dsa
from paraview.util.vtkAlgorithm import smproxy , smproperty , smdomain
import numpy as np
# mu = 1
# to add a source, instead of a filter, use the ‘smproxy.source‘ decorator.
@smproxy.source(label="CR3BP System")
class PythonCR3BPSystemSource(VTKPythonAlgorithmBase):
def __init__(self):
VTKPythonAlgorithmBase.__init__(self,
nInputPorts=0,
nOutputPorts=2,
outputType='vtkPolyData')
from vtkmodules.vtkFiltersSources import vtkSphereSource
self.prim = vtkSphereSource()
self.prim.SetThetaResolution(20)
self.prim.SetPhiResolution(20)
self.prim.SetStartTheta(1e-5)
self.sec = vtkSphereSource()
self.sec.SetThetaResolution(20)
self.sec.SetPhiResolution(20)
self.sec.SetStartTheta(1e-5)
def RequestData(self, request , inInfo , outInfo):
from vtkmodules.vtkCommonDataModel import vtkPolyData
self.prim.Update()
self.sec.Update()
output0 = vtkPolyData.GetData(outInfo , 0)
output0.ShallowCopy(self.prim.GetOutput())
output1 = vtkPolyData.GetData(outInfo , 1)
output1.ShallowCopy(self.sec.GetOutput())
return 1
@smproperty.doublevector(name="mu", default_values=2.528017682687079e-05)
@smdomain.doublerange(min=0, max=0.5)
def SetMu(self, mu):
self.mu = mu
self.sec.SetCenter(1-mu,0,0)
self.prim.SetCenter(-mu,0,0)
self.Modified()
@smproperty.doublevector(name="R1", default_values=0.1041737445984205)
def SetPrimRadius(self, R1):
self.prim.SetRadius(R1)
self.Modified()
@smproperty.doublevector(name="R2", default_values=0.0023257338697660556)
def SetSecRadius(self, R2):
self.sec.SetRadius(R2)
self.Modified()
Thanks! That works for me. I’ve attached my code change below.
def RequestData(self, request , inInfo , outInfo):
from vtkmodules.vtkCommonDataModel import vtkPolyData, vtkFieldData
from vtkmodules.vtkCommonCore import vtkDoubleArray
# from vtkmodules.vtkCommonDataModel import *
data = vtkDoubleArray()
data.SetNumberOfComponents(1)
data.SetNumberOfTuples(1)
data.SetName("mu")
data.SetComponent(0,0,42)
field = vtkFieldData()
field.AddArray(data)
self.prim.Update()
self.sec.Update()
output0 = vtkPolyData.GetData(outInfo , 0)
output0.ShallowCopy(self.prim.GetOutput())
output0.SetFieldData(field)
As a followup question, this field data is assigned to one of the sphere objects, not the CR3BPSystem object. Could I add the fielddata to the CR3BPSystem object and have that be the input to my filter? I’m going to have other parameters associated with both spheres that I want to pass on.
OK, my MultiBlockDataSet looks great. I can animate the spheres moving around each other.
Now I would like to create a new source that reads in the FieldData and outputs a new PolyLineSource(). I’m getting stuck reading in the MultiBlockDataSet.
I’ve tried creating the following source from the example filter that keeps the input type
from vtkmodules.vtkCommonDataModel import vtkDataSet
from vtkmodules.util.vtkAlgorithm import VTKPythonAlgorithmBase
from vtkmodules.numpy_interface import dataset_adapter as dsa
from paraview.util.vtkAlgorithm import smproxy , smproperty , smdomain
import numpy as np
@smproxy.source(label="CR3BP Traj")
@smproperty.input(name="Input")
@smdomain.datatype(dataTypes=["vtkMultiBlockDataSet"], composite_data_supported=True)
class PreserveInputTypeFilter(VTKPythonAlgorithmBase):
"""
Example filter demonstrating how to write a filter that preserves the input
dataset type.
"""
def __init__(self):
VTKPythonAlgorithmBase.__init__(self,
nInputPorts=1,
nOutputPorts=1,
outputType='vtkMultiBlockDataSet')
def RequestData(self, request, inInfo, outInfo):
input0 = dsa.WrapDataObject(vtkDataSet.GetData(inInfo[0]))
inData = self.GetInputData(inInfo, 0, 0)
outData = self.GetOutputData(outInfo, 0)
print("input type =", inData.GetClassName())
print("output type =", outData.GetClassName())
assert outData.IsA(inData.GetClassName())
return 1
I create a CR3BPSystem object, select it, then try to create this CR3BPTraj object. I get the following errors
Input port 0 of algorithm vtkPythonAlgorithm(0x9a3b240) has 0 connections but is not optional.
ERROR: In /home/buildslave/dashboards/buildbot/paraview-pvbinsdash-linux-shared-release_superbuild/build/superbuild/paraview/src/VTK/Common/ExecutionModel/vtkDemandDrivenPipeline.cxx, line 668
vtkPVCompositeDataPipeline (0x9ed5260): Input port 0 of algorithm vtkPythonAlgorithm(0x9a3b240) has 0 connections but is not optional.
Algorithm vtkPVGeometryFilter(0xbd369c0) returned failure for request: vtkInformation (0xbd344b0) Debug: Off Modified Time: 1792682 Reference Count: 1 Registered Events: (none) Request: REQUEST_DATA_OBJECT FROM_OUTPUT_PORT: 0 ALGORITHM_AFTER_FORWARD: 1 FORWARD_DIRECTION: 0
ERROR: In /home/buildslave/dashboards/buildbot/paraview-pvbinsdash-linux-shared-release_superbuild/build/superbuild/paraview/src/VTK/Common/ExecutionModel/vtkExecutive.cxx, line 753
vtkCompositeDataPipeline (0xc006ce0): Algorithm vtkPVGeometryFilter(0xbd369c0) returned failure for request: vtkInformation (0xbd344b0)
Debug: Off
Modified Time: 1792682
Reference Count: 1
Registered Events: (none)
Request: REQUEST_DATA_OBJECT
FROM_OUTPUT_PORT: 0
ALGORITHM_AFTER_FORWARD: 1
FORWARD_DIRECTION: 0
I’m still getting the same error. I’ve pared down my code to the bare minimum.
from vtkmodules.vtkCommonDataModel import vtkDataSet
from vtkmodules.util.vtkAlgorithm import VTKPythonAlgorithmBase
from vtkmodules.numpy_interface import dataset_adapter as dsa
from paraview.util.vtkAlgorithm import smproxy , smproperty , smdomain
import numpy as np
@smproxy.source(label="CR3BP Traj")
@smproperty.input(name="Input")
# @smdomain.datatype(dataTypes=["vtkMultiBlockDataSet"], composite_data_supported=True)
class PythonCR3BPTrajSource(VTKPythonAlgorithmBase):
def __init__(self):
VTKPythonAlgorithmBase.__init__(self,
nInputPorts=1,
inputType='vtkMultiBlockDataSet',
nOutputPorts=1,
outputType='vtkMultiBlockDataSet')
def RequestData(self, request, inInfo, outInfo):
input0 = vtkMultiBlockDataSet.GetData(inInfo[0])
input1 = dsa.WrapDataObject(vtkMultiBlockDataSet.GetData(inInfo[0]))
input2 = self.GetInputData(inInfo, 0, 0)
return 1
Input port 0 of algorithm vtkPythonAlgorithm(0x7f1454010af0) has 0 connections but is not optional.
ERROR: In /home/buildslave/dashboards/buildbot/paraview-pvbinsdash-linux-shared-release_superbuild/build/superbuild/paraview/src/VTK/Common/ExecutionModel/vtkDemandDrivenPipeline.cxx, line 668
vtkPVCompositeDataPipeline (0xa2cbc90): Input port 0 of algorithm vtkPythonAlgorithm(0x7f1454010af0) has 0 connections but is not optional.