作ってみたら意外と発見があったのでコードを置いておく。斬新だったのは、二つのvtkPolyDataをvtkAppendPolyDataで結合するところで、これができるといろいろと複雑なモデルを作りやすい。
#include <iostream> //VTK_MODULE_INITに必要 #include <vtkAutoInit.h> #include <vtkSmartPointer.h> #include <vtkRenderer.h> #include <vtkRenderWindow.h> #include <vtkRenderWindowInteractor.h> // メッシュ生成に必要 #include <vtkQuad.h> #include <vtkTriangle.h> #include <vtkPolyDataMapper.h> #include <vtkAppendPolyData.h> #pragma comment(lib,"opengl32.lib") #pragma comment(lib,"psapi.lib") #pragma comment(lib,"dbghelp.lib") #pragma comment(lib,"ws2_32.lib") //必須 VTK_MODULE_INIT(vtkRenderingOpenGL2); VTK_MODULE_INIT(vtkInteractionStyle);
vtkSmartPointer<vtkPolyData> MyCreateTriangularPrism(float height) { float ph = height/2; float mh = -height/2; float x[6] = { 0.0,1.0,0.5,0.0,1.0,0.5 }; float y[6] = { 0.0,0.0,0.866,0.0,0.0,0.866 }; float z[6] = { mh,mh,mh,ph,ph,ph }; // 頂点を定義 vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New(); points->InsertNextPoint(x[0], z[0], y[0]); // 0 points->InsertNextPoint(x[1], z[1], y[1]); // 1 points->InsertNextPoint(x[2], z[2], y[2]); // 2 points->InsertNextPoint(x[3], z[3], y[3]); // 3 points->InsertNextPoint(x[4], z[4], y[4]); // 4 points->InsertNextPoint(x[5], z[5], y[5]); // 5 // 三角形一覧を定義 vtkSmartPointer<vtkCellArray> top_bottom = vtkSmartPointer<vtkCellArray>::New(); // 底面 vtkSmartPointer<vtkTriangle> t_bottom = vtkSmartPointer<vtkTriangle>::New(); t_bottom->GetPointIds()->SetId(0, 0); t_bottom->GetPointIds()->SetId(1, 2); t_bottom->GetPointIds()->SetId(2, 1); top_bottom->InsertNextCell(t_bottom); // 上面 vtkSmartPointer<vtkTriangle> t_top = vtkSmartPointer<vtkTriangle>::New(); t_top->GetPointIds()->SetId(0, 3); t_top->GetPointIds()->SetId(1, 4); t_top->GetPointIds()->SetId(2, 5); top_bottom->InsertNextCell(t_top); // 四角形一覧(側面用)を定義 vtkSmartPointer<vtkCellArray> quads_sides = vtkSmartPointer<vtkCellArray>::New(); vtkSmartPointer<vtkQuad> quad1 = vtkSmartPointer<vtkQuad>::New(); quad1->GetPointIds()->SetId(0, 0); quad1->GetPointIds()->SetId(1, 1); quad1->GetPointIds()->SetId(2, 4); quad1->GetPointIds()->SetId(3, 3); quads_sides->InsertNextCell(quad1); vtkSmartPointer<vtkQuad> quad2 = vtkSmartPointer<vtkQuad>::New(); quad2->GetPointIds()->SetId(0, 1); quad2->GetPointIds()->SetId(1, 2); quad2->GetPointIds()->SetId(2, 5); quad2->GetPointIds()->SetId(3, 4); quads_sides->InsertNextCell(quad2); vtkSmartPointer<vtkQuad> quad3 = vtkSmartPointer<vtkQuad>::New(); quad3->GetPointIds()->SetId(0, 2); quad3->GetPointIds()->SetId(1, 0); quad3->GetPointIds()->SetId(2, 3); quad3->GetPointIds()->SetId(3, 5); quads_sides->InsertNextCell(quad3); /////////////////////////////////////////////////////// // 上下の三角形二枚からなるPolyDataを作成 vtkSmartPointer<vtkPolyData> polyData1 = vtkSmartPointer<vtkPolyData>::New(); polyData1->SetPoints(points); polyData1->SetPolys(top_bottom);
// 側面の四角形からなるPolyDataを作成 vtkSmartPointer<vtkPolyData> polyData2 = vtkSmartPointer<vtkPolyData>::New(); polyData2->SetPoints(points); polyData2->SetPolys(quads_sides); /////////////////////////////////////////////////////// // PolyDataを結合 vtkSmartPointer<vtkAppendPolyData> appendFilter = vtkSmartPointer<vtkAppendPolyData>::New(); appendFilter->AddInputData(polyData1); appendFilter->AddInputData(polyData2); appendFilter->Update(); vtkSmartPointer<vtkPolyData> polyData = appendFilter->GetOutput(); return polyData; }
int main(int /*argc*/, char** /*argv*/) { vtkSmartPointer<vtkPolyData> triangularprim = MyCreateTriangularPrism(3.0f); // 三角柱(高さ3.0) // マッパーを作成 vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New(); mapper->SetInputData(triangularprim); // アクターを作成 vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New(); actor->SetMapper(mapper); ////////////////////////////////////// auto renderer = vtkSmartPointer<vtkRenderer>::New(); renderer->AddActor(actor); renderer->ResetCamera(); ////////////////////////////////////// auto interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New(); ////////////////////////////////////// auto renderWindow = vtkSmartPointer<vtkRenderWindow>::New(); renderWindow->AddRenderer(renderer); renderWindow->SetInteractor(interactor); renderWindow->Render(); interactor->Start(); //イベントループへ入る return 0; }
#include <iostream> //VTK_MODULE_INITに必要 #include <vtkAutoInit.h> #include <vtkSmartPointer.h> #include <vtkRenderer.h> #include <vtkRenderWindow.h> #include <vtkRenderWindowInteractor.h> // メッシュ生成に必要 #include <vtkQuad.h> #include <vtkTriangle.h> #include <vtkPolyDataMapper.h> #include <vtkAppendPolyData.h> #include <vtkPolygon.h> #pragma comment(lib,"opengl32.lib") #pragma comment(lib,"psapi.lib") #pragma comment(lib,"dbghelp.lib") #pragma comment(lib,"ws2_32.lib") //必須 VTK_MODULE_INIT(vtkRenderingOpenGL2); VTK_MODULE_INIT(vtkInteractionStyle);
vtkSmartPointer<vtkPolyData> MyCreateNPrism(float height, int N) { // 角柱の上面、底面の位置を定義 float ph = height / 2; float mh = -height / 2; vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New(); vtkSmartPointer<vtkCellArray> top_bottom = vtkSmartPointer<vtkCellArray>::New(); vtkSmartPointer<vtkCellArray> quads_sides = vtkSmartPointer<vtkCellArray>::New(); // 底面と上面の頂点を定義 for (int i = 0; i < N; ++i) { double angle = 2.0 * 3.1415926535 * i / N; double x = cos(angle); double y = sin(angle); points->InsertNextPoint(x, y, mh); // 底面 points->InsertNextPoint(x, y, ph); // 上面 } // 底面と上面のポリゴンを定義 vtkSmartPointer<vtkPolygon> polygon_bottom = vtkSmartPointer<vtkPolygon>::New(); polygon_bottom->GetPointIds()->SetNumberOfIds(N); vtkSmartPointer<vtkPolygon> polygon_top = vtkSmartPointer<vtkPolygon>::New(); polygon_top->GetPointIds()->SetNumberOfIds(N); for (int i = 0; i < N; ++i) { polygon_bottom->GetPointIds()->SetId(i, i * 2); polygon_top->GetPointIds()->SetId(i, i * 2 + 1); } top_bottom->InsertNextCell(polygon_bottom); top_bottom->InsertNextCell(polygon_top); // 側面を定義 for (int i = 0; i < N; ++i) { vtkSmartPointer<vtkQuad> quad = vtkSmartPointer<vtkQuad>::New(); quad->GetPointIds()->SetId(0, (i * 2)); quad->GetPointIds()->SetId(1, ((i * 2 + 2) % (N * 2))); quad->GetPointIds()->SetId(2, ((i * 2 + 3) % (N * 2))); quad->GetPointIds()->SetId(3, (i * 2 + 1)); quads_sides->InsertNextCell(quad); } // 上下の面をなすPolyDataを作成 vtkSmartPointer<vtkPolyData> polyData1 = vtkSmartPointer<vtkPolyData>::New(); polyData1->SetPoints(points); polyData1->SetPolys(top_bottom); // 側面の四角形からなるPolyDataを作成 vtkSmartPointer<vtkPolyData> polyData2 = vtkSmartPointer<vtkPolyData>::New(); polyData2->SetPoints(points); polyData2->SetPolys(quads_sides); // PolyDataを結合 vtkSmartPointer<vtkAppendPolyData> appendFilter = vtkSmartPointer<vtkAppendPolyData>::New(); appendFilter->AddInputData(polyData1); appendFilter->AddInputData(polyData2); appendFilter->Update(); vtkSmartPointer<vtkPolyData> polyData = appendFilter->GetOutput(); return polyData; }
int main(int /*argc*/, char** /*argv*/) { vtkSmartPointer<vtkPolyData> nprim = MyCreateNPrism(3.0, 5);// 五角柱を作成 // マッパーを作成 vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New(); mapper->SetInputData(nprim); // アクターを作成 vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New(); actor->SetMapper(mapper); ////////////////////////////////////// auto renderer = vtkSmartPointer<vtkRenderer>::New(); renderer->AddActor(actor); renderer->ResetCamera(); ////////////////////////////////////// auto interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New(); ////////////////////////////////////// auto renderWindow = vtkSmartPointer<vtkRenderWindow>::New(); renderWindow->AddRenderer(renderer); renderWindow->SetInteractor(interactor); renderWindow->Render(); interactor->Start(); //イベントループへ入る return 0; }