【VTK】使用vtkActor2D新增polyline
阿新 • • 發佈:2018-12-16
具體實現如下:
#include <iostream> #include <vtkSmartPointer.h> #include <vtkSphereSource.h> #include <vtkActor.h> #include <vtkConeSource.h> #include <vtkRenderer.h> #include <vtkRenderWindow.h> #include <vtkPolyDataMapper.h> #include <vtkProperty.h> #include <vtkRenderWindowInteractor.h> #include <vtkLight.h> #include <vtkCamera.h> #include <vtkPolyDataMapper2D.h> #include <vtkActor2D.h> #include <vtkProperty2D.h> using namespace std; int main() { vtkSmartPointer<vtkConeSource> cone = vtkSmartPointer<vtkConeSource>::New(); vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New(); mapper->SetInputConnection( cone->GetOutputPort() ); vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New(); actor->SetMapper( mapper ); vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New(); renderer->AddActor(actor); renderer->SetBackground( 0, 0, 0 ); vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New(); renderWindow->AddRenderer( renderer ); vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New(); renderWindowInteractor->SetRenderWindow( renderWindow ); // ------------- start to add red line ---------------- vtkSmartPointer<vtkPolyDataMapper2D> v1mmMapper = vtkSmartPointer<vtkPolyDataMapper2D>::New(); vtkSmartPointer<vtkPolyData> v1mmPolyData = vtkSmartPointer<vtkPolyData>::New(); vtkSmartPointer<vtkCellArray> v1mmLines = vtkSmartPointer<vtkCellArray>::New(); vtkSmartPointer<vtkPoints> v1mmPoints = vtkSmartPointer<vtkPoints>::New(); v1mmPolyData->SetPoints( v1mmPoints ); v1mmPolyData->SetLines( v1mmLines ); v1mmMapper->SetInputData( v1mmPolyData ); vtkSmartPointer<vtkActor2D> v1mmLinesActor = vtkSmartPointer<vtkActor2D>::New(); v1mmLinesActor->SetMapper( v1mmMapper ); v1mmLinesActor->GetProperty()->SetColor( 1, 0, 0 ); v1mmLinesActor->GetProperty()->SetLineWidth( 1 ); vtkSmartPointer<vtkCoordinate> normCoords = vtkSmartPointer<vtkCoordinate>::New(); normCoords->SetCoordinateSystemToView(); v1mmMapper->SetTransformCoordinate( normCoords ); // just for test vtkCoordinate *cd = v1mmMapper->GetTransformCoordinate(); assert( nullptr != cd ); printf( "GetCoordinateSystemAsString: %s\n", cd->GetCoordinateSystemAsString() ); double linePoint1[3] = { 0, -1, 0.0 }; double linePoint2[3] = { 0, 1, 0.0 }; vtkIdType pointId1 = v1mmPoints->InsertNextPoint(linePoint1); vtkIdType pointId2 = v1mmPoints->InsertNextPoint(linePoint2); vtkIdType lineIds[2] = { pointId1, pointId2 }; v1mmLines->InsertNextCell(2, lineIds); linePoint1[0] = -1; linePoint1[1] = 0; linePoint1[2] = 0; linePoint2[0] = 1; linePoint2[1] = 0; linePoint2[2] = 0; lineIds[0] = v1mmPoints->InsertNextPoint(linePoint1); lineIds[1] = v1mmPoints->InsertNextPoint(linePoint2); v1mmLines->InsertNextCell(2, lineIds); v1mmPolyData->Modified(); // ------------- adding red line finished---------------- renderer->ResetCamera(); renderer->AddActor2D( v1mmLinesActor ); renderWindow->Render(); renderWindowInteractor->Start(); return 0; }
我們也可以使用viewport座標系來繪圖。
改動的程式碼只有vtkCoordinate的座標系統設定以及線段兩端點的位置設定。
因為view的座標範圍是[0,1],而viewport的座標對應著畫素值,所以我們需要使用renderWindow->GetSize();
獲取窗體的畫素尺寸。
vtkSmartPointer<vtkCoordinate> normCoords = vtkSmartPointer<vtkCoordinate>::New(); normCoords->SetCoordinateSystemToViewport(); v1mmMapper->SetTransformCoordinate( normCoords ); // just for test vtkCoordinate *cd = v1mmMapper->GetTransformCoordinate(); assert( nullptr != cd ); printf( "GetCoordinateSystemAsString: %s\n", cd->GetCoordinateSystemAsString() ); renderWindow->Render(); //after render, window's size is not (0, 0) any more. int *size = renderWindow->GetSize(); printf( "size: %d, %d\n", size[0], size[1] ); // viewport origin point is at left-bottom corner. double linePoint1[3] = { size[0]/2.0, 0, 0.0 }; double linePoint2[3] = { size[0]/2.0, size[1] * 1.0, 0.0 }; vtkIdType pointId1 = v1mmPoints->InsertNextPoint(linePoint1); vtkIdType pointId2 = v1mmPoints->InsertNextPoint(linePoint2); vtkIdType lineIds[2] = { pointId1, pointId2 }; v1mmLines->InsertNextCell(2, lineIds); linePoint1[0] = 0; linePoint1[1] = size[1] / 2; linePoint1[2] = 0; linePoint2[0] = size[0]; linePoint2[1] = size[1] / 2; linePoint2[2] = 0; lineIds[0] = v1mmPoints->InsertNextPoint(linePoint1); lineIds[1] = v1mmPoints->InsertNextPoint(linePoint2); v1mmLines->InsertNextCell(2, lineIds); v1mmPolyData->Modified(); // ------------- adding red line finished----------------
顯示結果和view系統一樣。 圖略。 在放大窗體後,view座標裡面的紅線仍然佈滿整個窗體,但是viewport裡的紅線因為最初設定的寸尺比改變後的窗體寸尺小,所以就會有這樣的放大效果:
如果不為render設定viewport,viewport和display的效果是一樣的
//normCoords->SetCoordinateSystemToViewport();
normCoords->SetCoordinateSystemToDisplay();
但是,我們如果設定了viewport,那麼差異就出現了: 在新增red line的程式碼塊之前寫上如下程式碼
renderer->SetViewport( 0.0, 0.0, 0.5, 1.0 );
效果: