2017-11-18 26 views
1

私は有限要素解析結果を扱うためにC++でVTKプログラムを書いています。等値面を表示するには、vtkContourFilterを試していますが、このフィルタの後には何も表示されません。私のvtkContourFilterに出力がないのはなぜですか?

私は単純なバージョンを書いています。カスタムリーダーは2セルの非構造メッシュを生成し、次のvtkContourFilterは等値面を抽出します。スカラーデータはポイントデータです。

私は等値面を取得しようとしていますが、それでも出力はゼロです。私は逃したものを知りたい。

私のプログラム:

#include <vtkSmartPointer.h> 
#include <vtkUnstructuredGrid.h> 
#include <vtkPoints.h> 
#include <vtkPointData.h> 
#include <vtkCellArray.h> 
#include <vtkIdList.h> 
#include <vtkDoubleArray.h> 
#include <vtkPointData.h> 
#include <vtkUnstructuredGridReader.h> 
#include <vtkInformation.h> 
#include <vtkInformationVector.h> 
#include <vtkClipDataSet.h> 
#include <vtkPlane.h> 
#include <vtkContourFilter.h> 
#include <iostream> 
using namespace std; 

// This is a fake reader that outputs an unstructured mesh 
class VTKIOLEGACY_EXPORT FakeUnstructuredGridReader : public vtkUnstructuredGridReader { 
public: 
    static FakeUnstructuredGridReader* New() { return new FakeUnstructuredGridReader(); } 
    vtkTypeMacro(FakeUnstructuredGridReader, vtkUnstructuredGridReader); 
    void PrintSelf(ostream& os, vtkIndent indent) VTK_OVERRIDE {} 

protected: 
    FakeUnstructuredGridReader() { this->SetNumberOfInputPorts(0); }// No input ports 
    // This method passes a 2-cell unstructured grid with 1 set of scalar point data 
    int RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector* outputVector) VTK_OVERRIDE { 
     static const double rawPoints[15] = { 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1 }; 
     static const vtkIdType rawIndices[8] = { 0, 1, 2, 3, 1, 2, 3, 4}; 
     static const double rawScalar[5] = { 5, 10, 20, 15, 50 }; 
     static const char* scalarName = "Stress"; 
     // Build Points 
     auto points = vtkSmartPointer<vtkPoints>::New(); 
     for (int i = 0; i < 15; i += 3) 
      points->InsertNextPoint(rawPoints + i); 
     // Build Cells 
     auto cells = vtkSmartPointer<vtkCellArray>::New(); 
     // Build Cell 1 
     auto indices1 = vtkSmartPointer<vtkIdList>::New(); 
     for (int i = 0; i < 4; ++i) 
      indices1->InsertNextId(rawIndices[i]);  
     cells->InsertNextCell(indices1); 
     // Build Cell 2 
     auto indices2 = vtkSmartPointer<vtkIdList>::New(); 
     for (int i = 0; i < 4; ++i) 
      indices2->InsertNextId(rawIndices[i + 4]); 
     cells->InsertNextCell(indices2); 
     // Scalar Data 
     auto dataArray = vtkSmartPointer<vtkDoubleArray>::New(); 
     dataArray->SetName(scalarName); 
     dataArray->SetNumberOfComponents(1); 
     for (int i = 0; i < 5; ++i) 
      dataArray->InsertNextValue(rawScalar[i]); 
     // Point Data 
     auto pointData = vtkSmartPointer<vtkPointData>::New(); 
     pointData->AddArray(dataArray); 
     // Pass Data 
     vtkInformation* outInfo = outputVector->GetInformationObject(0); 
     vtkUnstructuredGrid *output = vtkUnstructuredGrid::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())); 
     output->SetPoints(points); 
     output->SetCells(VTK_TETRA, cells); 
     output->SetFieldData(pointData); 
     return 1; 
    } 
}; 


int main() { 
    // Reader 
    auto fakeReader = vtkSmartPointer<FakeUnstructuredGridReader>::New(); 

    // Isosurface Filter 
    auto isoFilter = vtkSmartPointer<vtkContourFilter>::New(); 
    isoFilter->SetInputConnection(fakeReader->GetOutputPort()); 
    isoFilter->GenerateValues(8, 0.0, 50.0); 
    isoFilter->Update(); 

    cout << fakeReader->GetOutput()->GetNumberOfPoints() << endl; 
    cout << fakeReader->GetOutput()->GetNumberOfCells() << endl; 
    cout << fakeReader->GetOutput()->GetFieldData()->GetNumberOfArrays() << endl; 
    cout << isoFilter->GetOutput()->GetNumberOfPoints() << endl; 
    cout << isoFilter->GetOutput()->GetNumberOfCells() << endl; 
    cout << isoFilter->GetOutput()->GetFieldData()->GetNumberOfArrays() << endl; 

    system("pause"); 
    return 0; 
} 

その出力:RequestData()はあなたがスカラー場を作るoutput->GetPointData()->AddArray(dataArray)で設定したデータのポイントにスカラー値を関連付けるために最初に必要な機能で

5 
2 
1 
0 
0 
1 

答えて

1

output->GetPointData()->SetActiveScalars(scalarName)でアクティブにして、vtkContourFilterが輪郭を計算するためにvtkContourFilterを選択できるようにします。 output->GetPointData()->SetScalars(dataArray)を実行して、これらの両方の操作を行うことができます。このソリューションでは、変数pointDataの割り当てをもう必要としないことに注意してください。

ので短いため、あなたが変更することができます。

int RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector* outputVector) VTK_OVERRIDE { 
    /* body of the function here */ 

    // old version 
    // output->SetFieldData(pointData); 
    // new version 
    output->GetPointData()->SetScalars(dataArray); 
    return 1; 
} 

あなたはそれに応じて印刷を変更することがあります。

// old version: 
// cout << fakeReader->GetOutput()->GetFieldData()->GetNumberOfArrays() << endl; 
// new version: 
cout << fakeReader->GetOutput()->GetPointData()->GetNumberOfArrays() << endl; 

// old version 
// cout << isoFilter->GetOutput()->GetFieldData()->GetNumberOfArrays() << endl; 
// new version 
cout << isoFilter->GetOutput()->GetPointData()->GetNumberOfArrays() << endl; 
+0

ありがとうございました!したがって、通常はSetFieldData()は何のために使われますか? – landings

+1

ドキュメントによると、 'SetFieldData()'は、このデータオブジェクトに一般的なフィールドデータを割り当てるために使われます。この関数も使用できますが、この場合、データセットの値のアサーションは指定されていません詳細については、vtkDataObject :: FieldAssociationsのドキュメントを参照してください)。つまり、 'SetFieldData()'を使用することはできますが、その場合は、 'vtkContourFilter'にどこに' isoFilter-> SetInputArrayToProcess(0,0,0、vtkDataObject :: FIELD_ASSOCIATION_NONE、 "Stress") 'データ配列を取得します。 –

+1

これを完成させるには、 'vtkContourFilter'がデフォルトで、点に関連付けられたスカラ値を表すデータ配列を取得する必要があります([コンストラクタ](https://github.com/Kitware/VTK/blob/master /Filters/Core/vtkContourFilter.cxx)の 'vtkContourFilter'を参照してください) –

関連する問題