2016-11-24 3 views
5

vtkオブジェクトvtkVectorTextを使用してテキストをレンダリングしようとしています。単一の3Dロケーションでうまく動作します。私が必要とするのは、3dテキストをいくつかの3d(vtkPoint)ポイントの上に置くことです。私はvtkTextActor3dでそれをやろうとしましたが、各テキストオブジェクトに別々のアクタが必要で、10kのアクタで終わってしまいました。VTK - 単一のアクタで複数の3Dテキストオブジェクトをレンダリングする方法

またappendFilterを適用してvtkVectorText配列を作成し、appendFilterのオブジェクトから構造化されていないグリッドを取得し、それをpolydataに変換して、非構造化グリッドを目的のポイント位置にレンダリングしました。これを行う最良の方法が何であるかわからないので、何も表示されません。

誰かがこれを手伝ってくれますか?ここで

は最後の部分から私のコードです:

vtkSmartPointer<vtkAppendFilter> appendFilter = vtkSmartPointer<vtkAppendFilter>::New(); 
//for each point 
for (int i = 0; i < N;i++) { 
    vtkSmartPointer<vtkVectorText> vecText = vtkSmartPointer<vtkVectorText>::New(); 
    vecText->SetText("My text, needs to appear multiple times"); 
    vecText->Update(); 
    appendFilter->AddInputData(vecText->GetOutput()); 
    appendFilter->Update(); 
} 
vtkSmartPointer<vtkUnstructuredGrid> unstructuredGrid = appendFilter->GetOutput(); 
unstructuredGrid->Allocate(N); 
unstructuredGrid->SetPoints(points); 
vtkSmartPointer<vtkGeometryFilter> geometryFilter = vtkSmartPointer<vtkGeometryFilter>::New(); 
geometryFilter->SetInputData(unstructuredGrid); 
geometryFilter->Update(); 
vtkSmartPointer<vtkPolyDataMapper> textMapper = vtkSmartPointer<vtkPolyDataMapper>::New(); 
textMapper->SetInputConnection(geometryFilter->GetOutputPort()); 
vtkSmartPointer<vtkActor> textActor = vtkSmartPointer<vtkActor>::New(); 
textActor->SetMapper(textMapper); 
textActor->GetProperty()->SetColor(0, 1, 0); 

renderer->AddActor(textActor); 

答えて

1

テキストは各点で同じであれば、私はグリフとしてそれを使用して提案する:

vtkSmartPointer<vtkPolyData> pointsHolder = vtkSmartPointer<vtkPolyData>::New(); 
pointsHolder->SetPoints(points); // I assume that these are the points where you want the object to be rendered 
vtkSmartPointer<vtkGlyph3DMapper> glyphMapper = vtkSmartPointer<vtkGlyph3DMapper>::New(); 
glyphMapper->SetSourceConnection(vecText->GetOutputPort()); // this says WHAT should be rendered 
glyphMapper->SetInputData(pointsHolder); // this says WHERE 
textActor->SetMapper(glyphMapper); 

これは、レンダリングします"points"配列内のすべての点のテキスト(テキストをレンダリングする位置のvtkPoints配列と仮定します)。この方法では、スケッチ配列を提供することによってグリフごとに異なるサイズを設定するか、またはマスク配列などを提供することによって対話的にオン/オフを切り替えるなど、1つのメッシュに追加するときにはできないすべての種類の作業を行うことができます。 http://www.vtk.org/doc/nightly/html/classvtkGlyph3DMapper.html

テキストがポイントごとに異なる場合は、おそらく追加する方法で行う必要があります。私はあなたの追加コードにいくつかのバグを見ることができます:

1)まず小さなパフォーマンスの1つ - appendFilter-> Update()を呼び出します。すべての入力を設定した後は、一度だけです。

2)

unstructuredGrid->Allocate(N); 
unstructuredGrid->SetPoints(points); 

割り当て呼び出すことで、あなただけのappendfilterがあなたのために行っているすべてのものをresetted。それがなくても、2行目はテキスト用に生成されたすべての点の位置を書き換えます。追加フィルタの出力は、マッパーに直接割り当てるべきものです。これらの2行を削除する必要があります。ちょうどvtkGeometryFilterと同様に、私はそれを(vtkUnstructuredGridの代わりにvtkPolyDataを得るために使用したと思います - vtkAppendFilterの代わりにvtkAppendPolydataを使用すると、直接polydataを生成します)。

3)しかし、今や "points"配列は使用されません。つまり、テキストは正しい位置にありません。それを追加フィルタに割り当てる前に、各テキストインスタンスのポリデータを変換する必要があります。最も単純なのは、あなたの "点"配列の点を翻訳ベクトルとして使うことです。そのため、vecText-> GetOutput()の各点に点の座標を追加してからappendフィルタに送ります。つまり、

vtkSmartPointer<vtkAppendPolyData> appendFilter = vtkSmartPointer<vtkAppendPolyData>::New(); 
//for each point 
for (int i = 0; i < N;i++) { 
    vtkSmartPointer<vtkVectorText> vecText = vtkSmartPointer<vtkVectorText>::New(); 
    vecText->SetText("My text, needs to appear multiple times"); 
    vecText->Update(); 
    vtkPolyData *output = vecText->GetOutput(); 
    double *location = points->GetPoint(i); 
    for (int j = 0; j < output->GetNumberOfPoints(); j++) { 
     double *point = output->GetPoint(j); 
     output->GetPoints()->SetPoint(j, point[0] + location[0], point[1] + location[1], points[2] + location[2]); 
    } 
    appendFilter->AddInputData(output); 
} 
appendFilter->Update(); 

テキストを中央に配置したい場合は、もっと賢いことが必要です。

関連する問題