#include "thQVTKOpenGLNativeWidget.h"
#include <QApplication>
#include <QDesktopWidget>
#include <QOpenGLContext>
#include <QOpenGLFramebufferObject>
#include <QOpenGLFunctions>
#include <QOpenGLFunctions_3_2_Core>
#include <QOpenGLTexture>
#include <QPointer>
#include <QScopedValueRollback>
#include <QtDebug>
#include "vtkAxesActor.h"
#include "vtkProperty.h"
#include "vtkProperty2D.h"
#include "vtkTextProperty.h"
#include "vtkCaptionActor2D.h"
#include <vtkRendererCollection.h>
#include <vtkRenderer.h>
#include "vtkAnnotatedCubeActor.h"
#include "vtkMapper.h"
#include "vtkPropAssembly.h"
#include "vtkPlaneSource.h"
#include "vtkTransform.h"
#include "vtkPolyDataMapper.h"
#include "vtkCamera.h"
#include "QVTKInteractor.h"
#include "QVTKInteractorAdapter.h"
#include "QVTKRenderWindowAdapter.h"
#include "vtkCommand.h"
#include "vtkGenericOpenGLRenderWindow.h"
#include "vtkNew.h"
#include "vtkObjectFactory.h"
#include "vtkOpenGLState.h"
#include "thinteractorstyletrackballcamera.h"
//-----------------------------------------------------------------------------
thQVTKOpenGLNativeWidget::thQVTKOpenGLNativeWidget(QWidget* parentWdg, Qt::WindowFlags f)
: thQVTKOpenGLNativeWidget(
vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New().GetPointer(), parentWdg, f)
{
}
//-----------------------------------------------------------------------------
thQVTKOpenGLNativeWidget::thQVTKOpenGLNativeWidget(
vtkGenericOpenGLRenderWindow* renderWin, QWidget* parentWdg, Qt::WindowFlags f)
: Superclass(parentWdg, f)
, RenderWindow(nullptr)
, m_axesWidget(nullptr)
, RenderWindowAdapter(nullptr)
, EnableHiDPI(true)
, UnscaledDPI(72)
, DefaultCursor(QCursor(Qt::ArrowCursor))
{
// default to strong focus
this->setFocusPolicy(Qt::StrongFocus);
this->setUpdateBehavior(QOpenGLWidget::NoPartialUpdate);
this->setMouseTracking(true);
// we use `QOpenGLWidget::resized` instead of `resizeEvent` or `resizeGL` as
// an indicator to resize our internal buffer size. This is done, since in
// addition to widget resize, `resized` gets fired when screen is changed
// which causes devicePixelRatio changes.
this->connect(this, SIGNAL(resized()), SLOT(updateSize()));
this->setRenderWindow(renderWin);
m_viewType = zxViewerType::TOP;
this->setViewerType(zxViewerType::ISO);
// enable qt gesture events
this->grabGesture(Qt::PinchGesture);
this->grabGesture(Qt::PanGesture);
this->grabGesture(Qt::TapGesture);
this->grabGesture(Qt::TapAndHoldGesture);
this->grabGesture(Qt::SwipeGesture);
}
//-----------------------------------------------------------------------------
thQVTKOpenGLNativeWidget::~thQVTKOpenGLNativeWidget()
{
this->makeCurrent();
this->cleanupContext();
if (m_axesWidget != NULL)
{
m_axesWidget->Off();
m_axesWidget->Delete();
m_axesWidget = NULL;
}
}
//-----------------------------------------------------------------------------
void thQVTKOpenGLNativeWidget::setRenderWindow(vtkRenderWindow* win)
{
auto gwin = vtkGenericOpenGLRenderWindow::SafeDownCast(win);
if (win != nullptr && gwin == nullptr)
{
qDebug() << "QVTKOpenGLNativeWidget requires a `vtkGenericOpenGLRenderWindow`. `"
<< win->GetClassName() << "` is not supported.";
}
this->setRenderWindow(gwin);
}
//-----------------------------------------------------------------------------
void thQVTKOpenGLNativeWidget::setRenderWindow(vtkGenericOpenGLRenderWindow* win)
{
if (this->RenderWindow == win)
{
return;
}
// this will release all OpenGL resources associated with the old render
// window, if any.
if (this->RenderWindowAdapter)
{
this->makeCurrent();
this->RenderWindowAdapter.reset(nullptr);
}
this->RenderWindow = win;
if (this->RenderWindow)
{
this->RenderWindow->SetReadyForRendering(false);
// if an interactor wasn't provided, we'll make one by default
if (!this->RenderWindow->GetInteractor())
{
// create a default interactor
vtkNew<QVTKInteractor> iren;
// iren->SetUseTDx(this->UseTDx);
this->RenderWindow->SetInteractor(iren);
iren->Initialize();
// now set the default style
vtkNew<thInteractorStyleTrackballCamera> style;
iren->SetInteractorStyle(style);
setAxesSystem(iren);
setReferenceAxesSystem();
}
if (this->isValid())
{
// this typically means that the render window is being changed after the
// QVTKOpenGLNativeWidget has initialized itself in a previous update
// pass, so we emulate the steps to ensure that the new vtkRenderWindow is
// brought to the same state (minus the actual render).
this->makeCurrent();
this->initializeGL();
this->updateSize();
}
}
}
//-----------------------------------------------------------------------------
vtkRenderWindow* thQVTKOpenGLNativeWidget::renderWindow() const
{
return this->RenderWindow;
}
//-----------------------------------------------------------------------------
QVTKInteractor* thQVTKOpenGLNativeWidget::interactor() const
{
return this->RenderWindow ? QVTKInteractor::SafeDownCast(this->RenderWindow->GetInteractor())
: nullptr;
}
//-----------------------------------------------------------------------------
QSurfaceFormat thQVTKOpenGLNativeWidget::defaultFormat(bool stereo_capable)
{
return QVTKRenderWindowAdapter::defaultFormat(stereo_capable);
}
//-----------------------------------------------------------------------------
void thQVTKOpenGLNativeWidget::setEnableHiDPI(bool enable)
{
this->EnableHiDPI = enable;
if (this->RenderWindowAdapter)
{
this->RenderWindowAdapter->setEnableHiDPI(enable);
}
}
//-----------------------------------------------------------------------------
void thQVTKOpenGLNativeWidget::setUnscaledDPI(int dpi)
{
this->UnscaledDPI = dpi;
if (this->RenderWindowAdapter)
{
this->RenderWindowAdapter->setUnscaledDPI(dpi);
}
}
//-----------------------------------------------------------------------------
void thQVTKOpenGLNativeWidget::setDefaultCursor(const QCursor& cursor)
{
this->DefaultCursor = cursor;
if (this->RenderWindowAdapter)
{
this->RenderWindowAdapter->setDefaultCursor(cursor);
}
}
void thQVTKOpenGLNativeWidget::setAxesSystem(vtkRenderWindowInteractor* iren)
{
if (!iren)
{
return;
}
if (this->RenderWindow->GetRenderers()->GetNumberOfItems() == 0) {
this->RenderWindow->AddRenderer(vtkRenderer::New());
//m_window->interactor()->Enable();
}
if (m_axesWidget == nullptr)
{
m_axesWidget = vtkOrientationMarkerWidget::New();
vtkSmartPointer<vtkAnnotatedCubeActor> cube = vtkSmartPointer<vtkAnnotatedCubeActor>::New();
cube->SetFaceTextScale(0.65);
cube->GetCubeProperty()->SetColor(0.9, 0.9, 0.9);
cube->GetTextEdgesProperty()->SetLineWidth(1);
cube->GetTextEdgesProperty()->SetDiffuse(0);
cube->GetTextEdgesProperty()->SetAmbient(1);
cube->GetTextEdgesProperty()->SetColor(0.2400, 0.2400, 0.2400);
vtkMapper::SetResolveCoincidentTopologyToPolygonOffset();
cube->SetXPlusFaceText("L");//左到右
cube->SetXMinusFaceText("R");
cube->SetYPlusFaceText("P");//前到后
cube->SetYMinusFaceText("A");
cube->SetZPlusFaceText("S");//下到上
cube->SetZMinusFaceText("I");
cube->GetXPlus