gpt4 book ai didi

c++ - VTK:在 vtkRenderWindowInteractor 处于事件状态时以编程方式旋转 Actor

转载 作者:太空狗 更新时间:2023-10-29 21:18:01 24 4
gpt4 key购买 nike

我尝试使用 vtkActor::RotateZ 旋转一个 vtkActor,然后调用 vtkRenderWindow::Render。它工作正常(旋转 Actor )但我无法移动、调整窗口大小,甚至无法聚焦窗口。

我怀疑这是由于未捕获操作系统事件引起的,因此我添加了一个 vtkRenderWindowInteractor 到组合中。现在我可以移动窗口、调整窗口大小和聚焦窗口,但 Actor 不再旋转。

我在下面的代码片段中分离了代码,注释第 43 行以查看两种效果:

renderWindowInteractor->Start();

我正在使用 mingw-w64 (GCC 4.9.1) 编译 VTK 6.2,在 Windows 8.1 中运行。我已经在 this repo 中上传了代码使用小型 CMake 设置,以便您可以轻松地对其进行测试。

感谢您的帮助!


constexpr float planeWidth = 200.0f;
constexpr float planeHeight = 100.0f;

int main()
{
auto renderer = vtkRenderer::New();

// Create render window
auto renWin = vtkRenderWindow::New();
renWin->AddRenderer(renderer);
renWin->SetSize(600,600);

// Create a plane
auto texturedPlane = vtkActor::New();
auto plane = vtkPlaneSource::New();
plane->SetOrigin(0, planeHeight, 0);
plane->SetPoint1(planeWidth, planeHeight, 0);
plane->SetPoint2(0, 0, 0);

auto planeMapper = vtkPolyDataMapper::New();
planeMapper->SetInputConnection(plane->GetOutputPort());
texturedPlane->SetMapper(planeMapper);
texturedPlane->SetOrigin(planeWidth / 2, planeHeight, 0);

renderer->AddActor(texturedPlane);
renderer->ResetCamera();

// Create a RenderWindowInteractor
auto renderWindowInteractor = vtkRenderWindowInteractor::New();
renderWindowInteractor->SetRenderWindow(renWin);
renderWindowInteractor->Start(); // <-- Comment this line!

// Render
float rot = 0.0f;
while(true)
{
texturedPlane->SetOrientation(0,0,0);
texturedPlane->RotateZ(rot++);

renWin->Render();
}
}

使用asdfasdf的方案解决:(代码在this repo)

constexpr float planeWidth = 200.0f;
constexpr float planeHeight = 100.0f;
vtkActor * texturedPlane;
vtkRenderWindowInteractor * renderWindowInteractor;
vtkRenderWindow * renWin;
float rot = 0.0f;

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

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

void Execute(vtkObject * vtkNotUsed(caller),
unsigned long vtkNotUsed(eventId),
void * vtkNotUsed(callData))
{
texturedPlane->SetOrientation(0,0,0);
texturedPlane->RotateZ(rot++);

renWin->Render();
}
};

int main()
{
auto renderer = vtkRenderer::New();

// Create render window
renWin = vtkRenderWindow::New();
renWin->AddRenderer(renderer);
renWin->SetSize(600,600);

// Create a plane
texturedPlane = vtkActor::New();
auto plane = vtkPlaneSource::New();
plane->SetOrigin(0, planeHeight, 0);
plane->SetPoint1(planeWidth, planeHeight, 0);
plane->SetPoint2(0, 0, 0);

auto planeMapper = vtkPolyDataMapper::New();
planeMapper->SetInputConnection(plane->GetOutputPort());
texturedPlane->SetMapper(planeMapper);
texturedPlane->SetOrigin(planeWidth / 2, planeHeight, 0);

renderer->AddActor(texturedPlane);

renderer->ResetCamera();

// Create a RenderWindowInteractor
renderWindowInteractor = vtkRenderWindowInteractor::New();
renderWindowInteractor->SetRenderWindow(renWin);
renderWindowInteractor->Initialize();
renderWindowInteractor->CreateRepeatingTimer(1);
RotateCommand * rotateCallback = RotateCommand::New();
renderWindowInteractor->AddObserver(vtkCommand::TimerEvent, rotateCallback );

renderWindowInteractor->Start();
}

最佳答案

破解以解决部分问题。

vtkRenderWindowInteractor * renderWindowInteractor;
constexpr float planeWidth = 200.0f;
constexpr float planeHeight = 100.0f;

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();
}
};

int main()
{
auto renderer = vtkRenderer::New();

// Create render window
auto renWin = vtkRenderWindow::New();
renWin->AddRenderer(renderer);
renWin->SetSize(600,600);

// Create a plane
auto texturedPlane = vtkActor::New();
auto plane = vtkPlaneSource::New();
plane->SetOrigin(0, planeHeight, 0);
plane->SetPoint1(planeWidth, planeHeight, 0);
plane->SetPoint2(0, 0, 0);

auto planeMapper = vtkPolyDataMapper::New();
planeMapper->SetInputConnection(plane->GetOutputPort());
texturedPlane->SetMapper(planeMapper);
texturedPlane->SetOrigin(planeWidth / 2, planeHeight, 0);

renderer->AddActor(texturedPlane);
renderer->ResetCamera();

// Create a RenderWindowInteractor
renderWindowInteractor = vtkRenderWindowInteractor::New();
renderWindowInteractor->SetRenderWindow(renWin);

renderWindowInteractor->Initialize();
renderWindowInteractor->CreateRepeatingTimer(1);

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


// Render
float rot = 0.0f;
while(true)
{
renderWindowInteractor->Start(); // <-- Comment this line!
texturedPlane->SetOrientation(0,0,0);
texturedPlane->RotateZ(rot++);
renWin->Render();
}
}

如果我没有给你任何其他回复,我很抱歉,但是由于这个解决方案很糟糕,我一直在等待其他人找到更好的解决方案,但似乎没有人回答你,所以这里是我会做什么。

您几乎可以猜到它的作用。开始交互后,每隔 1 ms,调用一个回调来停止交互,并进行轮换。

关于c++ - VTK:在 vtkRenderWindowInteractor 处于事件状态时以编程方式旋转 Actor ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31075569/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com