VTK-vtkSelectPolyDataFilter

前書き: このブログ投稿は主に vtkSelectPolyDataFilter インターフェイスのアプリケーションと実装原理を記録し、vtkClipPolyData&vtkImplicitSelectionLoop の同様のアプリケーションと比較して、友人が vtkSelectPolyDataFilter インターフェイスの実装原理を理解し、他のインターフェイスと区別できるようにします。

結果表示

    

                 SelectPolyData ImplicitSelectionLoop

vtkSelectPolyDataFilter

説明: vtkSelectPolyData は、「ループ」を定義し、ループ内の領域を示すことによってポリゴン データを選択するフィルターです。ループ内のメッシュは無傷のセルで構成されます (セルは切断されていません)。あるいは、このフィルターを使用してスカラーを生成することもできます。これらのスカラー値はループまでの距離の測定値であり、クリップや輪郭に使用できます。または、データを抽出します (つまり、暗黙的な関数で実行できることはすべて)。

ループは、xyz 点座標の配列によって定義されます。(座標は入力ポリゴン データと同じ座標空間内にある必要があります。) リングは凹面、非平面にすることができますが、自己交差することはできません。フィルターへの入力はポリゴン メッシュ (トライアングル ストリップやポリゴンのみなどのサーフェス プリミティブ)、出力は、a) 選択ループ GenerateSelectionScalarsOff 内でタイル化された元のメッシュの一部、または b) スカラー値を持つ同じポリゴンです。グリッド(GenerateSelectionScalarsOn)を追加しました。

アルゴリズムは次のように機能します。ループ内の各点座標について、グリッド内の最も近い点が見つかります。結果は、グリッドに最も近いポイント ID で構成されるループになります。次に、グリッド内の最も近い点を接続するエッジを見つけます (ループを形成する線に沿って配置します)。貪欲なエッジ トレーシングのプロセスを以下に示します。現在の点で、方向が直線に最も近い端点を持つメッシュ エッジを選択します。エッジを新しい終点までたどって、このプロセスを繰り返します。このプロセスは、ループ全体が作成されるまで続きます。

メッシュのどの部分がループの内側と外側にあるのかを判断するには、3 つのオプションがあります。1) 最小の接続領域、2) 最大の接続領域、3) ユーザーが指定した点に最も近い接続領域。(ivar SelectionMode を設定)

GenerateSelectionScalars は、ループが上記のように評価されると、フィルターの出力を制御します。オンの場合、円までの距離に基づいてスカラー値を生成します。それ以外の場合、選択ループ内のセルが出力されます。デフォルトでは、ループ内のメッシュ タイルが出力されますが、InsideOut がオンの場合は、ループの外側のメッシュの部分が出力されます。

GenerateUnselectedOutput を設定することで、メッシュの選択されていない部分を出力として生成するようにフィルターを構成できます。この出力にアクセスするには、メソッド GetUnselectedOutput を使用します。(注: このフラグは、generateSelectionScalars がオフの場合にのみ関連します。)

インスタンス TestSelectPolyData

#include <vtkSmartPointer.h>
#include <vtkProperty.h>
#include <vtkSelectPolyData.h>
#include <vtkSphereSource.h>
#include <vtkClipPolyData.h>
#include <vtkProperty.h>
#include <vtkPolyDataMapper.h>
#include <vtkLODActor.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>

#include <vtkNamedColors.h>

