基於三維模型的任意平面分割

#include "vtkPlane.h"
#include "vtkProperty.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkContourFilter.h"
#include "vtkSmartPointer.h"
#include "vtkPolyDataNormals.h"
#include "vtkPolyDataMapper.h"
#include "vtkActor.h"
#include "vtkOutlineFilter.h"
#include "vtkStripper.h"
#include "vtkCamera.h"
#include "vtkSmoothPolyDataFilter.h"
#include <vtkImagePlaneWidget.h>
#include <vtkInteractorStyleTrackballActor.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include "vtkActor.h"
#include <vtkSmartPointer.h>
#include <vtkMetaImageReader.h>
using namespace std;
#include "vtkImplicitPlaneWidget.h"
#include "vtkClipPolyData.h"

#include <vtkAutoInit.h>
VTK_AUTOINIT_DECLARE(vtkRenderingOpenGL2) static struct vtkRenderingOpenGL2_ModuleInit
{
    vtkRenderingOpenGL2_ModuleInit() { VTK_AUTOINIT_CONSTRUCT(vtkRenderingOpenGL2) }
    ~vtkRenderingOpenGL2_ModuleInit() { VTK_AUTOINIT_DESTRUCT(vtkRenderingOpenGL2) }
} vtkRenderingOpenGL2_ModuleInit_Instance;;
// VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkInteractionStyle);

class BuildVTKWidgetCall : public vtkCommand
{
public:

    static BuildVTKWidgetCall *New()
    {
        return new BuildVTKWidgetCall;
    }
public:
    virtual void Execute(vtkObject *caller, unsigned long eventId, void *callData)
    {
        vtkImplicitPlaneWidget *pWidget = reinterpret_cast<vtkImplicitPlaneWidget*>(caller);
        if (pWidget)
        {
            vtkSmartPointer<vtkPlane> planeNew = vtkPlane::New();
            pWidget->GetPlane(planeNew);

            cliper->SetClipFunction(planeNew);
            cliper->Update();

            vtkSmartPointer<vtkPolyData> clipedData = vtkPolyData::New();
            clipedData->DeepCopy(cliper->GetOutput());

            vtkSmartPointer<vtkPolyDataMapper> coneMapper = vtkPolyDataMapper::New();
            coneMapper->SetInputData(clipedData);
            coneMapper->ScalarVisibilityOff();
            actor->SetMapper(coneMapper);
        }
    }
    void setCliper(vtkSmartPointer<vtkClipPolyData> other) { cliper = other; }
    void setPlane(vtkSmartPointer<vtkPlane> other) { pPlane = other; }
    void setActor(vtkSmartPointer<vtkActor> other) { actor = other; }
private:
    vtkSmartPointer<vtkPlane> pPlane;
    vtkSmartPointer<vtkActor> actor;
    vtkSmartPointer<vtkClipPolyData> cliper;
};




