将转换应用于PolyData

时间:2015-06-25 12:23:02

标签: c++ vtk

我希望能够将转换应用于Polydata,但无论我如何尝试,它都无法工作。

这就是我所拥有的" drawing"我的一个类中的polydata调用Drawing.cpp:

Drawing.h

vtkSmartPointer<vtkPlane> clipPlane; 
vtkSmartPointer<vtkImplicitPlaneRepresentation> planeRep; 
vtkSmartPointer<vtkActor> actorPlaneSource; 
vtkSmartPointer<vtkActor> mainActor; 

vtkSmartPointer<vtkTransformPolyDataFilter> transformFilter; 
vtkSmartPointer<vtkTransform> translation ; 
vtkContextView* ctxView ; 
vtkRenderWindow* win ; 
vtkRenderer* ren ; 
vtkCamera* cam ; 
vtkSmartPointer<vtkPolyData> inputPolyData;

然后调用read函数并开始渲染,这是drawing.cpp中的函数:

void Drawing::read(){ 

        std::string filename = BUNNY; 
        // Read all the data from the file 
        vtkSmartPointer<vtkXMLPolyDataReader> reader =vtkSmartPointer<vtkXMLPolyDataReader>::New(); 
        reader->SetFileName(filename.c_str()); 
        reader->Update(); 
        inputPolyData = reader->GetOutput(); 

        cout << "File Found and Loaded : " << filename << endl ; 

        vtkSmartPointer<vtkTransform> translation = vtkSmartPointer<vtkTransform>::New(); 
        translation->Translate(0.3, -0.05, 0); 
        transformFilter = vtkSmartPointer<vtkTransformPolyDataFilter>::New(); 
        //transformFilter->SetInputConnection(reader->GetOutputPort()); 
        transformFilter->SetInputData(inputPolyData); 
        transformFilter->SetTransform(translation); 
        //transformFilter->Update(); 

        vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New(); 
        mapper->SetInputConnection(transformFilter->GetOutputPort()); 

        mainActor = vtkSmartPointer<vtkActor>::New(); 
        mainActor->SetMapper(mapper); 

        ren->AddActor(mainActor); 

        vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New(); 
        iren->SetRenderWindow(win); 
        vtkInteractorStyleMultiTouchCamera *style = 
        vtkInteractorStyleMultiTouchCamera::New(); 
        iren->SetInteractorStyle(style); 

        //Start the event loop 
        iren->Initialize(); 
        iren->Start(); 

        defineClipping(); 
        win->PolygonSmoothingOn(); 
        win->Render(); 
        win->Start(); 
} 

由此,我有一个运行服务器的另一个线程获取消息,并且有一个指向我的绘图对象的指针,并且应该根据它从客户端获得的消息调用这三个函数中的一个:

void Drawing::scale(float k){ 
        vtkSmartPointer<vtkTransform> transform =vtkSmartPointer<vtkTransform>::New(); 
        transform->Scale(5,1,1); 
        vtkSmartPointer<vtkTransformFilter> transformFilter = vtkSmartPointer<vtkTransformFilter>::New(); 
        transformFilter->SetInputConnection(cone->GetOutputPort()); 
        transformFilter->SetTransform(transform); 
        mapper->SetInputConnection(transformFilter->GetOutputPort()); 
        ren->GetActiveCamera(); 
} 

void Drawing::translate(float x, float y, float z){ 
        cout << "Translate: " << x << " - " << " - " << y << " - " << z << endl ; 
        vtkSmartPointer<vtkTransform> transform1a = vtkSmartPointer<vtkTransform>::New(); 
        //transform1a->Translate(x,y,z); 
        //transformFilter->SetTransform(transform1a); 
        //transformFilter->Update(); 
        double* position = mainActor->GetPosition(); 
        mainActor->SetPosition(position[0]+x,position[1]+y,position[2]+z); 
} 

void Drawing::rotate(float x, float y, float z){ 
        cout << "Rotate: " << x << " - " << " - " << y << " - " << z << endl ; 
        vtkSmartPointer<vtkTransform> transform1a = vtkSmartPointer<vtkTransform>::New(); 
        //transform1a->PostMultiply(); 
        //transform1a->RotateX(x); 
        //transform1a->RotateY(y); 
        //transform1a->RotateZ(z); 
        //mainActor->SetUserTransform(transform1a); 
        mainActor->RotateWXYZ(20,1,0,0); 

}

这些功能都不起作用,因为渲染窗口中没有任何变化,除非我单击渲染窗口本身。 所以我想也许我应该尝试添加到每个转换函数:ctxView->Render(); 但当我这样做时,我得到了:

  

