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 |