attach a widget (not working well yet)

This commit is contained in:
AndreaRigoni
2026-03-08 09:42:28 +00:00
parent 32a1104769
commit 2548582036
6 changed files with 309 additions and 169 deletions

View File

@@ -32,11 +32,16 @@
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
BOOST_AUTO_TEST_CASE(vtkDetectorChamberTest) { BOOST_AUTO_TEST_CASE(vtkDetectorChamberTest) {
uLib::DetectorChamber content; uLib::DetectorChamber d1, d2;
content.SetSize(uLib::Vector3f(10, 10, 10)); d1.SetSize(uLib::Vector3f(10, 20, 2));
content.SetPosition(uLib::Vector3f(0, 0, 0)); d1.SetPosition(uLib::Vector3f(0, 0, 0));
uLib::Vtk::vtkDetectorChamber vtkDetectorChamber(&content); d2.SetSize(uLib::Vector3f(10, 20, 2));
d2.SetPosition(uLib::Vector3f(0, 0, 20));
uLib::Vtk::vtkDetectorChamber vtkDetectorChamber(&d1);
uLib::Vtk::vtkDetectorChamber vtkDetectorChamber2(&d2);
if (!vtkDetectorChamber.GetProp()) { if (!vtkDetectorChamber.GetProp()) {
BOOST_FAIL("vtkDetectorChamber::GetProp() returned NULL"); BOOST_FAIL("vtkDetectorChamber::GetProp() returned NULL");
@@ -45,6 +50,7 @@ BOOST_AUTO_TEST_CASE(vtkDetectorChamberTest) {
if (std::getenv("CTEST_PROJECT_NAME") == nullptr) { if (std::getenv("CTEST_PROJECT_NAME") == nullptr) {
uLib::Vtk::Viewer viewer; uLib::Vtk::Viewer viewer;
viewer.AddPuppet(vtkDetectorChamber); viewer.AddPuppet(vtkDetectorChamber);
viewer.AddPuppet(vtkDetectorChamber2);
viewer.Start(); viewer.Start();
} }

View File

@@ -23,18 +23,45 @@
//////////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////////*/
#include <vtkAxes.h>
#include <vtkBoxWidget.h>
#include <vtkCubeSource.h>
#include <vtkLineSource.h>
#include <vtkMatrix4x4.h>
#include <vtkPolyDataMapper.h>
#include <vtkPropPicker.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkRendererCollection.h>
#include <vtkSmartPointer.h>
#include <vtkTransform.h>
#include "Vtk/HEP/Detectors/vtkDetectorChamber.h" #include "Vtk/HEP/Detectors/vtkDetectorChamber.h"
#include "Vtk/vtkContainerBox.h"
namespace uLib { namespace uLib {
namespace Vtk { namespace Vtk {
vtkDetectorChamber::vtkDetectorChamber(DetectorChamber *content) vtkDetectorChamber::vtkDetectorChamber(DetectorChamber *content)
: vtkContainerBox(content) { : vtkContainerBox(content) {
InstallPipe(); m_Widget = vtkBoxWidget::New();
m_Callback = vtkWidgetCallback::New();
m_PickerCallback = vtkSelectionCallback::New();
m_Callback->SetChamber(this);
m_PickerCallback->SetChamber(this);
m_Widget->AddObserver(vtkCommand::InteractionEvent, m_Callback);
m_Widget->SetRotationEnabled(1);
m_Widget->SetTranslationEnabled(1);
m_Widget->SetScalingEnabled(0);
} }
vtkDetectorChamber::~vtkDetectorChamber() {} vtkDetectorChamber::~vtkDetectorChamber() {
m_Widget->Delete();
m_Callback->Delete();
m_PickerCallback->Delete();
}
DetectorChamber *vtkDetectorChamber::GetContent() { DetectorChamber *vtkDetectorChamber::GetContent() {
return static_cast<DetectorChamber *>(m_Content); return static_cast<DetectorChamber *>(m_Content);
@@ -44,7 +71,130 @@ void vtkDetectorChamber::PrintSelf(std::ostream &o) const {
vtkContainerBox::PrintSelf(o); vtkContainerBox::PrintSelf(o);
} }
void vtkDetectorChamber::InstallPipe() { vtkContainerBox::InstallPipe(); } void vtkDetectorChamber::ConnectInteractor(
vtkRenderWindowInteractor *interactor) {
if (!interactor)
return;
m_Widget->SetInteractor(interactor);
m_Widget->SetProp3D(m_Cube);
m_Widget->PlaceWidget();
interactor->AddObserver(vtkCommand::LeftButtonPressEvent, m_PickerCallback);
}
void vtkDetectorChamber::Update() {
if (!m_Content)
return;
Matrix4f mat = static_cast<Content *>(m_Content)->GetWorldMatrix();
vtkSmartPointer<vtkMatrix4x4> vmat = vtkSmartPointer<vtkMatrix4x4>::New();
for (int i = 0; i < 4; ++i)
for (int j = 0; j < 4; ++j)
vmat->SetElement(i, j, mat(i, j));
m_Cube->SetUserMatrix(vmat);
m_Axes->SetUserMatrix(vmat);
m_Pivot->SetUserMatrix(vmat);
}
void vtkDetectorChamber::InstallPipe() {
if (!m_Content)
return;
// Cube: unit box (0,0,0) -> (1,1,1)
vtkSmartPointer<vtkCubeSource> cube = vtkSmartPointer<vtkCubeSource>::New();
cube->SetBounds(0, 1, 0, 1, 0, 1);
vtkSmartPointer<vtkPolyDataMapper> mapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(cube->GetOutputPort());
m_Cube->SetMapper(mapper);
m_Cube->GetProperty()->SetRepresentationToWireframe();
m_Cube->GetProperty()->SetAmbient(0.7);
// Axes: corner origin
vtkSmartPointer<vtkAxes> axes = vtkSmartPointer<vtkAxes>::New();
axes->SetOrigin(0, 0, 0);
axes->SetScaleFactor(0.2);
mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(axes->GetOutputPort());
m_Axes->SetMapper(mapper);
m_Axes->GetProperty()->SetLineWidth(3);
m_Axes->GetProperty()->SetAmbient(0.4);
// Pivot: center of unit box
vtkSmartPointer<vtkAxes> pivot = vtkSmartPointer<vtkAxes>::New();
pivot->SetOrigin(0.5, 0.5, 0.5);
pivot->SetScaleFactor(0.1);
mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(pivot->GetOutputPort());
m_Pivot->SetMapper(mapper);
m_Pivot->GetProperty()->SetLineWidth(3);
m_Pivot->GetProperty()->SetAmbient(0.4);
this->SetProp(m_Cube);
this->SetProp(m_Axes);
this->SetProp(m_Pivot);
this->Update();
}
void vtkDetectorChamber::vtkWidgetCallback::Execute(vtkObject *caller,
unsigned long, void *) {
vtkBoxWidget *widget = reinterpret_cast<vtkBoxWidget *>(caller);
vtkSmartPointer<vtkTransform> t = vtkSmartPointer<vtkTransform>::New();
widget->GetTransform(t);
vtkMatrix4x4 *vmat = t->GetMatrix();
Matrix4f mat;
for (int i = 0; i < 4; ++i)
for (int j = 0; j < 4; ++j)
mat(i, j) = vmat->GetElement(i, j);
chamber->GetContent()->SetMatrix(mat);
// Reset internal matrix to identity to avoid double-transformation
vtkProp3D *prop = widget->GetProp3D();
if (prop) {
prop->SetPosition(0, 0, 0);
prop->SetOrientation(0, 0, 0);
prop->SetScale(1, 1, 1);
}
chamber->Update();
}
void vtkDetectorChamber::vtkSelectionCallback::Execute(vtkObject *caller,
unsigned long, void *) {
vtkRenderWindowInteractor *interactor =
reinterpret_cast<vtkRenderWindowInteractor *>(caller);
vtkSmartPointer<vtkPropPicker> picker = vtkSmartPointer<vtkPropPicker>::New();
int *pos = interactor->GetEventPosition();
picker->Pick(
pos[0], pos[1], 0,
interactor->GetRenderWindow()->GetRenderers()->GetFirstRenderer());
vtkProp *picked = picker->GetViewProp();
if (picked == chamber->m_Cube || picked == chamber->m_Axes ||
picked == chamber->m_Pivot) {
if (!chamber->m_Widget->GetEnabled()) {
// Register current position/rotation/scale from content //
Matrix4f mat = chamber->GetContent()->GetWorldMatrix();
vtkSmartPointer<vtkMatrix4x4> vmat = vtkSmartPointer<vtkMatrix4x4>::New();
for (int i = 0; i < 4; ++i)
for (int j = 0; j < 4; ++j)
vmat->SetElement(i, j, mat(i, j));
vtkSmartPointer<vtkTransform> t = vtkSmartPointer<vtkTransform>::New();
t->SetMatrix(vmat);
chamber->m_Widget->SetTransform(t);
chamber->m_Widget->PlaceWidget();
chamber->m_Widget->On();
}
} else {
if (chamber->m_Widget->GetEnabled()) {
chamber->m_Widget->Off();
}
}
}
} // namespace Vtk } // namespace Vtk
} // namespace uLib } // namespace uLib

View File

@@ -27,26 +27,17 @@
#define VTK_DETECTOR_CHAMBER_H #define VTK_DETECTOR_CHAMBER_H
#include <vtkActor.h> #include <vtkActor.h>
#include <vtkAppendPolyData.h>
#include <vtkLineSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkSmartPointer.h>
#include <vtkSphereSource.h>
#include <vtk3DWidget.h>
#include <vtkBoxWidget.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkCommand.h> #include <vtkCommand.h>
#include <vtkSmartPointer.h>
#include <vtkTransform.h> #include <vtkTransform.h>
#include "Math/Dense.h"
#include "HEP/Detectors/DetectorChamber.h" #include "HEP/Detectors/DetectorChamber.h"
#include "Math/Dense.h"
#include "Vtk/uLibVtkInterface.h" #include "Vtk/uLibVtkInterface.h"
#include "Vtk/vtkContainerBox.h" #include "Vtk/vtkContainerBox.h"
class vtkBoxWidget;
namespace uLib { namespace uLib {
namespace Vtk { namespace Vtk {
@@ -59,12 +50,39 @@ public:
Content *GetContent(); Content *GetContent();
void Update();
void ConnectInteractor(vtkRenderWindowInteractor *interactor) override;
void PrintSelf(std::ostream &o) const; void PrintSelf(std::ostream &o) const;
private: protected:
void InstallPipe(); void InstallPipe() override;
vtkDetectorChamber::Content *content; private:
class vtkWidgetCallback : public vtkCommand {
public:
static vtkWidgetCallback *New() { return new vtkWidgetCallback; }
void SetChamber(uLib::Vtk::vtkDetectorChamber *ch) { this->chamber = ch; }
virtual void Execute(vtkObject *caller, unsigned long, void *) override;
private:
uLib::Vtk::vtkDetectorChamber *chamber;
};
class vtkSelectionCallback : public vtkCommand {
public:
static vtkSelectionCallback *New() { return new vtkSelectionCallback; }
void SetChamber(uLib::Vtk::vtkDetectorChamber *ch) { this->chamber = ch; }
virtual void Execute(vtkObject *caller, unsigned long, void *) override;
private:
uLib::Vtk::vtkDetectorChamber *chamber;
};
vtkBoxWidget *m_Widget;
vtkWidgetCallback *m_Callback;
vtkSelectionCallback *m_PickerCallback;
}; };
} // namespace Vtk } // namespace Vtk

View File

@@ -23,37 +23,32 @@
//////////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////////*/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
#include <vtkSmartPointer.h>
#include <vtkRendererCollection.h>
#include <vtkRenderWindowInteractor.h> #include <vtkRenderWindowInteractor.h>
#include <vtkRendererCollection.h>
#include <vtkSmartPointer.h>
#include <vtkTextProperty.h>
#include <vtkAxesActor.h> #include <vtkAxesActor.h>
#include <vtkCamera.h> #include <vtkCamera.h>
#include <vtkInteractorStyleTrackballCamera.h> #include <vtkInteractorStyleTrackballCamera.h>
#include <vtkObjectFactory.h> #include <vtkObjectFactory.h>
#include <vtkTextProperty.h>
#include "uLibVtkViewer.h" #include "uLibVtkViewer.h"
// Custom interactor style: disables spin/inertia so the scene only // Custom interactor style: disables spin/inertia so the scene only
// rotates while the mouse is actively being moved with the button held. // rotates while the mouse is actively being moved with the button held.
class vtkInteractorStyleNoSpin : public vtkInteractorStyleTrackballCamera class vtkInteractorStyleNoSpin : public vtkInteractorStyleTrackballCamera {
{
public: public:
static vtkInteractorStyleNoSpin *New(); static vtkInteractorStyleNoSpin *New();
vtkTypeMacro(vtkInteractorStyleNoSpin, vtkInteractorStyleTrackballCamera); vtkTypeMacro(vtkInteractorStyleNoSpin, vtkInteractorStyleTrackballCamera);
// Override: when the left button is released, immediately stop any // Override: when the left button is released, immediately stop any
// ongoing motion (rotation/spin) so no momentum is carried over. // ongoing motion (rotation/spin) so no momentum is carried over.
void OnLeftButtonUp() override void OnLeftButtonUp() override {
{
this->StopState(); this->StopState();
vtkInteractorStyleTrackballCamera::OnLeftButtonUp(); vtkInteractorStyleTrackballCamera::OnLeftButtonUp();
} }
@@ -63,23 +58,18 @@ vtkStandardNewMacro(vtkInteractorStyleNoSpin);
namespace uLib { namespace uLib {
namespace Vtk { namespace Vtk {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
///// VTK VIEWER ////////////////////////////////////////////////////////////// ///// VTK VIEWER //////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
Viewer::Viewer()
Viewer::Viewer() : : m_RenderWindow(vtkRenderWindow::New()), m_Renderer(vtkRenderer::New()),
m_RenderWindow(vtkRenderWindow::New()),
m_Renderer(vtkRenderer::New()),
m_Annotation(vtkCornerAnnotation::New()), m_Annotation(vtkCornerAnnotation::New()),
m_Marker(vtkOrientationMarkerWidget::New()) m_Marker(vtkOrientationMarkerWidget::New()) {
{
InstallPipe(); InstallPipe();
} }
Viewer::~Viewer() Viewer::~Viewer() {
{
UninstallPipe(); UninstallPipe();
m_Annotation->Delete(); m_Annotation->Delete();
@@ -88,8 +78,7 @@ Viewer::~Viewer()
m_RenderWindow->Delete(); m_RenderWindow->Delete();
} }
void Viewer::InstallPipe() void Viewer::InstallPipe() {
{
m_RenderWindow->AddRenderer(m_Renderer); m_RenderWindow->AddRenderer(m_Renderer);
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New(); vtkSmartPointer<vtkRenderWindowInteractor>::New();
@@ -109,8 +98,7 @@ void Viewer::InstallPipe()
m_Renderer->AddViewProp(m_Annotation); m_Renderer->AddViewProp(m_Annotation);
// orientation marker // // orientation marker //
vtkSmartPointer<vtkAxesActor> axes = vtkSmartPointer<vtkAxesActor> axes = vtkSmartPointer<vtkAxesActor>::New();
vtkSmartPointer<vtkAxesActor>::New();
m_Marker->SetInteractor(renderWindowInteractor); m_Marker->SetInteractor(renderWindowInteractor);
m_Marker->SetOrientationMarker(axes); m_Marker->SetOrientationMarker(axes);
m_Marker->SetViewport(0.0, 0.0, 0.2, 0.2); m_Marker->SetViewport(0.0, 0.0, 0.2, 0.2);
@@ -121,64 +109,51 @@ void Viewer::InstallPipe()
m_RenderWindow->Render(); m_RenderWindow->Render();
} }
void Viewer::UninstallPipe() void Viewer::UninstallPipe() {
{
m_Renderer->RemoveAllViewProps(); m_Renderer->RemoveAllViewProps();
m_Renderer->Clear(); m_Renderer->Clear();
} }
void Viewer::addProp(vtkProp *prop) void Viewer::addProp(vtkProp *prop) {
{
m_Renderer->AddActor(prop); m_Renderer->AddActor(prop);
m_Renderer->Render(); m_Renderer->Render();
} }
void Viewer::RemoveProp(vtkProp *prop) void Viewer::RemoveProp(vtkProp *prop) {
{
m_Renderer->RemoveViewProp(prop); m_Renderer->RemoveViewProp(prop);
m_Renderer->Render(); m_Renderer->Render();
} }
void Viewer::AddPuppet(Puppet &prop) void Viewer::AddPuppet(Puppet &prop) {
{
prop.ConnectRenderer(m_Renderer); prop.ConnectRenderer(m_Renderer);
prop.ConnectInteractor(this->GetInteractor());
m_Renderer->Render(); m_Renderer->Render();
} }
void Viewer::RemovePuppet(Puppet &prop) void Viewer::RemovePuppet(Puppet &prop) {
{
prop.DisconnectRenderer(m_Renderer); prop.DisconnectRenderer(m_Renderer);
m_Renderer->Render(); m_Renderer->Render();
} }
void Viewer::Start() void Viewer::Start() { m_RenderWindow->GetInteractor()->Start(); }
{
m_RenderWindow->GetInteractor()->Start();
}
vtkCornerAnnotation *Viewer::GetAnnotation() vtkCornerAnnotation *Viewer::GetAnnotation() { return m_Annotation; }
{
return m_Annotation;
}
vtkRenderer *Viewer::GetRenderer() vtkRenderer *Viewer::GetRenderer() { return m_Renderer; }
{
return m_Renderer;
}
vtkRenderWindowInteractor *Viewer::GetInteractor() vtkRenderWindowInteractor *Viewer::GetInteractor() {
{
return m_RenderWindow->GetInteractor(); return m_RenderWindow->GetInteractor();
} }
void Viewer::Reset() void Viewer::Reset() {
{ this->ZoomAuto();
m_Renderer->ResetCameraClippingRange();
m_Renderer->ResetCamera();
m_Renderer->Render(); m_Renderer->Render();
} }
void Viewer::ZoomAuto() {
m_Renderer->ResetCameraClippingRange();
m_Renderer->ResetCamera();
}
} // vtk } // namespace Vtk
} // uLib } // namespace uLib

View File

@@ -23,18 +23,16 @@
//////////////////////////////////////////////////////////////////////////////*/ //////////////////////////////////////////////////////////////////////////////*/
#ifndef ULIBVTKVIEWER_H #ifndef ULIBVTKVIEWER_H
#define ULIBVTKVIEWER_H #define ULIBVTKVIEWER_H
#include <iostream>
#include "uLibVtkInterface.h" #include "uLibVtkInterface.h"
#include <iostream>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkCornerAnnotation.h> #include <vtkCornerAnnotation.h>
#include <vtkOrientationMarkerWidget.h> #include <vtkOrientationMarkerWidget.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
class vtkProp; class vtkProp;
class vtk3DWidget; class vtk3DWidget;
@@ -45,23 +43,19 @@ class vtkRenderer;
namespace uLib { namespace uLib {
namespace Vtk { namespace Vtk {
template <class T> class Tie {
template <class T>
class Tie {
public: public:
void DoAction() { void DoAction() {
std::cout << "Tie::DoAction -> generic Tie does nothing\n"; std::cout << "Tie::DoAction -> generic Tie does nothing\n";
} }
}; };
class Viewer { class Viewer {
public: public:
Viewer(); Viewer();
~Viewer(); ~Viewer();
void AddPuppet(Puppet &prop); void AddPuppet(Puppet &prop);
void RemovePuppet(Puppet &prop); void RemovePuppet(Puppet &prop);
@@ -69,6 +63,7 @@ public:
void AddWidget(vtk3DWidget *widget); void AddWidget(vtk3DWidget *widget);
void Reset(); void Reset();
void ZoomAuto();
void Start(); void Start();
@@ -92,16 +87,12 @@ private:
vtkOrientationMarkerWidget *m_Marker; vtkOrientationMarkerWidget *m_Marker;
}; };
template <> template <> class Tie<Viewer> {
class Tie<Viewer> {
public: public:
void DoAction() { void DoAction() { std::cout << " VIEWER TIE !!! \n"; }
std::cout << " VIEWER TIE !!! \n";
}
}; };
} // namespace Vtk
} // vtk } // namespace uLib
} // uLib
#endif // ULIBVTKVIEWER_H #endif // ULIBVTKVIEWER_H

View File

@@ -42,7 +42,7 @@ public:
virtual class vtkPolyData *GetPolyData() const; virtual class vtkPolyData *GetPolyData() const;
protected: protected:
void InstallPipe(); virtual void InstallPipe();
vtkActor *m_Cube; vtkActor *m_Cube;
vtkActor *m_Axes; vtkActor *m_Axes;