線織面の作成(VTKライブラリ)

VTKライブラリを使用して、2つの円周に対する線織面を作成します。

下図のように、各円周上に対応する点を取り、片方を固定し、もう一方をz-軸を中心にα度だけ回転させ、さらにθを0°から360°まで変えてたときに、その2点を結んだ線が描く面は線織面となります。

線織面のパラメータ表示

α=30°, =90°,=135°としたときは下のプログラムを使用して描画すると以下のようになります。

線織面

以下は、プログラムの実行方法です。

 RuledSurfaceFilter.exe radius resolution angle(degree) translation

プログラムの引数の意味は以下となります。

radius2つの円の半径
resolution円周上の点数(解像度)
angle(degree)オフセットする角度
translation2つの円周間の距離(z軸方向)

例えば、α=135°のときは、以下のような実行になります。

 RuledSurfaceFilter.exe 10.0 100 135.0 20.0

RuledSurfaceFilter.cxx

Everything is expanded.Everything is shortened.
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
-
|
-
|
|
!
|
|
|
|
|
|
-
!
|
|
|
|
|
|
-
!
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-
|
|
!
|
|
|
|
|
-
|
|
!
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-
!
|
|
|
|
|
|
|
|
|
|
|
|
!
 
#include <vtkSmartPointer.h>
 
#include <vtkDiskSource.h>
#include <vtkPolyLine.h>
#include <vtkRuledSurfaceFilter.h>
#include <vtkTransform.h>
#include <vtkTransformPolyDataFilter.h>
#include <vtkSTLWriter.h>
 
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkCellArray.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkCamera.h>
 
int main(int argc, char *argv[])
{
  if (argc != 5)
  {
    std::cout << "Required parameters: radius resolution angle(degree) translation" << std::endl;
    return EXIT_FAILURE;
  }
 
  double radius = atof(argv[1]);
  int resolution = atoi(argv[2]);
  double angle = atof(argv[3]); // degree
  double translation = atof(argv[4]);
 
  // Create first disk source.
  auto disk1 = vtkSmartPointer<vtkDiskSource>::New();
  disk1->SetInnerRadius(0.0);
  disk1->SetOuterRadius(10.0);
  disk1->SetRadialResolution(1);
  disk1->SetCircumferentialResolution(resolution);
  disk1->Update();
 
  // Create second disk source.
  auto disk2 = vtkSmartPointer<vtkDiskSource>::New();
  disk2->SetInnerRadius(0.0);
  disk2->SetOuterRadius(10.0);
  disk2->SetRadialResolution(1);
  disk2->SetCircumferentialResolution(resolution);
 
  auto transform = vtkSmartPointer<vtkTransform>::New();
  transform->RotateWXYZ(angle, 0, 0, 1);
  transform->Translate(0, 0, translation);
 
  auto transformFilter = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
  transformFilter->SetTransform(transform);
  transformFilter->SetInputConnection(disk2->GetOutputPort());
  transformFilter->Update();
 
  auto points = vtkSmartPointer<vtkPoints>::New();
 
  auto polyLine1 = vtkSmartPointer<vtkPolyLine>::New();
  polyLine1->GetPointIds()->SetNumberOfIds(resolution+1);
  for (int i = 0; i < resolution; ++i)
  {
    points->InsertNextPoint(disk1->GetOutput()->GetPoint(2*i+1));
    polyLine1->GetPointIds()->SetId(i, i);
  }
  polyLine1->GetPointIds()->SetId(resolution, 0);
 
  auto polyLine2 = vtkSmartPointer<vtkPolyLine>::New();
  polyLine2->GetPointIds()->SetNumberOfIds(resolution+1);
  for (int i = 0; i < resolution; ++i)
  {
    points->InsertNextPoint(transformFilter->GetOutput()->GetPoint(2*i+1));
    polyLine2->GetPointIds()->SetId(i, resolution + i);
  }
  polyLine2->GetPointIds()->SetId(resolution, resolution);
  
  auto polyLines = vtkSmartPointer<vtkCellArray>::New();
  polyLines->InsertNextCell(polyLine1);
  polyLines->InsertNextCell(polyLine2);
 
  auto polydata = vtkSmartPointer<vtkPolyData>::New();
  polydata->SetPoints(points);
  polydata->SetLines(polyLines);
 
  vtkSmartPointer<vtkRuledSurfaceFilter> ruledSurfaceFilter =
    vtkSmartPointer<vtkRuledSurfaceFilter>::New();
  ruledSurfaceFilter->SetInputData(polydata);
  ruledSurfaceFilter->SetResolution(resolution+1, resolution+1);
  ruledSurfaceFilter->SetRuledModeToResample();
  ruledSurfaceFilter->Update();
 
  auto writer = vtkSmartPointer<vtkSTLWriter>::New();
  writer->SetFileName("ruled_surface.stl");
  writer->SetInputData(ruledSurfaceFilter->GetOutput());
  writer->Write();
 
  vtkSmartPointer<vtkRenderer> renderer = 
    vtkSmartPointer<vtkRenderer>::New();
    
  vtkSmartPointer<vtkRenderWindow> renderWindow = 
    vtkSmartPointer<vtkRenderWindow>::New();
  renderWindow->AddRenderer(renderer);
  
  vtkSmartPointer<vtkRenderWindowInteractor> interactor = 
    vtkSmartPointer<vtkRenderWindowInteractor>::New();
  interactor->SetRenderWindow(renderWindow);
  
  vtkSmartPointer<vtkPolyDataMapper> mapper =
    vtkSmartPointer<vtkPolyDataMapper>::New();
  mapper->SetInputConnection(ruledSurfaceFilter->GetOutputPort());
 
  vtkSmartPointer<vtkActor> actor =
    vtkSmartPointer<vtkActor>::New();
  actor->SetMapper(mapper);
  actor->GetProperty()->SetColor(0.89, 0.81, 0.34);
 
  // Add the actors to the renderer, set the background and size
  renderer->AddActor(actor);
  renderer->SetBackground(.3, .4, .5);
 
  renderer->ResetCamera();
  renderer->GetActiveCamera()->Azimuth(60);
  renderer->GetActiveCamera()->Elevation(60);
  renderer->GetActiveCamera()->Dolly(1.2);
  renderer->ResetCameraClippingRange();
 
  renderWindow->Render();
  interactor->Start();
 
  return EXIT_SUCCESS;
}

ダウンロードとビルド

ソースコードとCMakeLists.txtファイル:


添付ファイル: fileRuledSurface.zip 48件 [詳細] fileruled_surfaces.png 49件 [詳細] fileoffset.png 53件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2019-06-24 (月) 15:59:24 (89d)