VTK 体渲染(2)

#include <iostream>
#include <vtkSmartPointer.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkBoxRepresentation.h>
#include <vtkBoxWidget2.h>
#include <vtkCamera.h>
#include <vtkColorTransferFunction.h>
#include <vtkCommand.h>
#include <vtkDICOMImageReader.h>
#include <vtkGPUVolumeRayCastMapper.h>
#include <vtkFixedPointVolumeRayCastMapper.h>
#include <vtkImageData.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkMath.h>
#include <vtkPiecewiseFunction.h>
#include <vtkPlanes.h>
#include <vtkVolume.h>
#include <vtkVolumeProperty.h>
#include <vtkInteractorStyle.h>
#include <vtkAxesActor.h>

using namespace std;

// Box interaction callback
class vtkBoxCallback:public vtkCommand{
    //
public:
    static vtkBoxCallback *New(){return new vtkBoxCallback;}
    vtkGPUVolumeRayCastMapper *m_mapper;
    vtkPlanes *m_planes;

    virtual void Execute(vtkObject *caller, unsigned long eventId, void *callData){
        //
        vtkBoxWidget2 *l_box_wdget=vtkBoxWidget2::SafeDownCast(caller);
        ((vtkBoxRepresentation*)l_box_wdget->GetRepresentation())->GetPlanes(m_planes);
        this->m_mapper->SetClippingPlanes(m_planes);
    }
    vtkBoxCallback(){}
};



int main(int argc,char* argv[])
{
    //cout << "Hello World!" << endl;
    if(argc!=2){
        cout<<"Usage : "<<argv[0]<<" Dicom dir"<<endl;
        return -1;
    }
    // Read volume
    vtkSmartPointer<vtkDICOMImageReader> reader=vtkSmartPointer<vtkDICOMImageReader>::New();
    reader->SetDirectoryName(argv[1]);
    reader->Update();

    vtkSmartPointer<vtkRenderer> ren=vtkSmartPointer<vtkRenderer>::New();
    ren->SetBackground(0.3,0.3,0.3);
    vtkSmartPointer<vtkRenderWindow> renWin=vtkSmartPointer<vtkRenderWindow>::New();
    renWin->AddRenderer(ren);
    renWin->SetSize(1000,1000);
    vtkSmartPointer<vtkInteractorStyleTrackballCamera> style=vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
    vtkSmartPointer<vtkRenderWindowInteractor> iren=vtkSmartPointer<vtkRenderWindowInteractor>::New();
    iren->SetInteractorStyle(style);
    iren->SetRenderWindow(renWin);
    iren->GetInteractorStyle()->SetDefaultRenderer(ren);
    iren->SetDesiredUpdateRate(15);

    // Setup GPU volume raycast mapper
    vtkSmartPointer<vtkGPUVolumeRayCastMapper> gpuMapper=vtkSmartPointer<vtkGPUVolumeRayCastMapper>::New();
    gpuMapper->SetInputConnection(reader->GetOutputPort());
    //vtkSmartPointer<vtkFixedPointVolumeRayCastMapper> cpuMapper=vtkSmartPointer<vtkFixedPointVolumeRayCastMapper>::New();
    //cpuMapper->SetInputConnection(reader->GetOutputPort());
    //cpuMapper->SetNumberOfThreads(4);

    // Setup Volume property
    // Window/Level
    double wl=35;
    double ww=350;

    // Window & Level
    // Organs      Window     Level
    // Brain       190         50
    // Skull       2000        500
    // Abdomen     400         35
    // Liver       175         45
    // Lung        2000        -500


    // Color function
    vtkSmartPointer<vtkColorTransferFunction> color=vtkSmartPointer<vtkColorTransferFunction>::New();
    color->SetColorSpaceToRGB();
    color->AddRGBPoint(wl-ww/2,0,0,0);
    color->AddRGBPoint(wl-ww/2+94*(ww/255.0),1,21/255.0,27/255.0);
    color->AddRGBPoint(wl-ww/2+147*(ww/255.0),1,176/255.0,9/255.0);
    color->AddRGBPoint(wl-ww/2+201*(ww/255.0),1,241/255.0,39/255.0);
    color->AddRGBPoint(wl-ww/2+255*(ww/255.0),1,1,1);
    color->Build();
    // Opacity function
    vtkSmartPointer<vtkPiecewiseFunction> opacity=vtkSmartPointer<vtkPiecewiseFunction>::New();
    opacity->AddPoint(wl-ww/2,0);
    opacity->AddPoint(wl+ww/2,1);

    // Volume property, light and shading
    vtkSmartPointer<vtkVolumeProperty> volumeproperty=vtkSmartPointer<vtkVolumeProperty>::New();
    volumeproperty->SetColor(color);
    volumeproperty->SetScalarOpacity(opacity);
    volumeproperty->SetInterpolationTypeToLinear();
    volumeproperty->ShadeOn();
    volumeproperty->SetAmbient(0.15);
    volumeproperty->SetDiffuse(0.8);
    volumeproperty->SetSpecular(0.25);
    volumeproperty->SetSpecularPower(40);

    vtkSmartPointer<vtkAxesActor> axes=vtkSmartPointer<vtkAxesActor>::New();
    axes->SetOrigin(0,0,0);
    axes->SetTotalLength(100,100,100);
    //axes->AxisLabelsOff();

    // Put everything together
    vtkSmartPointer<vtkVolume> volume=vtkSmartPointer<vtkVolume>::New();
    volume->SetProperty(volumeproperty);
    volume->SetMapper(gpuMapper);
    //volume->SetMapper(cpuMapper);

    ren->AddVolume(volume);
    ren->AddActor(axes);
    ren->ResetCamera();
    // Setup Box interactive widget
    vtkSmartPointer<vtkBoxRepresentation> boxRep=vtkSmartPointer<vtkBoxRepresentation>::New();
    boxRep->SetInsideOut(true);

    vtkSmartPointer<vtkBoxWidget2> voi_widget=vtkSmartPointer<vtkBoxWidget2>::New();
    voi_widget->SetRepresentation(boxRep);
    voi_widget->SetInteractor(iren);
    voi_widget->GetRepresentation()->SetPlaceFactor(1);
    voi_widget->GetRepresentation()->PlaceWidget(reader->GetOutput()->GetBounds());
    voi_widget->SetEnabled(true);

    vtkSmartPointer<vtkPlanes> planes=vtkSmartPointer<vtkPlanes>::New();
    vtkSmartPointer<vtkBoxCallback> callback=vtkSmartPointer<vtkBoxCallback>::New();
    callback->m_mapper=gpuMapper;
    //callback->m_mapper=cpuMapper;
    callback->m_planes=planes;
    voi_widget->AddObserver(vtkCommand::InteractionEvent,callback);
    iren->Initialize();
    iren->Start();



    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值