资源已经忙碌时出错。

我是VTK的新手,但我觉得奇怪的是我甚至无法对一个对象进行简单的转换。真的很想得到一些帮助。

编辑: 好吧,经过几个小时尝试不同的事情,我注意到如果我注释掉iren->Start();行我的轮换和翻译被调用。但是,程序一完成就会关闭,我无法再与我的窗口交互了。你对此有什么见解吗?

提前致谢。

4 个答案:

答案 0 :(得分:1)

是的,我可以尝试提供一些代码来旋转聚合数据,但我想这与你的管道不同(我使用 vtkImageReslice 对象作为 m_pReslice ):

int nExtent[3];
double dSpacing[3];
double dOrigin[3];

m_pReader->GetOutput()->GetSpacing(dSpacing);
m_pReader->GetOutput()->GetOrigin(dOrigin);
m_pReader->GetOutput()->GetDimensions(nExtent);

double dCenter[3];
dCenter[0] = dOrigin[0] + dSpacing[0] * 0.5 * nExtent[0];   // nExtent[0] is width
dCenter[1] = dOrigin[1] + dSpacing[1] * 0.5 * nExtent[1];   // nExtent[1] is height
dCenter[2] = dOrigin[2] + dSpacing[2] * 0.5 * nExtent[2];   // nExtent[2] is depth

vtkSmartPointer<vtkTransform> pTransform = vtkSmartPointer<vtkTransform>::New();
pTransform->PreMultiply();

int nDirection = CDirectionDlg::GetDirection();
if(CDirectionDlg::DIR_AXIAL == nDirection)
{
    pTransform->Translate(dCenter[0], 0, dCenter[2]);
    pTransform->RotateY(180);
    pTransform->Translate(-dCenter[0], 0, -dCenter[2]);
}
else
{
    pTransform->Translate(dCenter[0], dCenter[1], 0);
    pTransform->RotateZ(180);
    pTransform->Translate(-dCenter[0], -dCenter[1], 0);
}

m_pReslice->SetResliceTransform(pTransform);
m_pReslice->SetInterpolationModeToLinear();
m_pReslice->Update();

考虑在视图中旋转对象的另一种方法是移动相机......我希望它可以帮助你。

答案 1 :(得分:1)

正如flaviu2所写,你绝对需要打电话

ren->Render();
更新vtkTransform后

。渲染器不会观察正在渲染的VTK对象以查看是否有任何更新。您需要显式调用Render()成员函数。

当心线程。可以使用线程,但大多数VTK都不是线程安全的,它可能会让你有些头疼。要将此问题与使用不同线程更新对象所导致的潜在问题分开,我会尝试在没有线程的情况下使其工作,并在遇到问题时更新此问题。

答案 2 :(得分:1)

由于您的问题是交互方,请尝试执行此操作。它确实为交互器创建了一个计时器,它将有助于摆脱启动阻塞方法:

class CommandSubclass2 : public vtkCommand
{
  public:
    vtkTypeMacro(CommandSubclass2, vtkCommand);

    static CommandSubclass2 *New()
    {
        return new CommandSubclass2;
    }

    void Execute(vtkObject *vtkNotUsed(caller), unsigned long vtkNotUsed(eventId), 
                    void *vtkNotUsed(callData))
    {
        std::cout << "timer callback" << std::endl;
        renderWindowInteractor->ExitCallback();
    }
};

//在您的主

vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New(); 
iren->SetRenderWindow(win); 

iren->CreateRepeatingTimer(1);

 vtkSmartPointer<CommandSubclass2> timerCallback = 
      vtkSmartPointer<CommandSubclass2>::New();
iren->AddObserver ( vtkCommand::TimerEvent, timerCallback );

vtkInteractorStyleMultiTouchCamera *style = 
        vtkInteractorStyleMultiTouchCamera::New(); 
iren->SetInteractorStyle(style); 



while(true)
{
    iren->Start();     
    ren->Render();
}

可能不是这样做的好方法,但我不知道任何其他方式摆脱交互式阻止方法start()

答案 3 :(得分:1)

所以感谢这里的人们的帮助以及对代码和文档的一些研究我已经认为我的代码中的这部分是在尝试旋转/翻译/缩放我的Polydata时没有发生的任何事情:

//Start the event loop
iren->Initialize();
iren->Start();

确实start()的{​​{1}}方法是阻塞的,因此无论我之后可以调用什么都没有处理。摆脱它允许我调用我的转换函数。然而,在应用每次转换后,可能会丢失与数据的可能交互并关闭窗口。