int main()
{
    vtkSmartPointer<vtkRenderer> aRenderer = vtkSmartPointer<vtkRenderer>::New();
    //aRenderer->SetViewport(0, 0.0, 0.5, 1.0);
    vtkSmartPointer<vtkRenderWindow> renWin = vtkSmartPointer<vtkRenderWindow>::New();
    renWin->AddRenderer(aRenderer);

    vtkSmartPointer<vtkRenderWindowInteractor> iren =
        vtkSmartPointer<vtkRenderWindowInteractor>::New();
    iren->SetRenderWindow(renWin);

    vtkSmartPointer<vtkMetaImageReader> Reader = vtkSmartPointer<vtkMetaImageReader>::New();
    //vtkSmartPointer<vtkNrrdReader> Reader =vtkSmartPointer<vtkNrrdReader>::New();
    Reader->SetFileName("/root/vtkExample/Examples/Chap02/data/head.mhd"/*"/Users/mac/Desktop/Pic13.nrrd"*/);   //讀血管mhd或者mha文件
    Reader->Update();
    if (!Reader->GetOutputPort())
    {
        cout << "open failed" << endl;
    }
    cout << "讀取數據完成" << endl;

    vtkSmartPointer<vtkContourFilter> skinExtractor =
        vtkSmartPointer<vtkContourFilter>::New();
    skinExtractor->SetInputConnection(Reader->GetOutputPort());
    skinExtractor->SetValue(0, 1);    //值越大,保留的部分越少。

                                      /**做平滑處理**/
    vtkSmartPointer<vtkSmoothPolyDataFilter> smooth = vtkSmoothPolyDataFilter::New();
    smooth->SetInputConnection(skinExtractor->GetOutputPort());
    smooth->SetNumberOfIterations(100);

    //重新計算法向量
    vtkSmartPointer<vtkPolyDataNormals> skinNormals =
        vtkSmartPointer<vtkPolyDataNormals>::New();

    skinNormals->SetInputConnection(smooth->GetOutputPort());
    skinNormals->SetFeatureAngle(180);

    vtkSmartPointer<vtkStripper> skinStripper =        //create triangle strips and/or poly-lines 爲了更快的顯示速度
        vtkSmartPointer<vtkStripper>::New();
    skinStripper->SetInputConnection(skinNormals->GetOutputPort());

    vtkSmartPointer<vtkPolyDataMapper> skinMapper =
        vtkSmartPointer<vtkPolyDataMapper>::New();
    skinMapper->SetInputConnection(skinStripper->GetOutputPort());
    skinMapper->ScalarVisibilityOff();    //這樣不會帶顏色

    vtkSmartPointer<vtkActor> skin =
        vtkSmartPointer<vtkActor>::New();
    skin->SetMapper(skinMapper);

    vtkSmartPointer<vtkOutlineFilter> outlineData =
        vtkSmartPointer<vtkOutlineFilter>::New();
    outlineData->SetInputConnection(Reader->GetOutputPort());

    vtkSmartPointer<vtkPolyDataMapper> mapOutline =
        vtkSmartPointer<vtkPolyDataMapper>::New();
    mapOutline->SetInputConnection(outlineData->GetOutputPort());

    vtkSmartPointer<vtkActor> outline =
        vtkSmartPointer<vtkActor>::New();
    outline->SetMapper(mapOutline);
    outline->GetProperty()->SetColor(0, 0, 0);

    vtkSmartPointer<vtkCamera> aCamera =
        vtkSmartPointer<vtkCamera>::New();
    aCamera->SetViewUp(0, 0, -1);
    aCamera->SetPosition(0, 1, 0);
    aCamera->SetFocalPoint(0, 0, 0);
    aCamera->ComputeViewPlaneNormal();
    aCamera->Azimuth(30.0);
    aCamera->Elevation(30.0);
    aCamera->Dolly(1.5);
    aRenderer->AddActor(outline);
    aRenderer->AddActor(skin);
    aRenderer->SetActiveCamera(aCamera);
    aRenderer->ResetCamera();
    aRenderer->SetBackground(0.2, 0.3, 0.4);
    aRenderer->ResetCameraClippingRange();

    renWin->SetSize(1000, 1000);

    vtkSmartPointer<vtkInteractorStyleTrackballCamera> style =
        vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
    iren->SetInteractorStyle(style);

    /////////設置截面
    vtkSmartPointer<vtkClipPolyData> cliper = vtkClipPolyData::New();
    cliper->SetInputData(skinStripper->GetOutput());

    // 此平面box可以通過右鍵來進行放大縮小處理(只有當鼠標控制區域只有切割體才單一有效)
    vtkSmartPointer<vtkImplicitPlaneWidget> implicitPlaneWidget = vtkImplicitPlaneWidget::New();
    implicitPlaneWidget->SetInteractor(iren);
    implicitPlaneWidget->SetPlaceFactor(1.25);
    //initially position the widget
    implicitPlaneWidget->SetInputData(skinStripper->GetOutput());
    implicitPlaneWidget->PlaceWidget();

    //////Render2
    vtkSmartPointer<vtkActor> coneSkinActor = vtkActor::New();
    coneSkinActor->SetMapper(skinMapper);

    //截取後的圖片在右側顯示
    vtkSmartPointer<vtkRenderer> rRenderer =
        vtkSmartPointer<vtkRenderer>::New();
    rRenderer->SetBackground(0.2, 0.3, 0.5);
    rRenderer->SetViewport(0.5, 0.0, 1.0, 1.0);
    rRenderer->AddActor(coneSkinActor);
    renWin->AddRenderer(rRenderer);

    vtkSmartPointer<BuildVTKWidgetCall> pCall = BuildVTKWidgetCall::New();
    pCall->setActor(coneSkinActor);
    pCall->setCliper(cliper);


    ///////

    implicitPlaneWidget->AddObserver(vtkCommand::EndInteractionEvent, pCall);
    implicitPlaneWidget->On();
    // Render
    renWin->Render();
    // Initialize the event loop and then start it.
    iren->Initialize();

    iren->Start();
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章