はじめに: 最近、点から曲面への投影点について調べていたときに、このインターフェイスを目にしました。このブログ投稿では主に、vtkDistancePolyDataFilter フィルターの目的、実装プロセス、例、およびスケーラブルなアプリケーションを記録します。
目次
2.3 ClipをClipFunctionとして実装します。
2.4 点 x から指定された PolyData に最も近い点 p を取得する
1.vtkDistancePolyDataFilter
1.1 説明
このインターフェイスは主に、2 つの vtkPlyData データセット間の距離を計算するために使用されます。vtkImplicitPolyDataDistance を使用して、最初の入力の各点で 2 番目の入力までの符号付き距離を計算します。オプションで、2 番目の入力の各点から最初の入力までの符号付き距離を計算できます。これは、ComputeSecondDistanceOn() を呼び出すことで有効にできます。
SignedDistanceOff() を設定すると、符号なしの距離値を計算できるようになります。
1.2 導入プロセス
vtkImplicitPolyDataDistance* imp = vtkImplicitPolyDataDistance::New();
imp->SetInput(src);
// Calculate distance from points.
int numPts = mesh->GetNumberOfPoints();
vtkDoubleArray* pointArray = vtkDoubleArray::New();
pointArray->SetName("Distance");
pointArray->SetNumberOfComponents(1);
pointArray->SetNumberOfTuples(numPts);
for (vtkIdType ptId = 0; ptId < numPts; ptId++)
{
double pt[3];
mesh->GetPoint(ptId, pt);
double val = imp->EvaluateFunction(pt);
double dist = SignedDistance ? (NegateDistance ? -val : val) : fabs(val);
pointArray->SetValue(ptId, dist);
}
1.3 例
#include <vtkSmartPointer.h>
#include <vtkActor.h>
#include <vtkDistancePolyDataFilter.h>
#include <vtkPolyDataMapper.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkPolyDataReader.h>
#include <vtkCleanPolyData.h>
#include <vtkProperty.h>
#include <vtkPointData.h>
#include <vtkScalarBarActor.h>
#include <vtkSphereSource.h>
#include <vtkNamedColors.h>
int main(int argc, char* argv[])
{
vtkSmartPointer<vtkPolyData> input1;
vtkSmartPointer<vtkPolyData> input2;
if (argc == 3)
{
// std::cerr << "Usage: " << argv[0]
// << " filename1.vtk"
// << " filename2.vtk" << std::endl;
vtkSmartPointer<vtkPolyDataReader> reader1 =
vtkSmartPointer<vtkPolyDataReader>::New();
reader1->SetFileName(argv[1]);
reader1->Update();
input1 = reader1->GetOutput();
vtkSmartPointer<vtkPolyDataReader> reader2 =
vtkSmartPointer<vtkPolyDataReader>::New();
reader2->SetFileName(argv[2]);
reader2->Update();
input2 = reader2->GetOutput();
}
else
{
vtkSmartPointer<vtkSphereSource> sphereSource1 =
vtkSmartPointer<vtkSphereSource>::New();
sphereSource1->SetCenter(1, 0, 0);
sphereSource1->SetPhiResolution(21);
sphereSource1->SetThetaResolution(21);
sphereSource1->Update();
input1 = sphereSource1->GetOutput();
vtkSmartPointer<vtkSphereSource> sphereSource2 =
vtkSmartPointer<vtkSphereSource>::New();
sphereSource2->SetPhiResolution(21);
sphereSource2->SetThetaResolution(21);
sphereSource2->Update();
input2 = sphereSource2->GetOutput();
}
vtkSmartPointer<vtkNamedColors> colors =
vtkSmartPointer<vtkNamedColors>::New();
vtkSmartPointer<vtkCleanPolyData> clean1 =
vtkSmartPointer<vtkCleanPolyData>::New();
clean1->SetInputData( input1);
vtkSmartPointer<vtkCleanPolyData> clean2 =
vtkSmartPointer<vtkCleanPolyData>::New();
clean2->SetInputData( input2);
vtkSmartPointer<vtkDistancePolyDataFilter> distanceFilter =
vtkSmartPointer<vtkDistancePolyDataFilter>::New();
distanceFilter->SetInputConnection( 0, clean1->GetOutputPort() );
distanceFilter->SetInputConnection( 1, clean2->GetOutputPort() );
distanceFilter->Update();
vtkSmartPointer<vtkPolyDataMapper> mapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection( distanceFilter->GetOutputPort() );
mapper->SetScalarRange(
distanceFilter->GetOutput()->GetPointData()->GetScalars()->GetRange()[0],
distanceFilter->GetOutput()->GetPointData()->GetScalars()->GetRange()[1]);
vtkSmartPointer<vtkActor> actor =
vtkSmartPointer<vtkActor>::New();
actor->SetMapper( mapper );
vtkSmartPointer<vtkScalarBarActor> scalarBar =
vtkSmartPointer<vtkScalarBarActor>::New();
scalarBar->SetLookupTable(mapper->GetLookupTable());
scalarBar->SetTitle("Distance");
scalarBar->SetNumberOfLabels(4);
vtkSmartPointer<vtkRenderer> renderer =
vtkSmartPointer<vtkRenderer>::New();
renderer->SetBackground(colors->GetColor3d("Silver").GetData());
renderer->SetBackground2(colors->GetColor3d("Gold").GetData());
renderer->GradientBackgroundOn();
vtkSmartPointer<vtkRenderWindow> renWin =
vtkSmartPointer<vtkRenderWindow>::New();
renWin->AddRenderer( renderer );
vtkSmartPointer<vtkRenderWindowInteractor> renWinInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
renWinInteractor->SetRenderWindow( renWin );
renderer->AddActor( actor );
renderer->AddActor2D(scalarBar);
renWin->Render();
renWinInteractor->Start();
return EXIT_SUCCESS;
}
2.vtkImplicitPolyDataDistance
2.1 説明
入力 vtkPolyData 上の点 x から最も近い点 p までの距離を計算する暗黙的な関数。関数の符号は、最も近い表面点のコーナー加重疑似法線とベクトル x - p の間の内積の符号に設定されます。ジオメトリ内のポイントの距離は負の値、外側のポイントの距離は正の値、入力 vtkPolyData 上のポイントの距離は 0 です。関数の勾配は、最も近い点の角度重み付けされた擬似法線です。
2.2 実装
1) vtkCellLocator を定義し、初期化します。
2) vtkCellLocator の FindClosestPoint メソッドを使用して、点 x から vtkPolyData データセットに最も近い点を計算します。
3) vtkCell の EvaluatePosition メソッドを使用して、最も近い点とシンボルを再度決定します。