搬运vtkImageViewer2
最近堕落的有点严重,带薪划水,没有动力,上周基本没有啥实际进展,改了两个微乎其微的小BUG。这几天其实也不知道该从哪里下手了。所以一直也在搁置中。不过还是研究了一部分东西的,就是在家没事看了下Qt的自定义控件的属性定义等。感兴趣的可以看这里
今天研究的代码是vtk官方的vtkImageViewer2
。也是先抄一遍,看看有没有可以修改的地方。其实在这几天中,我已经搞了一部分了,就是开始计划是他移植到我的BPPMPRWidget
中,也是想把它和QVTKOpenGLNativeWidget
弄在一起,后面有觉得不合理,还是分开比较合适,所以就还是先分开来抄。
搬运vtkImageViewer2
这里没有啥好说的,基本就是抄,改名呗。
#ifndef IMAGEPIPELINE_H
#define IMAGEPIPELINE_H
#include <QObject>
#include <vtkObject.h>
class vtkAlgorithm;
class vtkAlgorithmOutput;
class vtkImageActor;
class vtkImageData;
class vtkImageMapToWindowLevelColors;
class vtkInformation;
class vtkInteractorStyleImage;
class vtkRenderWindow;
class vtkRenderer;
class vtkRenderWindowInteractor;
class ImagePipeLine : public vtkObject
{
public:
static ImagePipeLine* New();
vtkTypeMacro(ImagePipeLine,vtkObject);
/**
* @brief getWindowName
* @return
* 获取窗口名称
*/
virtual const char* getWindowName();
/**
* @brief Render
* 开始渲染图像
*/
virtual void render();
/**
* @brief getInput
* @return
* 获取输入数据
*/
virtual vtkImageData* getInput();
/**
* @brief setInputData
* @param in
* 设置输入数据
*/
virtual void setInputData(vtkImageData* in);
/**
* @brief setInputConnection
* @param input
* 设置输入数据
*/
virtual void setInputConnection(vtkAlgorithmOutput* input);
/**
* 切片方向
*/
enum
{
SLICE_ORIENTATION_YZ = 0,
SLICE_ORIENTATION_XZ = 1,
SLICE_ORIENTATION_XY = 2
};
int getSliceOrientation();
/**
* @brief ImagePipeLine::setSliceOrientation
* @param orientation
* 设置切片方向
*/
virtual void setSliceOrientation(int orientation);
/**
* @brief setSliceOrientationToXY
* 设置切片方向
*/
virtual void setSliceOrientationToXY();
/**
* @brief setSliceOrientationToXY
* 设置切片方向
*/
virtual void setSliceOrientationToYZ();
/**
* @brief setSliceOrientationToXY
* 设置切片方向
*/
virtual void setSliceOrientationToXZ();
/**
* @brief updateDisplayExtent
* 更新显示
*/
virtual void updateDisplayExtent();
/**
* @brief getSliceMin
* @return
* 获取最小切片
*/
virtual int getSliceMin();
/**
* @brief getSliceMax
* @return
* 获取最大切片
*/
virtual int getSliceMax();
/**
* @brief getSliceRange
* @param range
* 获取切片范围
*/
virtual void getSliceRange(int range[2]);
/**
* @brief getSliceRange
* @param min
* @param max
* 获取切片范围
*/
virtual void getSliceRange(int& min, int& max);
/**
* @brief getSliceRange
* @return
* 获取切片范围
*/
virtual int* getSliceRange();
/**
* @brief getColorWindow
* @return
* 获取窗宽
*/
virtual double getColorWindow();
/**
* @brief getColorLevel
* @return
* 获取窗位
*/
virtual double getColorLevel();
/**
* @brief setColorWindow
* @param s
* 设置窗宽
*/
virtual void setColorWindow(double s);
/**
* @brief setColorLevel
* @param s
* 设置窗位
*/
virtual void setColorLevel(double s);
/**
* These are here when using a Tk window.
*/
virtual void setDisolayId(void* a);
virtual void setWindowId(void* a);
virtual void setParentId(void* a);
/**
* @brief getPosition
* @return
* 获取图像位置
*/
virtual int* getPosition();
virtual void setPosition(int x,int y);
virtual void setPosition(int a[2]);
virtual int* getSize();
virtual void setSize(int width,int height);
virtual void setSize(int a[2]);
/**
* @brief ImagePipeLine::setRenderWindow
* @param arg
* 设置渲染窗口
*/
virtual void setRenderWindow(vtkRenderWindow* arg);
/**
* @brief ImagePipeLine::setRenderer
* @param arg
* 设置渲染器
*/
virtual void setRenderer(vtkRenderer* arg);
/**
* @brief getRenderWindow
* @return
* 获取渲染窗口
*/
vtkRenderWindow* getRenderWindow();
/**
* @brief getRenderer
* @return
* 获取渲染器
*/
vtkRenderer* getRenderer();
/**
* @brief getImageActor
* @return
* 获取演员
*/
vtkImageActor* getImageActor();
/**
* @brief getWindowLevel
* @return
* 获取图像信息
*/
vtkImageMapToWindowLevelColors* getWindowLevel();
/**
* @brief getInteratorStyle
* @return
* 获取交互器
*/
vtkInteractorStyleImage* getInteratorStyle();
/**
* @brief setupInteractor
* @param arg
* 设置交互器
*/
virtual void setupInteractor(vtkRenderWindowInteractor*arg);
virtual void setOffScreenRendering(vtkTypeBool i);
virtual vtkTypeBool getOffScreenRendering();
virtual void offScreenRenderingOn();
virtual void offScreenRenderingOff();
protected:
ImagePipeLine();
~ImagePipeLine() override;
/**
* @brief updateOrientation
* 设置相机位置
*/
virtual void updateOrientation();
/**
* @brief getInputAlgorithm
* @return
*/
vtkAlgorithm* getInputAlgorithm();
/**
* @brief getInputInformation
* @return
*/
vtkInformation* getInputInformation();
/**
* @brief installPipeline
* 安装流水线
*/
virtual void installPipeline();
/**
* @brief unInstallPipeline
* 卸载流水线
*/
virtual void unInstallPipeline();
protected:
vtkImageMapToWindowLevelColors* WindowLevel;
vtkRenderWindow* RenderWindow;
vtkRenderer* Renderer;
vtkImageActor* ImageActor;
vtkRenderWindowInteractor* Interactor;
vtkInteractorStyleImage* InteractorStyle;
int SliceOrientation;
int FirstRender;
int Slice;
friend class ImagePipeLineCallback;
signals:
private:
ImagePipeLine(const ImagePipeLine&) = delete;
void operator=(const ImagePipeLine&) = delete;
};
#endif // IMAGEPIPELINE_H
#include "imagepipeline.h"
#include "vtkCamera.h"
#include "vtkCommand.h"
#include "vtkImageActor.h"
#include "vtkImageData.h"
#include "vtkImageMapToWindowLevelColors.h"
#include "vtkImageMapper3D.h"
#include "vtkInformation.h"
#include "vtkInteractorStyleImage.h"
#include "vtkObjectFactory.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkRenderer.h"
#include "vtkStreamingDemandDrivenPipeline.h"
class ImagePipeLineCallback : public vtkCommand
{
public:
static ImagePipeLineCallback* New()
{
return new ImagePipeLineCallback;
}
void Execute(vtkObject* caller,unsigned long event,void* vtkNotUsed(callData)) override
{
if(this->IV->getInput() == nullptr)
{
return;
}
if(event == vtkCommand::ResetWindowLevelEvent)
{
this->IV->getInputAlgorithm()->UpdateWholeExtent();
double* range = this->IV->getInput()->GetScalarRange();
this->IV->setColorWindow(range[1] - range[0]);
this->IV->setColorLevel(0.5 * (range[1] + range[0]));
this->IV->render();
return;
}
if(event == vtkCommand::StartWindowLevelEvent)
{
this->InitialWindow = this->IV->getColorWindow();
this->InitialLevel = this->IV->getColorLevel();
return;
}
vtkInteractorStyleImage* isi = static_cast<vtkInteractorStyleImage*>(caller);
const int* size = this->IV->getRenderWindow()->GetSize();
double window = this->InitialWindow;
double level = this->InitialLevel;
double dx = 4.0 * (isi->GetWindowLevelCurrentPosition()[0] - isi->GetWindowLevelStartPosition()[0]) / size[0];
double dy = 4.0 * (isi->GetWindowLevelStartPosition()[1] - isi->GetWindowLevelCurrentPosition()[1]) / size[1];
if(fabs(window) > 0.01)
dx = dx * window;
else
dx = dx * (window < 0 ? -0.01 : 0.01);
if(fabs(level) > 0.01)
dy = dy * level;
else
dy = dy * (level < 0 ? -0.01 : 0.01);
if(window < 0.01)
dx = -1 * dx;
if(level < 0.01)
dy = -1 * dy;
double newWindow = dx + window;
double newLevel = level -dy;
if(fabs(newWindow) < 0.01)
newWindow = 0.01 * (newWindow < 0 ? -1 :1);
if(fabs(newLevel) < 0.01)
newLevel = 0.01 * (newLevel < 0 ? -1 : 1);
this->IV->setColorWindow(newWindow);
this->IV->setColorLevel(newLevel);
this->IV->render();
}
ImagePipeLine* IV;
double InitialWindow;
double InitialLevel;
};
vtkStandardNewMacro(ImagePipeLine);
/**
* @brief getWindowName
* @return
* 获取窗口名称
*/
const char *ImagePipeLine::getWindowName()
{
return this->RenderWindow->GetWindowName();
}
/**
* @brief Render
* 开始渲染图像
*/
void ImagePipeLine::render()
{
if(this->FirstRender)
{
vtkAlgorithm* input = this->getInputAlgorithm();
if(input)
{
input->UpdateInformation();
int* w_ext = this->getInputInformation()->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT());
int xs = 0,ys = 0;
switch (this->SliceOrientation){
case ImagePipeLine::SLICE_ORIENTATION_XY:
default:
xs = w_ext[1] - w_ext[0] + 1;
ys = w_ext[3] - w_ext[2] +1;
break;
case ImagePipeLine::SLICE_ORIENTATION_XZ:
xs = w_ext[1] - w_ext[0] + 1;
ys = w_ext[5] - w_ext[4] +1;
break;
case ImagePipeLine::SLICE_ORIENTATION_YZ:
xs = w_ext[3] - w_ext[2] + 1;
ys = w_ext[5] - w_ext[4] +1;
break;
}
/*
* 如果图像尺寸小于150*100,那么强制把图像尺寸设置为150*100
*/
if(this->RenderWindow->GetSize()[0] == 0)
{
this->RenderWindow->SetSize(xs < 150 ? 150 : xs, ys < 100 ? 100 : ys);
}
if(this->Renderer)
{
this->Renderer->ResetCamera();
this->Renderer->GetActiveCamera()->SetParallelScale(xs < 150 ? 75 : (xs - 1) / 2.0);
}
this->FirstRender = 0;
}
}
if(this->getInput())
{
this->RenderWindow->Render();
}
}
/**
* @brief getInput
* @return
* 获取输入数据
*/
vtkImageData *ImagePipeLine::getInput()
{
return vtkImageData::SafeDownCast(this->WindowLevel->GetInput());
}
/**
* @brief setInputData
* @param in
* 设置输入数据
*/
void ImagePipeLine::setInputData(vtkImageData *in)
{
this->WindowLevel->SetInputData(in);
this->updateDisplayExtent();
}
/**
* @brief setInputConnection
* @param input
* 设置输入数据
*/
void ImagePipeLine::setInputConnection(vtkAlgorithmOutput *input)
{
this->WindowLevel->SetInputConnection(input);
this->updateDisplayExtent();
}
int ImagePipeLine::getSliceOrientation()
{
return SliceOrientation;
}
/**
* @brief ImagePipeLine::setSliceOrientation
* @param orientation
* 设置切片方向
*/
void ImagePipeLine::setSliceOrientation(int orientation)
{
if(orientation < ImagePipeLine::SLICE_ORIENTATION_YZ || orientation > ImagePipeLine::SLICE_ORIENTATION_XY)
return;
if(this->SliceOrientation == orientation)
return;
this->SliceOrientation = orientation;
int* range = this->getSliceRange();
if(range)
this->Slice = static_cast<int>((range[0] + range[1]) * 0.5);
this->updateOrientation();
this->updateDisplayExtent();
if(this->Renderer && this->getInput())
{
double scale = this->Renderer->GetActiveCamera()->GetParallelScale();
this->Renderer->ResetCamera();
this->Renderer->GetActiveCamera()->SetParallelScale(scale);
}
this->render();
}
void ImagePipeLine::setSliceOrientationToXY()
{
this->setSliceOrientation(ImagePipeLine::SLICE_ORIENTATION_XY);
}
void ImagePipeLine::setSliceOrientationToYZ()
{
this->setSliceOrientation(ImagePipeLine::SLICE_ORIENTATION_YZ);
}
void ImagePipeLine::setSliceOrientationToXZ()
{
this->setSliceOrientation(ImagePipeLine::SLICE_ORIENTATION_XZ);
}
void ImagePipeLine::updateDisplayExtent()
{
vtkAlgorithm* input = this->getInputAlgorithm();
if(!input || this->ImageActor)
return;
input->UpdateInformation();
vtkInformation* outInfo = input->GetOutputInformation(0);
int* w_ext = outInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT());
/*
* 判断切片是否在范围之内,如果不在,则修复
*/
int slice_min = w_ext[this->SliceOrientation *2];
int slice_max = w_ext[this->SliceOrientation *2 + 1];
if(this->Slice < slice_min || this->Slice > slice_max)
this->Slice = static_cast<int>((slice_min + slice_max) * 0.5);
/*
* 设置图像Actor
*/
switch (this->SliceOrientation) {
case ImagePipeLine::SLICE_ORIENTATION_XY:
this->ImageActor->SetDisplayExtent(w_ext[0],w_ext[1],w_ext[2],w_ext[3],this->Slice,this->Slice);
break;
case ImagePipeLine::SLICE_ORIENTATION_XZ:
this->ImageActor->SetDisplayExtent(w_ext[0],w_ext[1],this->Slice,this->Slice,w_ext[4],w_ext[5]);
break;
case ImagePipeLine::SLICE_ORIENTATION_YZ:
this->ImageActor->SetDisplayExtent(this->Slice,this->Slice,w_ext[2],w_ext[3],w_ext[4],w_ext[5]);
break;
}
/*
* 找出正确的裁剪范围
*/
if(this->Renderer)
{
if(this->InteractorStyle && this->InteractorStyle->GetAutoAdjustCameraClippingRange())
{
this->Renderer->ResetCameraClippingRange();
}
else
{
vtkCamera* cam = this->Renderer->GetActiveCamera();
if(cam)
{
double bounds[6];
this->ImageActor->GetBounds(bounds);
double spos = bounds[this->SliceOrientation * 2];
double cpos = cam->GetPosition()[this->SliceOrientation];
double range = fabs(spos - cpos);
double* spacing = outInfo->Get(vtkDataObject::SPACING());
double avg_spacing = (spacing[0] + spacing[1] + spacing[2]) / 3.0;
cam->SetClippingRange(range - avg_spacing * 3.0,range + avg_spacing * 3.0);
}
}
}
}
int ImagePipeLine::getSliceMin()
{
int* range = this->getSliceRange();
if(range)
{
return range[0];
}
return 0;
}
int ImagePipeLine::getSliceMax()
{
int* range = this->getSliceRange();
if(range)
{
return range[1];
}
return 0;
}
void ImagePipeLine::getSliceRange(int range[])
{
this->getSliceRange(range[0], range[1]);
}
void ImagePipeLine::getSliceRange(int &min, int &max)
{
vtkAlgorithm* input = this->getInputAlgorithm();
if(input)
{
input->UpdateInformation();
int* w_ext = input->GetOutputInformation(0)->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT());
min = w_ext[this->SliceOrientation * 2];
max = w_ext[this->SliceOrientation * 2 +1];
}
}
int *ImagePipeLine::getSliceRange()
{
vtkAlgorithm* input = this->getInputAlgorithm();
if (input)
{
input->UpdateInformation();
return input->GetOutputInformation(0)->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT()) + this->SliceOrientation * 2;
}
return nullptr;
}
double ImagePipeLine::getColorWindow()
{
return this->WindowLevel->GetWindow();
}
double ImagePipeLine::getColorLevel()
{
return this->WindowLevel->GetLevel();
}
void ImagePipeLine::setColorWindow(double s)
{
if(this->WindowLevel)
WindowLevel->SetWindow(s);
}
void ImagePipeLine::setColorLevel(double s)
{
if(this->WindowLevel)
WindowLevel->SetLevel(s);
}
void ImagePipeLine::setDisolayId(void *a)
{
this->RenderWindow->SetDisplayId(a);
}
void ImagePipeLine::setWindowId(void *a)
{
this->RenderWindow->SetWindowId(a);
}
void ImagePipeLine::setParentId(void *a)
{
this->RenderWindow->SetParentId(a);
}
int *ImagePipeLine::getPosition()
{
return this->RenderWindow->GetPosition();
}
void ImagePipeLine::setPosition(int x, int y)
{
this->RenderWindow->SetPosition(x,y);
}
void ImagePipeLine::setPosition(int a[])
{
this->setPosition(a[0],a[1]);
}
int *ImagePipeLine::getSize()
{
return this->RenderWindow->GetSize();
}
void ImagePipeLine::setSize(int width, int height)
{
this->RenderWindow->SetSize(width,height);
}
void ImagePipeLine::setSize(int a[])
{
this->setSize(a[0],a[1]);
}
/**
* @brief ImagePipeLine::setRenderWindow
* @param arg
* 设置渲染窗口
*/
void ImagePipeLine::setRenderWindow(vtkRenderWindow *arg)
{
if(this->RenderWindow == arg)
{
return;
}
this->unInstallPipeline();
if(this->RenderWindow)
{
this->RenderWindow->UnRegister(this);
}
this->RenderWindow = arg;
if(this->RenderWindow)
{
this->RenderWindow->Register(this);
}
this->installPipeline();
}
/**
* @brief ImagePipeLine::setRenderer
* @param arg
* 设置渲染器
*/
void ImagePipeLine::setRenderer(vtkRenderer *arg)
{
if(Renderer == arg)
{
return;
}
this->unInstallPipeline();
if(this->Renderer)
{
Renderer->UnRegister(this);
}
Renderer = arg;
if(this->Renderer)
{
this->Renderer->Register(this);
}
this->installPipeline();
this->updateOrientation();
}
/**
* @brief getRenderWindow
* @return
* 获取渲染窗口
*/
vtkRenderWindow *ImagePipeLine::getRenderWindow()
{
return this->RenderWindow;
}
vtkRenderer *ImagePipeLine::getRenderer()
{
return this->Renderer;
}
vtkImageActor *ImagePipeLine::getImageActor()
{
return this->ImageActor;
}
vtkImageMapToWindowLevelColors *ImagePipeLine::getWindowLevel()
{
return this->WindowLevel;
}
vtkInteractorStyleImage *ImagePipeLine::getInteratorStyle()
{
return this->InteractorStyle;
}
void ImagePipeLine::setupInteractor(vtkRenderWindowInteractor *arg)
{
if(this->Interactor == arg)
return;
this->unInstallPipeline();
if(this->Interactor)
this->Interactor->UnRegister(this);
this->Interactor = arg;
if(this->Interactor)
this->Interactor->Register(this);
this->installPipeline();
if(this->Renderer)
this->Renderer->GetActiveCamera()->ParallelProjectionOn();
}
void ImagePipeLine::setOffScreenRendering(vtkTypeBool i)
{
this->RenderWindow->SetOffScreenRendering(i);
}
vtkTypeBool ImagePipeLine::getOffScreenRendering()
{
return this->RenderWindow->GetOffScreenRendering();
}
void ImagePipeLine::offScreenRenderingOn()
{
this->setOffScreenRendering(static_cast<vtkTypeBool>(1));
}
void ImagePipeLine::offScreenRenderingOff()
{
this->setOffScreenRendering(static_cast<vtkTypeBool>(0));
}
/**
* @brief ImagePipeLine::ImagePipeLine
* 构造函数
*/
ImagePipeLine::ImagePipeLine()
{
this->RenderWindow = nullptr;
this->Renderer = nullptr;
this->ImageActor = vtkImageActor::New();
this->WindowLevel = vtkImageMapToWindowLevelColors::New();
this->Interactor = nullptr;
this->InteractorStyle = nullptr;
this->Slice = 0;
this->FirstRender = 1;
this->SliceOrientation = ImagePipeLine::SLICE_ORIENTATION_XY;
/*
* 设置流水线
*/
vtkRenderWindow* renwin = vtkRenderWindow::New();
this->setRenderWindow(renwin);
renwin->Delete();
vtkRenderer* ren = vtkRenderer::New();
this->setRenderer(ren);
ren->Delete();
this->installPipeline();
}
/**
* @brief ImagePipeLine::~ImagePipeLine
* 析构函数
*/
ImagePipeLine::~ImagePipeLine()
{
if(this->WindowLevel)
{
this->WindowLevel->Delete();
this->WindowLevel = nullptr;
}
if(this->ImageActor)
{
this->ImageActor->Delete();
this->ImageActor = nullptr;
}
if(this->Renderer)
{
this->Renderer->Delete();
this->Renderer = nullptr;
}
if(this->RenderWindow)
{
this->RenderWindow->Delete();
this->RenderWindow = nullptr;
}
if(this->Interactor)
{
this->Interactor->Delete();
this->Interactor = nullptr;
}
if(this->InteractorStyle)
{
this->InteractorStyle->Delete();
this->InteractorStyle = nullptr;
}
}
/**
* @brief ImagePipeLine::updateOrientation
* 设置相机位置
*/
void ImagePipeLine::updateOrientation()
{
vtkCamera* cam = this->Renderer ? this->Renderer->GetActiveCamera() : nullptr;
if(cam)
{
switch (this->SliceOrientation) {
case ImagePipeLine::SLICE_ORIENTATION_XY:
cam->SetFocalPoint(0,0,0);
cam->SetPosition(0,0,1);
cam->SetViewUp(0,1,0);
break;
case ImagePipeLine::SLICE_ORIENTATION_XZ:
cam->SetFocalPoint(0,0,0);
cam->SetPosition(0,-1,0);
cam->SetViewUp(0,0,1);
break;
case ImagePipeLine::SLICE_ORIENTATION_YZ:
cam->SetFocalPoint(0,0,0);
cam->SetPosition(1,0,0);
cam->SetViewUp(0,0,1);
break;
}
}
}
vtkAlgorithm *ImagePipeLine::getInputAlgorithm()
{
return this->WindowLevel->GetInputAlgorithm();
}
vtkInformation *ImagePipeLine::getInputInformation()
{
return this->WindowLevel->GetInputInformation();
}
/**
* @brief installPipeline
* 安装流水线
*/
void ImagePipeLine::installPipeline()
{
if(this->RenderWindow && this->Renderer)
{
this->RenderWindow->AddRenderer(this->Renderer);
}
if(this->Interactor)
{
if(!this->InteractorStyle)
{
this->InteractorStyle = vtkInteractorStyleImage::New();
ImagePipeLineCallback* cbk = ImagePipeLineCallback::New();
cbk->IV = this;
this->InteractorStyle->AddObserver(vtkCommand::WindowLevelEvent,cbk);
this->InteractorStyle->AddObserver(vtkCommand::StartWindowLevelEvent,cbk);
this->InteractorStyle->AddObserver(vtkCommand::ResetWindowLevelEvent,cbk);
cbk->Delete();
}
this->Interactor->SetInteractorStyle(this->InteractorStyle);
this->Interactor->SetRenderWindow(this->RenderWindow);
}
if(this->Renderer && this->ImageActor)
this->Renderer->AddViewProp(this->ImageActor);
if(this->ImageActor && this->WindowLevel)
this->ImageActor->GetMapper()->SetInputConnection(this->WindowLevel->GetOutputPort());
}
/**
* @brief unInstallPipeline
* 卸载流水线
*/
void ImagePipeLine::unInstallPipeline()
{
if(this->ImageActor)
this->ImageActor->GetMapper()->SetInputConnection(nullptr);
if(this->Renderer && this->ImageActor)
this->Renderer->RemoveViewProp(this->ImageActor);
if(this->RenderWindow && this->Renderer)
this->RenderWindow->RemoveRenderer(this->Renderer);
if(this->Interactor)
{
this->Interactor->SetInteractorStyle(nullptr);
this->Interactor->SetRenderWindow(nullptr);
}
}
调用测试
调用提示也是很简单,在我的控件里面在包一层。如下
先声明两个函数,简单测试一下。
/**
* @brief setInputData
* @param data 输入数据
* 设置输入数据
*/
void setInputData(vtkImageData* data);
/**
* @brief render
* 开始渲染
*/
void render();
实现,更简单,直接在调用子控件的接口就好了,如下:
/**
* @brief setInputData
* @param data 输入数据
* 设置输入数据
*/
void BPPMPRWidget::setInputData(vtkImageData *data)
{
if(m_PipeLine)
m_PipeLine->setInputData(data);
}
/**
* @brief render
* 开始渲染
*/
void BPPMPRWidget::render()
{
if(m_PipeLine)
m_PipeLine->render();
}
需要在构造函数里面实现一个新的子类m_PipeLine
调用方式基本是一致的。如下,上面是正常官方的调用方式,下面是我自己的
/**
* @brief MainWindow::readDicomImage
* @param url
* 读取Dicom文件
*/
void MainWindow::readDicomImageNormal(const char *url)
{
vtkSmartPointer<vtkDICOMImageReader> render = vtkSmartPointer<vtkDICOMImageReader>::New();
render->SetFileName(url);
render->Update();
vtkSmartPointer<vtkImageViewer2> viewer = vtkSmartPointer<vtkImageViewer2>::New();
viewer->SetInputData(render->GetOutput());
viewer->SetRenderWindow(ui->openGLWidget->renderWindow());
viewer->Render();
}
/**
* @brief MainWindow::readDicomImageBPP
* @param url
* 读取Dicom文件
*/
void MainWindow::readDicomImageBPP(const char *url)
{
vtkSmartPointer<vtkDICOMImageReader> render = vtkSmartPointer<vtkDICOMImageReader>::New();
render->SetFileName(url);
render->Update();
// vtkSmartPointer<ImagePipeLine> viewer = vtkSmartPointer<ImagePipeLine>::New();
// viewer->setInputData(render->GetOutput());
// viewer->setRenderWindow(mBPPMPRWidget->renderWindow());
// viewer->render();
mBPPMPRWidget->setInputData(render->GetOutput());
mBPPMPRWidget->render();
}
目前还存在点小问题,会报错,如下图所示
目前虽然知道是哪里出了问题,但是没有找到解决方法。后面将看看能不能集合一下这个东西。