Can't handle button callback function.
Opened this issue · 1 comments
ipoirot commented
#include <iostream>
#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtkActor.h>
#include <vtkConeSource.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkPolyDataMapper.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkButtonWidget.h>
#include <vtkPNGReader.h>
#include <vtkTexturedButtonRepresentation2D.h>
#include <vtkCoordinate.h>
#include "../vtkGlfw/vtkGlfwOpenGLRenderWindow.h"
#include "../vtkGlfw/vtkGlfwRenderWindowInteractor.h"
#include "vtkAutoInit.h"
VTK_MODULE_INIT(vtkRenderingOpenGL2);
#define vtkSPtr vtkSmartPointer
#define vtkSPtrNew(Var, Type) vtkSPtr<Type> Var = vtkSPtr<Type>::New();
enum ButtonType { E_Button0, E_Button1, E_ButtonCount };
vtkSPtr<vtkButtonWidget> m_Button[E_ButtonCount];
//vtkSPtr<vtkRenderWindowInteractor> m_RenderWindowInteractor;
vtkSPtr<vtkGlfwRenderWindowInteractor> m_RenderWindowInteractor;
vtkSPtr<vtkRenderer> m_Renderer;
ButtonType GetButtonType(const vtkButtonWidget *const buttonWidget)
{
ButtonType result = E_ButtonCount;
for (int i = 0; i < E_ButtonCount; ++i)
{
if (buttonWidget == m_Button[i])
{
result = (ButtonType)i;
break;
}
}
return result;
}
class ButtonCallBack : public vtkCommand
{
public:
static ButtonCallBack *New() { return new ButtonCallBack(); }
virtual void Execute(vtkObject *caller, unsigned long eventId, void *callData)
{
vtkButtonWidget* buttonWidget = reinterpret_cast<vtkButtonWidget*>(caller);
vtkTexturedButtonRepresentation2D* rep = reinterpret_cast<vtkTexturedButtonRepresentation2D*>(buttonWidget->GetRepresentation());
int state = rep->GetState();
ButtonType buttonT = GetButtonType(buttonWidget);
cout << "state: " << state << ", buttonT: " << buttonT << endl;
// add your costum click function for different button.
}
};
void InitButton(const ButtonType buttonType, const std::string& beforeImagePath, const std::string& afterImagePath)
{
vtkSPtrNew(pngReader, vtkPNGReader);
pngReader->SetFileName(beforeImagePath.c_str());
pngReader->Update();
vtkSPtrNew(pngReader1, vtkPNGReader);
pngReader1->SetFileName(afterImagePath.c_str());
pngReader1->Update();
vtkSPtrNew(buttonRep, vtkTexturedButtonRepresentation2D);
if (beforeImagePath != afterImagePath)
{
buttonRep->SetNumberOfStates(2);
buttonRep->SetButtonTexture(0, pngReader->GetOutput());
buttonRep->SetButtonTexture(1, pngReader1->GetOutput());
}
else
{
buttonRep->SetNumberOfStates(1);
buttonRep->SetButtonTexture(0, pngReader->GetOutput());
}
m_Button[buttonType]->SetInteractor(m_RenderWindowInteractor);
m_Button[buttonType]->SetRepresentation(buttonRep);
buttonRep->SetPlaceFactor(1);
m_Button[buttonType]->On();
vtkSPtrNew(buttonCB, ButtonCallBack);
m_Button[buttonType]->AddObserver(vtkCommand::StateChangedEvent, buttonCB);
}
void UpdateButtonsPosition()
{
vtkWidgetRepresentation* buttonRep = m_Button[E_Button0]->GetRepresentation();
vtkSPtrNew(coordinate, vtkCoordinate);
coordinate->SetCoordinateSystemToNormalizedDisplay();
coordinate->SetValue(1.0, 0.8);
double bds[6];
double sz = 50;
bds[0] = coordinate->GetComputedDisplayValue(m_Renderer)[0] - sz;
bds[1] = bds[0] + sz;
bds[2] = coordinate->GetComputedDisplayValue(m_Renderer)[1] - sz;
bds[3] = bds[2] + sz;
bds[4] = bds[5] = 0;
buttonRep->PlaceWidget(bds);
// ================== Put the second button ==================
double tmpBds[6] = { bds[0], bds[1], bds[2], bds[3], bds[4], bds[5] };
buttonRep = m_Button[E_Button1]->GetRepresentation();
bds[0] = tmpBds[0];
bds[1] = bds[0] + sz;
bds[2] = tmpBds[2] - sz - 5;
bds[3] = bds[2] + sz;
bds[4] = bds[5] = 0;
buttonRep->PlaceWidget(bds);
}
int main()
{
vtkSPtrNew(cone, vtkConeSource);
vtkSPtrNew(mapper, vtkPolyDataMapper);
mapper->SetInputConnection(cone->GetOutputPort());
vtkSPtrNew(actor, vtkActor);
actor->SetMapper(mapper);
m_Renderer = vtkSPtr<vtkRenderer>::New();
m_Renderer->AddActor(actor);
m_Renderer->SetBackground(0, 0, 0);
//vtkSPtrNew(renderWindow, vtkRenderWindow);
vtkNew<vtkGlfwOpenGLRenderWindow> renderWindow;
renderWindow->SetSize(300, 300);
renderWindow->AddRenderer(m_Renderer);
renderWindow->SetWindowName("Cylinder");
renderWindow->SetMultiSamples(8);
m_RenderWindowInteractor = vtkSPtr<vtkGlfwRenderWindowInteractor>::New();
m_RenderWindowInteractor->SetRenderWindow(renderWindow);
for (int i = 0; i < 2; ++i)
{
m_Button[i] = vtkSmartPointer<vtkButtonWidget>::New();
}
std::string path0 = "F:/bullet3-3.17/Extras/sphereOctree.png";
std::string path1 = "F:/bullet3-3.17/Extras/LA_closed.png";
InitButton(E_Button0, path0, path1);
InitButton(E_Button1, path1, path0);
m_Renderer->ResetCamera();
renderWindow->Render();
UpdateButtonsPosition();
m_RenderWindowInteractor->Start();
return 0;
}
ipoirot commented
Hi,
I use vtkButtonWidget to Create 2D button. The vtkWidgetRepresentation object controls the button’s position and show button pictures. Write class ButtonCallBack that inherits vtkCommand and use it to listen for vtkCommand::StateChangedEvent, then I can add our button click function in it.
It worked fine in native vtk, but crashed in vtkGlfwOpenGLRenderWindow.