int main(int, char *[])
{
  
  vtkSmartPointer<vtkNamedColors> colors =
    vtkSmartPointer<vtkNamedColors>::New();

  vtkSmartPointer<vtkSphereSource> sphereSource = 
    vtkSmartPointer<vtkSphereSource>::New();
  sphereSource->SetPhiResolution(50);
  sphereSource->SetThetaResolution(100);
  sphereSource->Update();
      
  vtkSmartPointer<vtkPoints> selectionPoints =
    vtkSmartPointer<vtkPoints>::New();
    
  selectionPoints->InsertPoint( 0, -0.16553, 0.135971, 0.451972 );
  selectionPoints->InsertPoint( 1, -0.0880123, -0.134952, 0.4747);
  selectionPoints->InsertPoint( 2,  0.00292618, -0.134604, 0.482459 );
  selectionPoints->InsertPoint( 3, 0.0641941, 0.067112, 0.490947);
  selectionPoints->InsertPoint( 4, 0.15577, 0.0734765, 0.469245);
  selectionPoints->InsertPoint( 5, 0.166667, -0.129217, 0.454622 );
  selectionPoints->InsertPoint( 6, 0.241259, -0.123363, 0.420581);
  selectionPoints->InsertPoint( 7,  0.240334, 0.0727106, 0.432555);
  selectionPoints->InsertPoint( 8, 0.308529, 0.0844311, 0.384357 );
  selectionPoints->InsertPoint( 9, 0.32672, -0.121674, 0.359187);
  selectionPoints-> InsertPoint( 10, 0.380721, -0.117342, 0.302527);
  selectionPoints ->InsertPoint( 11, 0.387804, 0.0455074, 0.312375 );
  selectionPoints ->InsertPoint( 12, 0.43943, -0.111673, 0.211707);
  selectionPoints ->InsertPoint( 13, 0.470984, -0.0801913, 0.147919);
  selectionPoints ->InsertPoint( 14, 0.436777, 0.0688872, 0.233021 );
  selectionPoints ->InsertPoint( 15, 0.44874, 0.188852, 0.109882);
  selectionPoints ->InsertPoint( 16, 0.391352, 0.254285, 0.176943);
  selectionPoints ->InsertPoint( 17, 0.373274, 0.154162, 0.294296 );
  selectionPoints ->InsertPoint( 18, 0.274659, 0.311654, 0.276609);
  selectionPoints ->InsertPoint( 19, 0.206068, 0.31396, 0.329702);
  selectionPoints ->InsertPoint( 20, 0.263789, 0.174982, 0.387308 );
  selectionPoints ->InsertPoint( 21, 0.213034, 0.175485, 0.417142);
  selectionPoints ->InsertPoint( 22, 0.169113, 0.261974, 0.390286);
  selectionPoints ->InsertPoint( 23, 0.102552, 0.25997, 0.414814 );
  selectionPoints ->InsertPoint( 24, 0.131512, 0.161254, 0.454705);
  selectionPoints ->InsertPoint( 25, 0.000192443, 0.156264, 0.475307);
  selectionPoints ->InsertPoint( 26, -0.0392091, 0.000251724, 0.499943); 
  selectionPoints ->InsertPoint( 27, -0.096161, 0.159646, 0.46438 );
  
  vtkSmartPointer<vtkSelectPolyData> loop =
    vtkSmartPointer<vtkSelectPolyData>::New();
  loop->SetInputConnection(sphereSource->GetOutputPort());
  loop->SetLoop(selectionPoints);
  loop->GenerateSelectionScalarsOn();
  loop->SetSelectionModeToSmallestRegion(); //negative scalars inside
  
  vtkSmartPointer<vtkClipPolyData> clip = //clips out positive region
    vtkSmartPointer<vtkClipPolyData>::New();
  clip->SetInputConnection(loop->GetOutputPort());

  vtkSmartPointer<vtkPolyDataMapper> clipMapper = 
    vtkSmartPointer<vtkPolyDataMapper>::New();
  clipMapper->SetInputConnection(clip->GetOutputPort());
  clipMapper->ScalarVisibilityOff();

  vtkSmartPointer<vtkProperty> backProp =
    vtkSmartPointer<vtkProperty>::New();
  backProp->SetColor(colors->GetColor3d("tomato").GetData());

  vtkSmartPointer<vtkLODActor> clipActor = 
    vtkSmartPointer<vtkLODActor>::New();
  clipActor->SetMapper(clipMapper);
  clipActor->SetBackfaceProperty(backProp);
  clipActor->GetProperty()->SetColor(colors->GetColor3d("banana").GetData());

  vtkSmartPointer<vtkRenderer> renderer =
    vtkSmartPointer<vtkRenderer>::New();
    
  vtkSmartPointer<vtkRenderWindow> renderWindow =
    vtkSmartPointer<vtkRenderWindow>::New();
  renderWindow->AddRenderer(renderer);
  
  vtkSmartPointer<vtkRenderWindowInteractor> interactor =
    vtkSmartPointer<vtkRenderWindowInteractor>::New();
  interactor->SetRenderWindow(renderWindow);

  // Add the actors to the renderer, set the background and size
  renderer->AddActor (clipActor);
  renderer->SetBackground (colors->GetColor3d("slate_grey").GetData());

  renderWindow->SetSize (500, 500);

  renderWindow->Render();
  interactor->Start();


  return EXIT_SUCCESS;
}

例 2 暗黙的な選択ループ

原則: vtkImplicitSelectionLoop を vtkImplicitFunction として使用して、vtkClipPolyData セグメンテーションを実現します。結果は上記の ImplicitSelectionLoop に示されています。

