split viewport for Qt and VtkViewer
This commit is contained in:
@@ -3,6 +3,7 @@ set(HEADERS uLibVtkInterface.h
|
|||||||
vtkContainerBox.h
|
vtkContainerBox.h
|
||||||
vtkHandlerWidget.h
|
vtkHandlerWidget.h
|
||||||
vtkQViewport.h
|
vtkQViewport.h
|
||||||
|
vtkViewport.h
|
||||||
vtkPolydata.h
|
vtkPolydata.h
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -11,6 +12,7 @@ set(SOURCES uLibVtkInterface.cxx
|
|||||||
vtkContainerBox.cpp
|
vtkContainerBox.cpp
|
||||||
vtkHandlerWidget.cpp
|
vtkHandlerWidget.cpp
|
||||||
vtkQViewport.cpp
|
vtkQViewport.cpp
|
||||||
|
vtkViewport.cpp
|
||||||
vtkPolydata.cpp
|
vtkPolydata.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
#include <vtkInteractorStyleTrackballCamera.h>
|
#include <vtkInteractorStyleTrackballCamera.h>
|
||||||
#include <vtkObjectFactory.h>
|
#include <vtkObjectFactory.h>
|
||||||
#include <vtkTextProperty.h>
|
#include <vtkTextProperty.h>
|
||||||
|
#include <vtkRenderWindow.h>
|
||||||
|
|
||||||
#include "uLibVtkViewer.h"
|
#include "uLibVtkViewer.h"
|
||||||
|
|
||||||
@@ -56,8 +57,6 @@ public:
|
|||||||
};
|
};
|
||||||
vtkStandardNewMacro(vtkInteractorStyleNoSpin);
|
vtkStandardNewMacro(vtkInteractorStyleNoSpin);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace uLib {
|
namespace uLib {
|
||||||
namespace Vtk {
|
namespace Vtk {
|
||||||
|
|
||||||
@@ -65,24 +64,12 @@ namespace Vtk {
|
|||||||
///// VTK VIEWER //////////////////////////////////////////////////////////////
|
///// VTK VIEWER //////////////////////////////////////////////////////////////
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
Viewer::Viewer()
|
Viewer::Viewer()
|
||||||
: m_RenderWindow(vtkRenderWindow::New()), m_Renderer(vtkRenderer::New()),
|
: Viewport(), m_RenderWindow(vtkRenderWindow::New()) {
|
||||||
m_Annotation(vtkCornerAnnotation::New()),
|
|
||||||
m_Marker(vtkOrientationMarkerWidget::New()), m_CameraWidget(nullptr) {
|
|
||||||
#if VTK_MAJOR_VERSION >= 9 || \
|
|
||||||
(VTK_MAJOR_VERSION == 8 && VTK_MINOR_VERSION >= 90)
|
|
||||||
m_CameraWidget = vtkCameraOrientationWidget::New();
|
|
||||||
#endif
|
|
||||||
InstallPipe();
|
InstallPipe();
|
||||||
}
|
}
|
||||||
|
|
||||||
Viewer::~Viewer() {
|
Viewer::~Viewer() {
|
||||||
UninstallPipe();
|
UninstallPipe();
|
||||||
|
|
||||||
m_Annotation->Delete();
|
|
||||||
m_Marker->Delete();
|
|
||||||
if (m_CameraWidget)
|
|
||||||
m_CameraWidget->Delete();
|
|
||||||
m_Renderer->Delete();
|
|
||||||
m_RenderWindow->Delete();
|
m_RenderWindow->Delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,34 +80,14 @@ void Viewer::InstallPipe() {
|
|||||||
vtkSmartPointer<vtkRenderWindowInteractor>::New();
|
vtkSmartPointer<vtkRenderWindowInteractor>::New();
|
||||||
renderWindowInteractor->SetRenderWindow(m_RenderWindow);
|
renderWindowInteractor->SetRenderWindow(m_RenderWindow);
|
||||||
|
|
||||||
// Use a custom style with no spin/inertia
|
// Common setup
|
||||||
|
Viewport::SetupPipeline(renderWindowInteractor);
|
||||||
|
|
||||||
|
// BUT we want to override the style with our custom NoSpin version
|
||||||
vtkSmartPointer<vtkInteractorStyleNoSpin> style =
|
vtkSmartPointer<vtkInteractorStyleNoSpin> style =
|
||||||
vtkSmartPointer<vtkInteractorStyleNoSpin>::New();
|
vtkSmartPointer<vtkInteractorStyleNoSpin>::New();
|
||||||
renderWindowInteractor->SetInteractorStyle(style);
|
renderWindowInteractor->SetInteractorStyle(style);
|
||||||
|
|
||||||
// annotation //
|
|
||||||
m_Annotation->GetTextProperty()->SetColor(1, 1, 1);
|
|
||||||
m_Annotation->GetTextProperty()->SetFontFamilyToArial();
|
|
||||||
m_Annotation->GetTextProperty()->SetOpacity(0.5);
|
|
||||||
m_Annotation->SetMaximumFontSize(10);
|
|
||||||
m_Annotation->SetText(0, "uLib VTK Viewer - OpenCMT all right reserved.");
|
|
||||||
m_Renderer->AddViewProp(m_Annotation);
|
|
||||||
|
|
||||||
// orientation marker //
|
|
||||||
vtkSmartPointer<vtkAxesActor> axes = vtkSmartPointer<vtkAxesActor>::New();
|
|
||||||
m_Marker->SetInteractor(renderWindowInteractor);
|
|
||||||
m_Marker->SetOrientationMarker(axes);
|
|
||||||
m_Marker->SetViewport(0.0, 0.0, 0.2, 0.2);
|
|
||||||
m_Marker->SetEnabled(true);
|
|
||||||
m_Marker->InteractiveOff();
|
|
||||||
|
|
||||||
// camera orientation widget //
|
|
||||||
if (m_CameraWidget) {
|
|
||||||
m_CameraWidget->SetParentRenderer(m_Renderer);
|
|
||||||
m_CameraWidget->SetInteractor(renderWindowInteractor);
|
|
||||||
m_CameraWidget->On();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Must be rendered here in Vtk-6.0 or seg-fault //
|
// Must be rendered here in Vtk-6.0 or seg-fault //
|
||||||
m_RenderWindow->Render();
|
m_RenderWindow->Render();
|
||||||
}
|
}
|
||||||
@@ -130,25 +97,9 @@ void Viewer::UninstallPipe() {
|
|||||||
m_Renderer->Clear();
|
m_Renderer->Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Viewer::addProp(vtkProp *prop) {
|
void Viewer::Render() {
|
||||||
m_Renderer->AddActor(prop);
|
if (m_RenderWindow)
|
||||||
m_Renderer->Render();
|
m_RenderWindow->Render();
|
||||||
}
|
|
||||||
|
|
||||||
void Viewer::RemoveProp(vtkProp *prop) {
|
|
||||||
m_Renderer->RemoveViewProp(prop);
|
|
||||||
m_Renderer->Render();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Viewer::AddPuppet(Puppet &prop) {
|
|
||||||
prop.ConnectRenderer(m_Renderer);
|
|
||||||
prop.ConnectInteractor(this->GetInteractor());
|
|
||||||
m_Renderer->Render();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Viewer::RemovePuppet(Puppet &prop) {
|
|
||||||
prop.DisconnectRenderer(m_Renderer);
|
|
||||||
m_Renderer->Render();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vtkSmartPointer<vtkCameraOrientationWidget>
|
vtkSmartPointer<vtkCameraOrientationWidget>
|
||||||
@@ -164,27 +115,11 @@ Viewer::MakeCameraOrientationWidget(vtkRenderWindowInteractor *interactor,
|
|||||||
|
|
||||||
void Viewer::Start() { m_RenderWindow->GetInteractor()->Start(); }
|
void Viewer::Start() { m_RenderWindow->GetInteractor()->Start(); }
|
||||||
|
|
||||||
vtkCornerAnnotation *Viewer::GetAnnotation() { return m_Annotation; }
|
|
||||||
|
|
||||||
vtkRenderer *Viewer::GetRenderer() { return m_Renderer; }
|
|
||||||
|
|
||||||
vtkRenderWindow *Viewer::GetRenderWindow() { return m_RenderWindow; }
|
vtkRenderWindow *Viewer::GetRenderWindow() { return m_RenderWindow; }
|
||||||
|
|
||||||
vtkRenderWindowInteractor *Viewer::GetInteractor() {
|
vtkRenderWindowInteractor *Viewer::GetInteractor() {
|
||||||
return m_RenderWindow->GetInteractor();
|
return m_RenderWindow->GetInteractor();
|
||||||
}
|
}
|
||||||
|
|
||||||
vtkCameraOrientationWidget *Viewer::GetCameraWidget() { return m_CameraWidget; }
|
|
||||||
|
|
||||||
void Viewer::Reset() {
|
|
||||||
this->ZoomAuto();
|
|
||||||
m_Renderer->Render();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Viewer::ZoomAuto() {
|
|
||||||
m_Renderer->ResetCameraClippingRange();
|
|
||||||
m_Renderer->ResetCamera();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Vtk
|
} // namespace Vtk
|
||||||
} // namespace uLib
|
} // namespace uLib
|
||||||
|
|||||||
@@ -26,80 +26,49 @@
|
|||||||
#ifndef ULIBVTKVIEWER_H
|
#ifndef ULIBVTKVIEWER_H
|
||||||
#define ULIBVTKVIEWER_H
|
#define ULIBVTKVIEWER_H
|
||||||
|
|
||||||
#include "uLibVtkInterface.h"
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include <vtkCornerAnnotation.h>
|
#include "vtkViewport.h"
|
||||||
#include <vtkOrientationMarkerWidget.h>
|
|
||||||
#include <vtkRenderWindow.h>
|
|
||||||
#include <vtkRenderer.h>
|
|
||||||
#include <vtkSmartPointer.h>
|
|
||||||
|
|
||||||
class vtkProp;
|
|
||||||
class vtk3DWidget;
|
|
||||||
class vtkCornerAnnotation;
|
|
||||||
class vtkRenderWindowInteractor;
|
|
||||||
class vtkRenderer;
|
|
||||||
class vtkCameraOrientationWidget;
|
|
||||||
|
|
||||||
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 Viewport {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Viewer();
|
Viewer();
|
||||||
~Viewer();
|
virtual ~Viewer();
|
||||||
|
|
||||||
void AddPuppet(Puppet &prop);
|
// Render scene
|
||||||
|
virtual void Render() override;
|
||||||
void RemovePuppet(Puppet &prop);
|
|
||||||
|
|
||||||
void AddWidget(vtk3DWidget *widget);
|
|
||||||
|
|
||||||
static vtkSmartPointer<vtkCameraOrientationWidget>
|
static vtkSmartPointer<vtkCameraOrientationWidget>
|
||||||
MakeCameraOrientationWidget(vtkRenderWindowInteractor *interactor,
|
MakeCameraOrientationWidget(vtkRenderWindowInteractor *interactor,
|
||||||
vtkRenderer *renderer);
|
vtkRenderer *renderer);
|
||||||
|
|
||||||
void Reset();
|
|
||||||
void ZoomAuto();
|
|
||||||
|
|
||||||
void Start();
|
void Start();
|
||||||
|
|
||||||
vtkCornerAnnotation *GetAnnotation();
|
virtual vtkRenderWindow *GetRenderWindow() override;
|
||||||
|
virtual vtkRenderWindowInteractor *GetInteractor() override;
|
||||||
vtkRenderer *GetRenderer();
|
|
||||||
vtkRenderWindow *GetRenderWindow();
|
|
||||||
vtkRenderWindowInteractor *GetInteractor();
|
|
||||||
|
|
||||||
vtkCameraOrientationWidget *GetCameraWidget();
|
|
||||||
|
|
||||||
void addProp(vtkProp *prop);
|
|
||||||
|
|
||||||
void RemoveProp(vtkProp *prop);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void InstallPipe();
|
void InstallPipe();
|
||||||
void UninstallPipe();
|
void UninstallPipe();
|
||||||
|
|
||||||
vtkRenderer *m_Renderer;
|
|
||||||
vtkRenderWindow *m_RenderWindow;
|
vtkRenderWindow *m_RenderWindow;
|
||||||
vtkCornerAnnotation *m_Annotation;
|
|
||||||
vtkOrientationMarkerWidget *m_Marker;
|
|
||||||
vtkCameraOrientationWidget *m_CameraWidget;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <> class Tie<Viewer> {
|
// template <> class Tie<Viewer> {
|
||||||
public:
|
// public:
|
||||||
void DoAction() { std::cout << " VIEWER TIE !!! \n"; }
|
// void DoAction() { std::cout << " VIEWER TIE !!! \n"; }
|
||||||
};
|
// };
|
||||||
|
|
||||||
} // namespace Vtk
|
} // namespace Vtk
|
||||||
} // namespace uLib
|
} // namespace uLib
|
||||||
|
|||||||
@@ -15,11 +15,8 @@ namespace Vtk {
|
|||||||
|
|
||||||
QViewport::QViewport(QWidget* parent)
|
QViewport::QViewport(QWidget* parent)
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
|
, Viewport()
|
||||||
, m_VtkWidget(nullptr)
|
, m_VtkWidget(nullptr)
|
||||||
, m_Renderer(vtkRenderer::New())
|
|
||||||
, m_Annotation(vtkCornerAnnotation::New())
|
|
||||||
, m_Marker(vtkOrientationMarkerWidget::New())
|
|
||||||
, m_CameraWidget(nullptr)
|
|
||||||
{
|
{
|
||||||
// Build the layout – zero margins so VTK fills the entire widget
|
// Build the layout – zero margins so VTK fills the entire widget
|
||||||
auto* layout = new QVBoxLayout(this);
|
auto* layout = new QVBoxLayout(this);
|
||||||
@@ -36,14 +33,6 @@ QViewport::QViewport(QWidget* parent)
|
|||||||
|
|
||||||
QViewport::~QViewport()
|
QViewport::~QViewport()
|
||||||
{
|
{
|
||||||
m_Renderer->RemoveAllViewProps();
|
|
||||||
m_Renderer->Clear();
|
|
||||||
|
|
||||||
m_Annotation->Delete();
|
|
||||||
m_Marker->Delete();
|
|
||||||
if (m_CameraWidget)
|
|
||||||
m_CameraWidget->Delete();
|
|
||||||
m_Renderer->Delete();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void QViewport::SetupPipeline()
|
void QViewport::SetupPipeline()
|
||||||
@@ -52,90 +41,19 @@ void QViewport::SetupPipeline()
|
|||||||
vtkRenderWindow* rw = m_VtkWidget->renderWindow();
|
vtkRenderWindow* rw = m_VtkWidget->renderWindow();
|
||||||
rw->AddRenderer(m_Renderer);
|
rw->AddRenderer(m_Renderer);
|
||||||
|
|
||||||
// Qt will supply its own interactor – grab it
|
// Common setup
|
||||||
vtkRenderWindowInteractor* iren = rw->GetInteractor();
|
Viewport::SetupPipeline(rw->GetInteractor());
|
||||||
|
|
||||||
// Trackball-camera interaction style
|
|
||||||
vtkNew<vtkInteractorStyleTrackballCamera> style;
|
|
||||||
iren->SetInteractorStyle(style);
|
|
||||||
|
|
||||||
// Corner annotation
|
|
||||||
m_Annotation->GetTextProperty()->SetColor(1, 1, 1);
|
|
||||||
m_Annotation->GetTextProperty()->SetFontFamilyToArial();
|
|
||||||
m_Annotation->GetTextProperty()->SetOpacity(0.5);
|
|
||||||
m_Annotation->SetMaximumFontSize(10);
|
|
||||||
m_Annotation->SetText(0, "uLib VTK Viewer - OpenCMT all right reserved.");
|
|
||||||
m_Renderer->AddViewProp(m_Annotation);
|
|
||||||
|
|
||||||
// Orientation axes marker (bottom-left corner)
|
|
||||||
vtkNew<vtkAxesActor> axes;
|
|
||||||
m_Marker->SetInteractor(iren);
|
|
||||||
m_Marker->SetOrientationMarker(axes);
|
|
||||||
m_Marker->SetViewport(0.0, 0.0, 0.2, 0.2);
|
|
||||||
m_Marker->SetEnabled(true);
|
|
||||||
m_Marker->InteractiveOff();
|
|
||||||
|
|
||||||
// Camera-orientation widget (VTK ≥ 9)
|
|
||||||
#if VTK_MAJOR_VERSION >= 9
|
|
||||||
m_CameraWidget = vtkCameraOrientationWidget::New();
|
|
||||||
m_CameraWidget->SetParentRenderer(m_Renderer);
|
|
||||||
m_CameraWidget->SetInteractor(iren);
|
|
||||||
m_CameraWidget->On();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
m_Renderer->SetBackground(0.15, 0.15, 0.15);
|
|
||||||
m_Renderer->ResetCamera();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Public API ────────────────────────────────────────────────────────────────
|
// ── Public API ────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
void QViewport::Render()
|
void QViewport::Render()
|
||||||
{
|
{
|
||||||
|
UpdateGrid();
|
||||||
|
if (m_VtkWidget && m_VtkWidget->renderWindow())
|
||||||
m_VtkWidget->renderWindow()->Render();
|
m_VtkWidget->renderWindow()->Render();
|
||||||
}
|
}
|
||||||
|
|
||||||
void QViewport::Reset()
|
|
||||||
{
|
|
||||||
ZoomAuto();
|
|
||||||
Render();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QViewport::ZoomAuto()
|
|
||||||
{
|
|
||||||
m_Renderer->ResetCameraClippingRange();
|
|
||||||
m_Renderer->ResetCamera();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QViewport::AddPuppet(Puppet& prop)
|
|
||||||
{
|
|
||||||
prop.ConnectRenderer(m_Renderer);
|
|
||||||
prop.ConnectInteractor(GetInteractor());
|
|
||||||
Render();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QViewport::RemovePuppet(Puppet& prop)
|
|
||||||
{
|
|
||||||
prop.DisconnectRenderer(m_Renderer);
|
|
||||||
Render();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QViewport::addProp(vtkProp* prop)
|
|
||||||
{
|
|
||||||
m_Renderer->AddActor(prop);
|
|
||||||
Render();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QViewport::RemoveProp(vtkProp* prop)
|
|
||||||
{
|
|
||||||
m_Renderer->RemoveViewProp(prop);
|
|
||||||
Render();
|
|
||||||
}
|
|
||||||
|
|
||||||
void QViewport::AddWidget(vtk3DWidget* /*widget*/)
|
|
||||||
{
|
|
||||||
// vtk3DWidget integration can be added here if needed
|
|
||||||
}
|
|
||||||
|
|
||||||
vtkRenderWindow* QViewport::GetRenderWindow()
|
vtkRenderWindow* QViewport::GetRenderWindow()
|
||||||
{
|
{
|
||||||
return m_VtkWidget->renderWindow();
|
return m_VtkWidget->renderWindow();
|
||||||
|
|||||||
@@ -12,6 +12,8 @@
|
|||||||
|
|
||||||
#include "uLibVtkInterface.h"
|
#include "uLibVtkInterface.h"
|
||||||
|
|
||||||
|
#include "vtkViewport.h"
|
||||||
|
|
||||||
class vtkProp;
|
class vtkProp;
|
||||||
class vtk3DWidget;
|
class vtk3DWidget;
|
||||||
class vtkRenderWindowInteractor;
|
class vtkRenderWindowInteractor;
|
||||||
@@ -25,42 +27,24 @@ namespace Vtk {
|
|||||||
* directly into the Qt application (no separate VTK window).
|
* directly into the Qt application (no separate VTK window).
|
||||||
* Puppets and actors are added to the embedded renderer.
|
* Puppets and actors are added to the embedded renderer.
|
||||||
*/
|
*/
|
||||||
class QViewport : public QWidget {
|
class QViewport : public QWidget, public Viewport {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit QViewport(QWidget* parent = nullptr);
|
explicit QViewport(QWidget* parent = nullptr);
|
||||||
virtual ~QViewport();
|
virtual ~QViewport();
|
||||||
|
|
||||||
// Render scene
|
// Render scene
|
||||||
void Render();
|
virtual void Render() override;
|
||||||
void Reset();
|
|
||||||
void ZoomAuto();
|
|
||||||
|
|
||||||
// Puppet / prop management
|
|
||||||
void AddPuppet(Puppet &prop);
|
|
||||||
void RemovePuppet(Puppet &prop);
|
|
||||||
void addProp(vtkProp *prop);
|
|
||||||
void RemoveProp(vtkProp *prop);
|
|
||||||
|
|
||||||
// Widget integration
|
|
||||||
void AddWidget(vtk3DWidget *widget);
|
|
||||||
|
|
||||||
// Direct access to VTK internals
|
// Direct access to VTK internals
|
||||||
vtkRenderer* GetRenderer() { return m_Renderer; }
|
virtual vtkRenderWindow* GetRenderWindow() override;
|
||||||
vtkRenderWindow* GetRenderWindow();
|
virtual vtkRenderWindowInteractor* GetInteractor() override;
|
||||||
vtkRenderWindowInteractor* GetInteractor();
|
|
||||||
vtkCornerAnnotation* GetAnnotation() { return m_Annotation; }
|
|
||||||
vtkCameraOrientationWidget* GetCameraWidget(){ return m_CameraWidget; }
|
|
||||||
QVTKOpenGLNativeWidget* GetWidget() { return m_VtkWidget; }
|
QVTKOpenGLNativeWidget* GetWidget() { return m_VtkWidget; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void SetupPipeline();
|
void SetupPipeline();
|
||||||
|
|
||||||
QVTKOpenGLNativeWidget* m_VtkWidget;
|
QVTKOpenGLNativeWidget* m_VtkWidget;
|
||||||
vtkRenderer* m_Renderer;
|
|
||||||
vtkCornerAnnotation* m_Annotation;
|
|
||||||
vtkOrientationMarkerWidget* m_Marker;
|
|
||||||
vtkCameraOrientationWidget* m_CameraWidget;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Vtk
|
} // namespace Vtk
|
||||||
|
|||||||
228
src/Vtk/vtkViewport.cpp
Normal file
228
src/Vtk/vtkViewport.cpp
Normal file
@@ -0,0 +1,228 @@
|
|||||||
|
#include "vtkViewport.h"
|
||||||
|
|
||||||
|
#include <vtkAxes.h>
|
||||||
|
#include <vtkAxesActor.h>
|
||||||
|
#include <vtkCamera.h>
|
||||||
|
#include <vtkCameraOrientationWidget.h>
|
||||||
|
#include <vtkInteractorStyleTrackballCamera.h>
|
||||||
|
#include <vtkObjectFactory.h>
|
||||||
|
#include <vtkPlaneSource.h>
|
||||||
|
#include <vtkRenderWindow.h>
|
||||||
|
#include <vtkRenderWindowInteractor.h>
|
||||||
|
#include <vtkSmartPointer.h>
|
||||||
|
#include <vtkNew.h>
|
||||||
|
#include <vtkTextProperty.h>
|
||||||
|
|
||||||
|
#include <vtkPolyDataMapper.h>
|
||||||
|
|
||||||
|
#include <vtkNamedColors.h>
|
||||||
|
#include <vtkProperty.h>
|
||||||
|
#include <vtkCallbackCommand.h>
|
||||||
|
#include <vtkMath.h>
|
||||||
|
#include <vtkActor.h>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
namespace uLib {
|
||||||
|
namespace Vtk {
|
||||||
|
|
||||||
|
Viewport::Viewport()
|
||||||
|
: m_Renderer(vtkRenderer::New())
|
||||||
|
, m_Annotation(vtkCornerAnnotation::New())
|
||||||
|
, m_Marker(vtkOrientationMarkerWidget::New())
|
||||||
|
, m_CameraWidget(nullptr)
|
||||||
|
, m_Colors(vtkNamedColors::New())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Viewport::~Viewport()
|
||||||
|
{
|
||||||
|
if (m_Renderer) {
|
||||||
|
m_Renderer->RemoveAllViewProps();
|
||||||
|
m_Renderer->Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_Annotation) m_Annotation->Delete();
|
||||||
|
if (m_Marker) m_Marker->Delete();
|
||||||
|
if (m_CameraWidget) m_CameraWidget->Delete();
|
||||||
|
if (m_Renderer) m_Renderer->Delete();
|
||||||
|
if (m_Colors) m_Colors->Delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Viewport::SetupPipeline(vtkRenderWindowInteractor* iren)
|
||||||
|
{
|
||||||
|
if (!iren) return;
|
||||||
|
|
||||||
|
// Trackball-camera interaction style
|
||||||
|
vtkNew<vtkInteractorStyleTrackballCamera> style;
|
||||||
|
iren->SetInteractorStyle(style);
|
||||||
|
|
||||||
|
// Corner annotation
|
||||||
|
m_Annotation->GetTextProperty()->SetColor(1, 1, 1);
|
||||||
|
m_Annotation->GetTextProperty()->SetFontFamilyToArial();
|
||||||
|
m_Annotation->GetTextProperty()->SetOpacity(0.5);
|
||||||
|
m_Annotation->SetMaximumFontSize(10);
|
||||||
|
m_Annotation->SetText(0, "uLib VTK Viewer - OpenCMT all right reserved.");
|
||||||
|
m_Renderer->AddViewProp(m_Annotation);
|
||||||
|
|
||||||
|
// Orientation axes marker (bottom-left corner)
|
||||||
|
vtkNew<vtkAxesActor> axes;
|
||||||
|
m_Marker->SetInteractor(iren);
|
||||||
|
m_Marker->SetOrientationMarker(axes);
|
||||||
|
m_Marker->SetViewport(0.0, 0.0, 0.2, 0.2);
|
||||||
|
m_Marker->SetEnabled(true);
|
||||||
|
m_Marker->InteractiveOff();
|
||||||
|
|
||||||
|
// Grid Plane centered at (0,0,0)
|
||||||
|
m_GridSource = vtkSmartPointer<vtkPlaneSource>::New();
|
||||||
|
m_GridActor = vtkSmartPointer<vtkActor>::New();
|
||||||
|
vtkNew<vtkPolyDataMapper> gridMapper;
|
||||||
|
gridMapper->SetInputConnection(m_GridSource->GetOutputPort());
|
||||||
|
|
||||||
|
m_GridActor->SetMapper(gridMapper);
|
||||||
|
m_GridActor->GetProperty()->SetRepresentationToWireframe();
|
||||||
|
m_GridActor->GetProperty()->SetColor(0.4, 0.4, 0.4);
|
||||||
|
m_GridActor->GetProperty()->SetLighting(0);
|
||||||
|
m_GridActor->GetProperty()->SetOpacity(0.5);
|
||||||
|
m_GridActor->PickableOff();
|
||||||
|
m_Renderer->AddActor(m_GridActor);
|
||||||
|
|
||||||
|
// Global Origin Axes
|
||||||
|
m_OriginAxes = vtkSmartPointer<vtkAxes>::New();
|
||||||
|
m_OriginAxes->SetScaleFactor(1.0); // will be updated
|
||||||
|
|
||||||
|
vtkNew<vtkPolyDataMapper> axesMapper;
|
||||||
|
axesMapper->SetInputConnection(m_OriginAxes->GetOutputPort());
|
||||||
|
|
||||||
|
m_OriginAxesActor = vtkSmartPointer<vtkActor>::New();
|
||||||
|
m_OriginAxesActor->SetMapper(axesMapper);
|
||||||
|
m_OriginAxesActor->PickableOff();
|
||||||
|
m_Renderer->AddActor(m_OriginAxesActor);
|
||||||
|
|
||||||
|
UpdateGrid();
|
||||||
|
|
||||||
|
// Observe interactor to update grid during interaction
|
||||||
|
vtkNew<vtkCallbackCommand> interactionCallback;
|
||||||
|
interactionCallback->SetClientData(this);
|
||||||
|
interactionCallback->SetCallback([](vtkObject*, unsigned long, void* clientdata, void*){
|
||||||
|
static_cast<Viewport*>(clientdata)->UpdateGrid();
|
||||||
|
});
|
||||||
|
iren->AddObserver(vtkCommand::InteractionEvent, interactionCallback);
|
||||||
|
m_Renderer->GetActiveCamera()->AddObserver(vtkCommand::ModifiedEvent, interactionCallback);
|
||||||
|
|
||||||
|
|
||||||
|
// Camera-orientation widget (VTK >= 9)
|
||||||
|
#if VTK_MAJOR_VERSION >= 9
|
||||||
|
m_CameraWidget = vtkCameraOrientationWidget::New();
|
||||||
|
m_CameraWidget->SetParentRenderer(m_Renderer);
|
||||||
|
m_CameraWidget->SetInteractor(iren);
|
||||||
|
m_CameraWidget->On();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
m_Renderer->SetBackground(0.15, 0.15, 0.15);
|
||||||
|
m_Renderer->ResetCamera();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Viewport::Reset()
|
||||||
|
{
|
||||||
|
ZoomAuto();
|
||||||
|
Render();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Viewport::ZoomAuto()
|
||||||
|
{
|
||||||
|
if (m_Renderer) {
|
||||||
|
m_Renderer->ResetCameraClippingRange();
|
||||||
|
m_Renderer->ResetCamera();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Viewport::AddPuppet(Puppet& prop)
|
||||||
|
{
|
||||||
|
prop.ConnectRenderer(m_Renderer);
|
||||||
|
prop.ConnectInteractor(GetInteractor());
|
||||||
|
Render();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Viewport::RemovePuppet(Puppet& prop)
|
||||||
|
{
|
||||||
|
prop.DisconnectRenderer(m_Renderer);
|
||||||
|
Render();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Viewport::addProp(vtkProp* prop)
|
||||||
|
{
|
||||||
|
if (m_Renderer) {
|
||||||
|
m_Renderer->AddActor(prop);
|
||||||
|
Render();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Viewport::RemoveProp(vtkProp* prop)
|
||||||
|
{
|
||||||
|
if (m_Renderer) {
|
||||||
|
m_Renderer->RemoveViewProp(prop);
|
||||||
|
Render();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Viewport::UpdateGrid()
|
||||||
|
{
|
||||||
|
if (!m_Renderer || !m_GridSource) return;
|
||||||
|
|
||||||
|
vtkCamera* camera = m_Renderer->GetActiveCamera();
|
||||||
|
if (!camera) return;
|
||||||
|
|
||||||
|
// Determine the "scale" of the view (how many units are visible vertically)
|
||||||
|
double viewHeight;
|
||||||
|
if (camera->GetParallelProjection()) {
|
||||||
|
viewHeight = 2.0 * camera->GetParallelScale();
|
||||||
|
} else {
|
||||||
|
double distance = camera->GetDistance();
|
||||||
|
// ViewAngle is height angle in degrees
|
||||||
|
double angleRad = camera->GetViewAngle() * vtkMath::Pi() / 180.0;
|
||||||
|
viewHeight = 2.0 * distance * std::tan(angleRad / 2.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (viewHeight <= 0) viewHeight = 1.0;
|
||||||
|
|
||||||
|
// We want roughly 5-15 grid divisions visible.
|
||||||
|
// Spacing should be a power of 10 (1mm, 1cm, 10cm, 1m, 10m...)
|
||||||
|
double log10Spacing = std::floor(std::log10(viewHeight / 5.0));
|
||||||
|
double spacing = std::pow(10.0, log10Spacing);
|
||||||
|
|
||||||
|
// Get current focal point to center the grid near what we're looking at
|
||||||
|
double focalPoint[3];
|
||||||
|
camera->GetFocalPoint(focalPoint);
|
||||||
|
|
||||||
|
// Align center to spacing
|
||||||
|
double centerX = std::round(focalPoint[0] / spacing) * spacing;
|
||||||
|
double centerY = std::round(focalPoint[1] / spacing) * spacing;
|
||||||
|
|
||||||
|
// Number of lines: enough to cover the screen even if aspect ratio is wide
|
||||||
|
// or if we rotate. 20x20 is usually plenty.
|
||||||
|
int numLines = 20;
|
||||||
|
double halfSize = (numLines / 2.0) * spacing;
|
||||||
|
|
||||||
|
double xmin = centerX - halfSize;
|
||||||
|
double xmax = centerX + halfSize;
|
||||||
|
double ymin = centerY - halfSize;
|
||||||
|
double ymax = centerY + halfSize;
|
||||||
|
|
||||||
|
// Update Plane Source
|
||||||
|
m_GridSource->SetOrigin(xmin, ymin, 0.0);
|
||||||
|
m_GridSource->SetPoint1(xmax, ymin, 0.0);
|
||||||
|
m_GridSource->SetPoint2(xmin, ymax, 0.0);
|
||||||
|
m_GridSource->SetXResolution(numLines);
|
||||||
|
m_GridSource->SetYResolution(numLines);
|
||||||
|
m_GridSource->Update();
|
||||||
|
|
||||||
|
if (m_OriginAxes) {
|
||||||
|
m_OriginAxes->SetScaleFactor(spacing);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Vtk
|
||||||
|
} // namespace uLib
|
||||||
76
src/Vtk/vtkViewport.h
Normal file
76
src/Vtk/vtkViewport.h
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
#ifndef ULIB_VTK_VIEWPORT_H
|
||||||
|
#define ULIB_VTK_VIEWPORT_H
|
||||||
|
|
||||||
|
#include "uLibVtkInterface.h"
|
||||||
|
#include <vtkCornerAnnotation.h>
|
||||||
|
#include <vtkOrientationMarkerWidget.h>
|
||||||
|
#include <vtkRenderer.h>
|
||||||
|
#include <vtkSmartPointer.h>
|
||||||
|
#include <vtkVersion.h>
|
||||||
|
|
||||||
|
class vtkAxes;
|
||||||
|
class vtkProp;
|
||||||
|
class vtk3DWidget;
|
||||||
|
class vtkRenderWindow;
|
||||||
|
class vtkRenderWindowInteractor;
|
||||||
|
class vtkCameraOrientationWidget;
|
||||||
|
class vtkPlaneSource;
|
||||||
|
class vtkActor;
|
||||||
|
class vtkNamedColors;
|
||||||
|
class vtkCamera;
|
||||||
|
|
||||||
|
namespace uLib {
|
||||||
|
namespace Vtk {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class Viewport
|
||||||
|
* @brief Base class for VTK viewports, providing core rendering and prop management.
|
||||||
|
*/
|
||||||
|
class Viewport {
|
||||||
|
public:
|
||||||
|
Viewport();
|
||||||
|
virtual ~Viewport();
|
||||||
|
|
||||||
|
// Render scene
|
||||||
|
virtual void Render() = 0;
|
||||||
|
void Reset();
|
||||||
|
void ZoomAuto();
|
||||||
|
|
||||||
|
// Puppet / prop management
|
||||||
|
void AddPuppet(Puppet &prop);
|
||||||
|
void RemovePuppet(Puppet &prop);
|
||||||
|
void addProp(vtkProp *prop);
|
||||||
|
void RemoveProp(vtkProp *prop);
|
||||||
|
|
||||||
|
// Widget integration
|
||||||
|
void AddWidget(vtk3DWidget *widget);
|
||||||
|
|
||||||
|
// Direct access to VTK internals
|
||||||
|
vtkRenderer* GetRenderer() { return m_Renderer; }
|
||||||
|
virtual vtkRenderWindow* GetRenderWindow() = 0;
|
||||||
|
virtual vtkRenderWindowInteractor* GetInteractor() = 0;
|
||||||
|
vtkCornerAnnotation* GetAnnotation() { return m_Annotation; }
|
||||||
|
vtkCameraOrientationWidget* GetCameraWidget(){ return m_CameraWidget; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void SetupPipeline(vtkRenderWindowInteractor* iren);
|
||||||
|
|
||||||
|
void UpdateGrid();
|
||||||
|
|
||||||
|
vtkRenderer* m_Renderer;
|
||||||
|
vtkCornerAnnotation* m_Annotation;
|
||||||
|
vtkOrientationMarkerWidget* m_Marker;
|
||||||
|
vtkCameraOrientationWidget* m_CameraWidget;
|
||||||
|
|
||||||
|
vtkSmartPointer<vtkPlaneSource> m_GridSource;
|
||||||
|
vtkSmartPointer<vtkActor> m_GridActor;
|
||||||
|
vtkSmartPointer<vtkAxes> m_OriginAxes;
|
||||||
|
vtkSmartPointer<vtkActor> m_OriginAxesActor;
|
||||||
|
|
||||||
|
vtkNamedColors* m_Colors;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Vtk
|
||||||
|
} // namespace uLib
|
||||||
|
|
||||||
|
#endif // ULIB_VTK_VIEWPORT_H
|
||||||
Reference in New Issue
Block a user