Programmable Filter2015年12月17日 | |
はじめにProgrammable Filter の使い方について。 使用バージョンParaView 4.4.0 Programmable Filter とはProgrammable Filter は、Python でフィルターを作ることができるものである。 簡単な例たとえば、"temperature" というケルビン単位の温度データがあったとして、それを摂氏に変換するフィルターを作るとしたら、次のようになる。 input = inputs[0] data = input.PointData['temperature'] - 273.15 output.PointData.append(data, 'temperature_degC') この書き方は、既存のデータに値を足したり掛けたりするときに使うことができるが、その場合は Calculator のほうが簡単に済むだろう。 ※そもそもこの方法が使えない場合がある。理由は知らない。 複雑な例複雑な例、たとえば、あるデータの値に対して場合分けをして新たなデータを生成したりするような、式だけでは表現できないような例では、上記の方法では難しい。 入力のコピー複雑な例を実現する方法を示す前に、まず、入力を出力にコピーするだけの方法を以下に示す。 input = self.GetInputDataObject(0, 0) output = self.GetOutputDataObject(0) output.ShallowCopy(input) 入力と同じデータを見ることができたら OK。 ブロックごとのコピーMulti-Block データセットの場合、データはブロックに分かれている (データセットの種類は "Information" タブで確認できる)。ブロックを巡回してコピーする場合は、次のように書ける。
input = self.GetInputDataObject(0, 0)
output = self.GetOutputDataObject(0)
numBlocks = input.GetNumberOfBlocks()
for i in range(numBlocks):
block = input.GetBlock(i)
newBlock = block.NewInstance()
newBlock.CopyStructure(block)
output.SetBlock(i, newBlock)
newBlock.ShallowCopy(block)
イテレータを用いると、同じ処理を次のようにも書ける。
input = self.GetInputDataObject(0, 0)
output = self.GetOutputDataObject(0)
output.CopyStructure(input)
iter = input.NewIterator()
iter.UnRegister(None)
iter.InitTraversal()
while not iter.IsDoneWithTraversal():
curInput = iter.GetCurrentDataObject()
curOutput = curInput.NewInstance()
curOutput.UnRegister(None)
output.SetDataSet(iter, curOutput)
curOutput.ShallowCopy(curInput)
iter.GoToNextItem()
温度変換の例上記の方法を用いると、温度変換は次のようになる。
input = self.GetInputDataObject(0, 0)
output = self.GetOutputDataObject(0)
output.CopyStructure(input)
numBlocks = input.GetNumberOfBlocks()
for i in range(numBlocks):
block = input.GetBlock(i)
newBlock = block.NewInstance()
newBlock.CopyStructure(block)
output.SetBlock(i, newBlock)
newBlock.ShallowCopy(block)
data = block.GetPointData().GetArray('temperature')
numTuples = data.GetNumberOfTuples()
newData = vtk.vtkFloatArray()
newData.SetNumberOfTuples(numTuples)
newData.SetName('temperature_degC')
for j in range(numTuples):
newData.SetValue(j, data.GetValue(j) - 273.15)
newBlock.GetPointData().AddArray(newData)
ブロックのコピーの後に、温度変換データを作成してブロックに追加している。 イテレータ版は次の通りである。
input = self.GetInputDataObject(0, 0)
output = self.GetOutputDataObject(0)
output.CopyStructure(input)
iter = input.NewIterator()
iter.UnRegister(None)
iter.InitTraversal()
while not iter.IsDoneWithTraversal():
curInput = iter.GetCurrentDataObject()
curOutput = curInput.NewInstance()
curOutput.UnRegister(None)
output.SetDataSet(iter, curOutput)
curOutput.ShallowCopy(curInput)
data = curInput.GetPointData().GetArray('temperature')
numTuples = data.GetNumberOfTuples()
newData = vtk.vtkFloatArray()
newData.SetNumberOfTuples(numTuples)
newData.SetName('temperature_degC')
for i in range(numTuples):
newData.SetValue(i, data.GetValue(i) - 273.15)
curOutput.GetPointData().AddArray(newData)
iter.GoToNextItem()
Multi-Block とそうでないものと両方のデータに対応するには、次のように書けばよいらしい。
def calc(input, output):
output.ShallowCopy(input)
data = input.GetPointData().GetArray('temperature')
numTuples = data.GetNumberOfTuples()
newData = vtk.vtkFloatArray()
newData.SetNumberOfTuples(numTuples)
newData.SetName('temperature_degC')
for i in range(numTuples):
newData.SetValue(i, data.GetValue(i) - 273.15)
output.GetPointData().AddArray(newData)
input = self.GetInputDataObject(0, 0)
output = self.GetOutputDataObject(0)
if input.IsA('vtkMultiBlockDataSet'):
output.CopyStructure(input)
iter = input.NewIterator()
iter.UnRegister(None)
iter.InitTraversal()
while not iter.IsDoneWithTraversal():
curInput = iter.GetCurrentDataObject()
curOutput = curInput.NewInstance()
curOutput.UnRegister(None)
output.SetDataSet(iter, curOutput)
calc(curInput, curOutput)
iter.GoToNextItem()
else:
calc(input, output)
参考 | |
| PENGUINITIS | |