#include <vtkClipPolyData.h>
#include <vtkImplicitSelectionLoop.h>
#include <vtkLODActor.h>
#include <vtkNamedColors.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>

int main(int, char*[])
{

  auto colors = vtkSmartPointer<vtkNamedColors>::New();

  auto sphereSource = vtkSmartPointer<vtkSphereSource>::New();
  sphereSource->SetPhiResolution(100);
  sphereSource->SetThetaResolution(100);
  sphereSource->Update();

  auto selectionPoints = vtkSmartPointer<vtkPoints>::New();

  selectionPoints->InsertPoint(0, -0.16553, 0.135971, 0.451972);
  selectionPoints->InsertPoint(1, -0.0880123, -0.134952, 0.4747);
  selectionPoints->InsertPoint(2, 0.00292618, -0.134604, 0.482459);
  selectionPoints->InsertPoint(3, 0.0641941, 0.067112, 0.490947);
  selectionPoints->InsertPoint(4, 0.15577, 0.0734765, 0.469245);
  selectionPoints->InsertPoint(5, 0.166667, -0.129217, 0.454622);
  selectionPoints->InsertPoint(6, 0.241259, -0.123363, 0.420581);
  selectionPoints->InsertPoint(7, 0.240334, 0.0727106, 0.432555);
  selectionPoints->InsertPoint(8, 0.308529, 0.0844311, 0.384357);
  selectionPoints->InsertPoint(9, 0.32672, -0.121674, 0.359187);
  selectionPoints->InsertPoint(10, 0.380721, -0.117342, 0.302527);
  selectionPoints->InsertPoint(11, 0.387804, 0.0455074, 0.312375);
  selectionPoints->InsertPoint(12, 0.43943, -0.111673, 0.211707);
  selectionPoints->InsertPoint(13, 0.470984, -0.0801913, 0.147919);
  selectionPoints->InsertPoint(14, 0.436777, 0.0688872, 0.233021);
  selectionPoints->InsertPoint(15, 0.44874, 0.188852, 0.109882);
  selectionPoints->InsertPoint(16, 0.391352, 0.254285, 0.176943);
  selectionPoints->InsertPoint(17, 0.373274, 0.154162, 0.294296);
  selectionPoints->InsertPoint(18, 0.274659, 0.311654, 0.276609);
  selectionPoints->InsertPoint(19, 0.206068, 0.31396, 0.329702);
  selectionPoints->InsertPoint(20, 0.263789, 0.174982, 0.387308);
  selectionPoints->InsertPoint(21, 0.213034, 0.175485, 0.417142);
  selectionPoints->InsertPoint(22, 0.169113, 0.261974, 0.390286);
  selectionPoints->InsertPoint(23, 0.102552, 0.25997, 0.414814);
  selectionPoints->InsertPoint(24, 0.131512, 0.161254, 0.454705);
  selectionPoints->InsertPoint(25, 0.000192443, 0.156264, 0.475307);
  selectionPoints->InsertPoint(26, -0.0392091, 0.000251724, 0.499943);
  selectionPoints->InsertPoint(27, -0.096161, 0.159646, 0.46438);

  auto loop = vtkSmartPointer<vtkImplicitSelectionLoop>::New();
  loop->SetLoop(selectionPoints);

  auto clip = // clips out positive region
      vtkSmartPointer<vtkClipPolyData>::New();
  clip->SetInputConnection(sphereSource->GetOutputPort());
  clip->SetClipFunction(loop);
  clip->SetValue(0.0);

  auto clipMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
  clipMapper->SetInputConnection(clip->GetOutputPort());
  clipMapper->ScalarVisibilityOff();

  auto backProp = vtkSmartPointer<vtkProperty>::New();
  backProp->SetColor(colors->GetColor3d("tomato").GetData());

  auto clipActor = vtkSmartPointer<vtkLODActor>::New();
  clipActor->SetMapper(clipMapper);
  clipActor->SetBackfaceProperty(backProp);
  clipActor->GetProperty()->SetColor(colors->GetColor3d("banana").GetData());

  auto renderer = vtkSmartPointer<vtkRenderer>::New();

  auto renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
  renderWindow->AddRenderer(renderer);

  auto interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
  interactor->SetRenderWindow(renderWindow);

  // Add the actors to the renderer, set the background and size
  renderer->AddActor(clipActor);
  renderer->SetBackground(colors->GetColor3d("slate_grey").GetData());

  renderWindow->SetSize(500, 500);

  renderWindow->Render();
  interactor->Start();

  return EXIT_SUCCESS;
}

おすすめ

転載: blog.csdn.net/qq_40041064/article/details/128704956