split viewport for Qt and VtkViewer
This commit is contained in:
@@ -3,6 +3,7 @@ set(HEADERS uLibVtkInterface.h
|
||||
vtkContainerBox.h
|
||||
vtkHandlerWidget.h
|
||||
vtkQViewport.h
|
||||
vtkViewport.h
|
||||
vtkPolydata.h
|
||||
)
|
||||
|
||||
@@ -11,6 +12,7 @@ set(SOURCES uLibVtkInterface.cxx
|
||||
vtkContainerBox.cpp
|
||||
vtkHandlerWidget.cpp
|
||||
vtkQViewport.cpp
|
||||
vtkViewport.cpp
|
||||
vtkPolydata.cpp
|
||||
)
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <vtkInteractorStyleTrackballCamera.h>
|
||||
#include <vtkObjectFactory.h>
|
||||
#include <vtkTextProperty.h>
|
||||
#include <vtkRenderWindow.h>
|
||||
|
||||
#include "uLibVtkViewer.h"
|
||||
|
||||
@@ -56,8 +57,6 @@ public:
|
||||
};
|
||||
vtkStandardNewMacro(vtkInteractorStyleNoSpin);
|
||||
|
||||
|
||||
|
||||
namespace uLib {
|
||||
namespace Vtk {
|
||||
|
||||
@@ -65,24 +64,12 @@ namespace Vtk {
|
||||
///// VTK VIEWER //////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
Viewer::Viewer()
|
||||
: m_RenderWindow(vtkRenderWindow::New()), m_Renderer(vtkRenderer::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
|
||||
: Viewport(), m_RenderWindow(vtkRenderWindow::New()) {
|
||||
InstallPipe();
|
||||
}
|
||||
|
||||
Viewer::~Viewer() {
|
||||
UninstallPipe();
|
||||
|
||||
m_Annotation->Delete();
|
||||
m_Marker->Delete();
|
||||
if (m_CameraWidget)
|
||||
m_CameraWidget->Delete();
|
||||
m_Renderer->Delete();
|
||||
m_RenderWindow->Delete();
|
||||
}
|
||||
|
||||
@@ -93,34 +80,14 @@ void Viewer::InstallPipe() {
|
||||
vtkSmartPointer<vtkRenderWindowInteractor>::New();
|
||||
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>::New();
|
||||
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 //
|
||||
m_RenderWindow->Render();
|
||||
}
|
||||
@@ -130,25 +97,9 @@ void Viewer::UninstallPipe() {
|
||||
m_Renderer->Clear();
|
||||
}
|
||||
|
||||
void Viewer::addProp(vtkProp *prop) {
|
||||
m_Renderer->AddActor(prop);
|
||||
m_Renderer->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();
|
||||
void Viewer::Render() {
|
||||
if (m_RenderWindow)
|
||||
m_RenderWindow->Render();
|
||||
}
|
||||
|
||||
vtkSmartPointer<vtkCameraOrientationWidget>
|
||||
@@ -164,27 +115,11 @@ Viewer::MakeCameraOrientationWidget(vtkRenderWindowInteractor *interactor,
|
||||
|
||||
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; }
|
||||
|
||||
vtkRenderWindowInteractor *Viewer::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 uLib
|
||||
|
||||
@@ -26,80 +26,49 @@
|
||||
#ifndef ULIBVTKVIEWER_H
|
||||
#define ULIBVTKVIEWER_H
|
||||
|
||||
#include "uLibVtkInterface.h"
|
||||
#include <iostream>
|
||||
|
||||
#include <vtkCornerAnnotation.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;
|
||||
#include "vtkViewport.h"
|
||||
|
||||
namespace uLib {
|
||||
namespace Vtk {
|
||||
|
||||
template <class T> class Tie {
|
||||
public:
|
||||
void DoAction() {
|
||||
std::cout << "Tie::DoAction -> generic Tie does nothing\n";
|
||||
}
|
||||
};
|
||||
// template <class T> class Tie {
|
||||
// public:
|
||||
// void DoAction() {
|
||||
// std::cout << "Tie::DoAction -> generic Tie does nothing\n";
|
||||
// }
|
||||
// };
|
||||
|
||||
class Viewer {
|
||||
class Viewer : public Viewport {
|
||||
|
||||
public:
|
||||
Viewer();
|
||||
~Viewer();
|
||||
virtual ~Viewer();
|
||||
|
||||
void AddPuppet(Puppet &prop);
|
||||
|
||||
void RemovePuppet(Puppet &prop);
|
||||
|
||||
void AddWidget(vtk3DWidget *widget);
|
||||
// Render scene
|
||||
virtual void Render() override;
|
||||
|
||||
static vtkSmartPointer<vtkCameraOrientationWidget>
|
||||
MakeCameraOrientationWidget(vtkRenderWindowInteractor *interactor,
|
||||
vtkRenderer *renderer);
|
||||
|
||||
void Reset();
|
||||
void ZoomAuto();
|
||||
vtkRenderer *renderer);
|
||||
|
||||
void Start();
|
||||
|
||||
vtkCornerAnnotation *GetAnnotation();
|
||||
|
||||
vtkRenderer *GetRenderer();
|
||||
vtkRenderWindow *GetRenderWindow();
|
||||
vtkRenderWindowInteractor *GetInteractor();
|
||||
|
||||
vtkCameraOrientationWidget *GetCameraWidget();
|
||||
|
||||
void addProp(vtkProp *prop);
|
||||
|
||||
void RemoveProp(vtkProp *prop);
|
||||
virtual vtkRenderWindow *GetRenderWindow() override;
|
||||
virtual vtkRenderWindowInteractor *GetInteractor() override;
|
||||
|
||||
private:
|
||||
void InstallPipe();
|
||||
void UninstallPipe();
|
||||
|
||||
vtkRenderer *m_Renderer;
|
||||
vtkRenderWindow *m_RenderWindow;
|
||||
vtkCornerAnnotation *m_Annotation;
|
||||
vtkOrientationMarkerWidget *m_Marker;
|
||||
vtkCameraOrientationWidget *m_CameraWidget;
|
||||
};
|
||||
|
||||
template <> class Tie<Viewer> {
|
||||
public:
|
||||
void DoAction() { std::cout << " VIEWER TIE !!! \n"; }
|
||||
};
|
||||
// template <> class Tie<Viewer> {
|
||||
// public:
|
||||
// void DoAction() { std::cout << " VIEWER TIE !!! \n"; }
|
||||
// };
|
||||
|
||||
} // namespace Vtk
|
||||
} // namespace uLib
|
||||
|
||||
@@ -15,11 +15,8 @@ namespace Vtk {
|
||||
|
||||
QViewport::QViewport(QWidget* parent)
|
||||
: QWidget(parent)
|
||||
, Viewport()
|
||||
, 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
|
||||
auto* layout = new QVBoxLayout(this);
|
||||
@@ -36,14 +33,6 @@ QViewport::QViewport(QWidget* parent)
|
||||
|
||||
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()
|
||||
@@ -52,88 +41,17 @@ void QViewport::SetupPipeline()
|
||||
vtkRenderWindow* rw = m_VtkWidget->renderWindow();
|
||||
rw->AddRenderer(m_Renderer);
|
||||
|
||||
// Qt will supply its own interactor – grab it
|
||||
vtkRenderWindowInteractor* iren = 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();
|
||||
// Common setup
|
||||
Viewport::SetupPipeline(rw->GetInteractor());
|
||||
}
|
||||
|
||||
// ── Public API ────────────────────────────────────────────────────────────────
|
||||
|
||||
void QViewport::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
|
||||
UpdateGrid();
|
||||
if (m_VtkWidget && m_VtkWidget->renderWindow())
|
||||
m_VtkWidget->renderWindow()->Render();
|
||||
}
|
||||
|
||||
vtkRenderWindow* QViewport::GetRenderWindow()
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
|
||||
#include "uLibVtkInterface.h"
|
||||
|
||||
#include "vtkViewport.h"
|
||||
|
||||
class vtkProp;
|
||||
class vtk3DWidget;
|
||||
class vtkRenderWindowInteractor;
|
||||
@@ -25,42 +27,24 @@ namespace Vtk {
|
||||
* directly into the Qt application (no separate VTK window).
|
||||
* Puppets and actors are added to the embedded renderer.
|
||||
*/
|
||||
class QViewport : public QWidget {
|
||||
class QViewport : public QWidget, public Viewport {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit QViewport(QWidget* parent = nullptr);
|
||||
virtual ~QViewport();
|
||||
|
||||
// Render scene
|
||||
void Render();
|
||||
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);
|
||||
virtual void Render() override;
|
||||
|
||||
// Direct access to VTK internals
|
||||
vtkRenderer* GetRenderer() { return m_Renderer; }
|
||||
vtkRenderWindow* GetRenderWindow();
|
||||
vtkRenderWindowInteractor* GetInteractor();
|
||||
vtkCornerAnnotation* GetAnnotation() { return m_Annotation; }
|
||||
vtkCameraOrientationWidget* GetCameraWidget(){ return m_CameraWidget; }
|
||||
virtual vtkRenderWindow* GetRenderWindow() override;
|
||||
virtual vtkRenderWindowInteractor* GetInteractor() override;
|
||||
QVTKOpenGLNativeWidget* GetWidget() { return m_VtkWidget; }
|
||||
|
||||
private:
|
||||
void SetupPipeline();
|
||||
|
||||
QVTKOpenGLNativeWidget* m_VtkWidget;
|
||||
vtkRenderer* m_Renderer;
|
||||
vtkCornerAnnotation* m_Annotation;
|
||||
vtkOrientationMarkerWidget* m_Marker;
|
||||
vtkCameraOrientationWidget* m_CameraWidget;
|
||||
};
|
||||
|
||||
} // 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