|
|
#include "PreWindowInitializer.h"
|
|
|
|
|
|
// VTK
|
|
|
#include <vtkCallbackCommand.h>
|
|
|
#include <vtkInteractorObserver.h>
|
|
|
#include <vtkCamera.h>
|
|
|
#include <vtkRenderWindow.h>
|
|
|
#include <vtkRenderer.h>
|
|
|
#include <vtkPointPicker.h>
|
|
|
#include <vtkCellPicker.h>
|
|
|
#include <vtkAreaPicker.h>
|
|
|
#include <vtkPlanes.h>
|
|
|
#include <vtkProp3DCollection.h>
|
|
|
#include <vtkPropPicker.h>
|
|
|
#include <vtkRenderWindowInteractor.h>
|
|
|
|
|
|
#include "FITK_Component/FITKRenderWindowVTK/FITKGraphAreaPicker.h"
|
|
|
#include "FITK_Kernel/FITKAppFramework/FITKKeyMouseStates.h"
|
|
|
|
|
|
// App
|
|
|
#include "FITK_Kernel/FITKAppFramework/FITKAppFramework.h"
|
|
|
#include "FITK_Kernel/FITKAppFramework/FITKGlobalData.h"
|
|
|
#include "FITK_Kernel/FITKAppFramework/FITKComponents.h"
|
|
|
#include "FITK_Kernel/FITKAppFramework/FITKComponentInterface.h"
|
|
|
|
|
|
// Operator
|
|
|
#include "FITK_Kernel/FITKCore/FITKOperatorRepo.h"
|
|
|
#include "OperatorsInterface/GraphInteractionOperator.h"
|
|
|
#include "OperatorsInterface/GraphEventOperator.h"
|
|
|
|
|
|
// Render
|
|
|
#include "FITK_Component/FITKRenderWindowVTK/FITKGraph3DWindowVTK.h"
|
|
|
#include "FITK_Component/FITKRenderWindowVTK/FITKGraphRender.h"
|
|
|
|
|
|
// GUI
|
|
|
#include "GUIFrame/MainWindow.h"
|
|
|
#include "GUIFrame/RenderWidget.h"
|
|
|
#include "FITK_Component/FITKWidget/FITKMdiArea.h"
|
|
|
#include "GUIWidget/GUIPickInfo.h"
|
|
|
|
|
|
PreWindowInitializer::PreWindowInitializer()
|
|
|
{
|
|
|
// 初始化渲染层数。
|
|
|
this->setLayerCount(3);
|
|
|
|
|
|
//背景颜色
|
|
|
//QColor top = QColor::fromRgb(27, 45, 70);
|
|
|
//QColor buttom = QColor::fromRgb(160, 174, 195);
|
|
|
//this->setValue(BackGroundColorTop, top);
|
|
|
//this->setValue(BackGroundColorButtom, buttom);
|
|
|
}
|
|
|
|
|
|
Comp::FITKGraphInteractionStyle* PreWindowInitializer::getStyle()
|
|
|
{
|
|
|
return PreWindowInteractionStyle::New();
|
|
|
}
|
|
|
|
|
|
PreWindowInteractionStyle* PreWindowInteractionStyle::New()
|
|
|
{
|
|
|
return new PreWindowInteractionStyle;
|
|
|
}
|
|
|
|
|
|
PreWindowInteractionStyle::PreWindowInteractionStyle()
|
|
|
{
|
|
|
// 初始化定时器属性。
|
|
|
m_timerForPrePick.setInterval(200);
|
|
|
m_timerForPrePick.setSingleShot(true);
|
|
|
|
|
|
connect(&m_timerForPrePick, &QTimer::timeout, this, &PreWindowInteractionStyle::slot_prePick);
|
|
|
|
|
|
// 初始化操作器。
|
|
|
//@{
|
|
|
auto operatorRepo = Core::FITKOperatorRepo::getInstance();
|
|
|
m_operPreview = operatorRepo->getOperatorT<EventOper::GraphInteractionOperator>("GraphPickPreview");
|
|
|
m_operPick = operatorRepo->getOperatorT<EventOper::GraphInteractionOperator>("GraphPick");
|
|
|
m_operGraph = operatorRepo->getOperatorT<EventOper::GraphEventOperator>("GraphPreprocess");
|
|
|
//@}
|
|
|
}
|
|
|
|
|
|
void PreWindowInteractionStyle::OnLeftButtonDown()
|
|
|
{
|
|
|
// TEST.
|
|
|
//@{
|
|
|
//GUI::GUIPickInfoStru info = GUI::GUIPickInfo::GetPickInfo();
|
|
|
//info._pickObjType = GUI::GUIPickInfo::PickObjType::POBJVert;
|
|
|
//info._pickMethod = GUI::GUIPickInfo::PickMethod::PMSingle;
|
|
|
//GUI::GUIPickInfo::SetPickInfo(info);
|
|
|
//@}
|
|
|
|
|
|
// TEST2.
|
|
|
//@{
|
|
|
// GUI::MainTreeEnum::MainTree_MeshPoint = 9
|
|
|
//GraphOperParam param;
|
|
|
//param.HighlightMode = HighlightLevel::AdvHighlight;
|
|
|
//param.AdvHighlightIndice = QVector<int>{ 1 };
|
|
|
//param.Visibility = true;
|
|
|
//m_operGraph->updateGraphByType(9, param);
|
|
|
//@}
|
|
|
|
|
|
this->Interactor->GetEventPosition(m_leftButtonDowmPos);
|
|
|
|
|
|
if (m_areaPick != nullptr)
|
|
|
{
|
|
|
m_areaPick->setLeftButtonDownPos(m_leftButtonDowmPos);
|
|
|
m_areaPick->enable(true);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void PreWindowInteractionStyle::OnLeftButtonUp()
|
|
|
{
|
|
|
vtkInteractorStyleRubberBandPick::OnLeftButtonUp();
|
|
|
this->Interactor->GetEventPosition(m_leftButtonUpPos);
|
|
|
|
|
|
// 只有在逐个选择模式下支持框选。
|
|
|
bool canAreaPick = GUI::GUIPickInfo::GetPickInfo()._pickMethod == GUI::GUIPickInfo::PickMethod::PMIndividually;
|
|
|
|
|
|
if (m_areaPick != nullptr && isMouseMoved())
|
|
|
{
|
|
|
if (m_areaPick->isEnable() && canAreaPick)
|
|
|
m_areaPick->pick();
|
|
|
m_areaPick->enable(false);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
pick();
|
|
|
}
|
|
|
|
|
|
AppFrame::FITKComponentInterface* fcInterface
|
|
|
= FITKAPP->getComponents()->getComponentByName("Graph3DWindowVTK");
|
|
|
if (fcInterface)
|
|
|
{
|
|
|
CallBackFuns fun = fcInterface->getCallBackFuns(1);
|
|
|
if (fun != nullptr)
|
|
|
fun(nullptr);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void PreWindowInteractionStyle::OnMiddleButtonDown()
|
|
|
{
|
|
|
this->Interactor->GetEventPosition(m_leftButtonDowmPos);
|
|
|
|
|
|
if (FITKAPP->getGlobalData()->getKeyMouseStates()->keyPressed(Qt::Key_Shift))
|
|
|
vtkInteractorStyleRubberBandPick::OnMiddleButtonDown();
|
|
|
else
|
|
|
vtkInteractorStyleRubberBandPick::OnLeftButtonDown();
|
|
|
}
|
|
|
|
|
|
void PreWindowInteractionStyle::OnMiddleButtonUp()
|
|
|
{
|
|
|
this->Interactor->GetEventPosition(m_leftButtonDowmPos);
|
|
|
|
|
|
vtkInteractorStyleRubberBandPick::OnLeftButtonUp();
|
|
|
vtkInteractorStyleRubberBandPick::OnMiddleButtonUp();
|
|
|
if (m_areaPick != nullptr)
|
|
|
{
|
|
|
m_areaPick->enable(false);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void PreWindowInteractionStyle::OnMouseMove()
|
|
|
{
|
|
|
if (m_timerForPrePick.isActive())
|
|
|
{
|
|
|
m_timerForPrePick.stop();
|
|
|
}
|
|
|
|
|
|
m_timerForPrePick.start();
|
|
|
|
|
|
this->Interactor->GetEventPosition(m_leftButtonUpPos);
|
|
|
|
|
|
vtkInteractorStyleRubberBandPick::OnMouseMove();
|
|
|
bool isMoved = this->isMouseMoved();
|
|
|
const bool lbd = FITKAPP->getGlobalData()->getKeyMouseStates()->mousePressed(Qt::LeftButton);
|
|
|
|
|
|
// 非单独拾取,且非算法拾取或非拾取状态时可绘制橡皮筋。
|
|
|
bool needDrawRect = (GUI::GUIPickInfo::GetPickInfo()._pickMethod == GUI::GUIPickInfo::PickMethod::PMIndividually ||
|
|
|
GUI::GUIPickInfo::GetPickInfo()._pickMethod == GUI::GUIPickInfo::PickMethod::PMNone);
|
|
|
|
|
|
if (lbd && isMoved && needDrawRect)
|
|
|
{
|
|
|
m_areaPick->drawRectangle();
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void PreWindowInteractionStyle::OnMouseWheelForward()
|
|
|
{
|
|
|
this->FindPokedRenderer(
|
|
|
this->Interactor->GetEventPosition()[0], this->Interactor->GetEventPosition()[1]);
|
|
|
if (this->CurrentRenderer == nullptr)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
this->GrabFocus(this->EventCallbackCommand);
|
|
|
this->StartDolly();
|
|
|
// double factor = this->MotionFactor * -0.2 * this->MouseWheelMotionFactor;
|
|
|
this->Dolly(0.98); // pow(1.1, factor)
|
|
|
this->EndDolly();
|
|
|
this->ReleaseFocus();
|
|
|
}
|
|
|
|
|
|
void PreWindowInteractionStyle::OnMouseWheelBackward()
|
|
|
{
|
|
|
this->FindPokedRenderer(
|
|
|
this->Interactor->GetEventPosition()[0], this->Interactor->GetEventPosition()[1]);
|
|
|
if (this->CurrentRenderer == nullptr)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
this->GrabFocus(this->EventCallbackCommand);
|
|
|
this->StartDolly();
|
|
|
// double factor = this->MotionFactor * 0.2 * this->MouseWheelMotionFactor;
|
|
|
this->Dolly(1.05); // pow(1.1, factor)
|
|
|
this->EndDolly();
|
|
|
this->ReleaseFocus();
|
|
|
}
|
|
|
|
|
|
void PreWindowInteractionStyle::OnRightButtonDown()
|
|
|
{
|
|
|
this->Interactor->GetEventPosition(m_leftButtonDowmPos);
|
|
|
}
|
|
|
|
|
|
void PreWindowInteractionStyle::OnRightButtonUp()
|
|
|
{
|
|
|
this->Interactor->GetEventPosition(m_leftButtonUpPos);
|
|
|
}
|
|
|
|
|
|
void PreWindowInteractionStyle::areaPick(int* startPos, int* endPos)
|
|
|
{
|
|
|
// 获取当前三维窗口。
|
|
|
Comp::FITKGraph3DWindowVTK* graphWindow = getCurrentGraphWindow();
|
|
|
if (!graphWindow || !m_operPick)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// 所有渲染层均执行一次框选并获取拾取演员。
|
|
|
//@{
|
|
|
QList<vtkActor*> actors;
|
|
|
vtkSmartPointer<vtkAreaPicker> areaPicker = vtkSmartPointer<vtkAreaPicker>::New();
|
|
|
|
|
|
for (int i = 0; i < graphWindow->getRenderCount(); i++)
|
|
|
{
|
|
|
vtkRenderer* renderer = graphWindow->getRenderer(i)->getRenderer();
|
|
|
areaPicker->AreaPick(startPos[0], startPos[1], endPos[0], endPos[1], renderer);
|
|
|
vtkProp3DCollection* props = areaPicker->GetProp3Ds();
|
|
|
props->InitTraversal();
|
|
|
|
|
|
const int nActors = props->GetNumberOfItems();
|
|
|
for (vtkIdType i = 0; i < nActors; i++)
|
|
|
{
|
|
|
vtkProp3D* prop = props->GetNextProp3D();
|
|
|
vtkActor* actor = vtkActor::SafeDownCast(prop);
|
|
|
if (actor)
|
|
|
{
|
|
|
actors.append(actor);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
//@}
|
|
|
|
|
|
// 没有拾取到,且不是Shift与Ctrl拾取模式则清除拾取。
|
|
|
AppFrame::FITKKeyMouseStates* settings = FITKGLODATA->getKeyMouseStates();
|
|
|
bool shiftOrCtrlPick = (settings->keyPressed(Qt::Key_Shift) && !settings->keyPressed(Qt::Key_Control))
|
|
|
|| (!settings->keyPressed(Qt::Key_Shift) && settings->keyPressed(Qt::Key_Control));
|
|
|
if (actors.isEmpty() && !shiftOrCtrlPick)
|
|
|
{
|
|
|
m_operPick->clear(graphWindow);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
vtkPlanes* cutPlane = areaPicker->GetFrustum();
|
|
|
|
|
|
// 操作器执行高亮。
|
|
|
m_operPick->picked(graphWindow, actors, cutPlane);
|
|
|
}
|
|
|
|
|
|
void PreWindowInteractionStyle::pick(bool isPreview)
|
|
|
{
|
|
|
if (!m_operPreview || !m_operPick)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// 获取当前鼠标位置进行拾取。
|
|
|
vtkRenderWindowInteractor* interactor = this->GetInteractor();
|
|
|
if (!interactor)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
Comp::FITKGraph3DWindowVTK* graphWindow = getCurrentGraphWindow();
|
|
|
if (!graphWindow)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
int* pos = interactor->GetEventPosition();
|
|
|
|
|
|
// 获取当前拾取类型。
|
|
|
GUI::GUIPickInfo::PickObjType type = GUI::GUIPickInfo::GetPickInfo()._pickObjType;
|
|
|
switch (type)
|
|
|
{
|
|
|
case GUI::GUIPickInfo::POBJVert:
|
|
|
pickPoint(graphWindow, pos, isPreview);
|
|
|
break;
|
|
|
case GUI::GUIPickInfo::POBJEdge:
|
|
|
case GUI::GUIPickInfo::POBJFace:
|
|
|
case GUI::GUIPickInfo::POBJSolid:
|
|
|
pickCell(graphWindow, pos, isPreview);
|
|
|
break;
|
|
|
default:
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void PreWindowInteractionStyle::pickPoint(Comp::FITKGraph3DWindowVTK* graphWindow, int* pos, bool isPreview, double tol)
|
|
|
{
|
|
|
// 节点拾取器。
|
|
|
//vtkSmartPointer<vtkCellPicker> picker = vtkSmartPointer<vtkCellPicker>::New();
|
|
|
//vtkSmartPointer<vtkPropPicker> pickerProp = vtkSmartPointer<vtkPropPicker>::New();
|
|
|
|
|
|
vtkPointPicker* picker = vtkPointPicker::New();
|
|
|
|
|
|
picker->SetTolerance(tol);
|
|
|
|
|
|
// 优先拾取最后一层,反向遍历。
|
|
|
for (int i = graphWindow->getRenderCount() - 1; i >= 0; i--)
|
|
|
{
|
|
|
vtkRenderer* renderer = graphWindow->getRenderer(i)->getRenderer();
|
|
|
|
|
|
int ret = picker->Pick(pos[0], pos[1], 0, renderer);
|
|
|
|
|
|
// 是否拾取到对象。
|
|
|
if (!ret)
|
|
|
{
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
// 获取拾取节点索引。
|
|
|
vtkActor* actor = picker->GetActor();
|
|
|
int index = picker->GetPointId();
|
|
|
if (index < 0)
|
|
|
{
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
double* pickedWorldPos = picker->GetPickPosition();
|
|
|
|
|
|
if (isPreview)
|
|
|
{
|
|
|
m_operPreview->picked(graphWindow, actor, index, pickedWorldPos);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
m_operPick->picked(graphWindow, actor, index, pickedWorldPos);
|
|
|
}
|
|
|
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// 没有拾取到则清除拾取。
|
|
|
if (isPreview)
|
|
|
{
|
|
|
m_operPreview->clear(graphWindow);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
// 没有拾取到,且不是Shift与Ctrl拾取模式则清除拾取。
|
|
|
AppFrame::FITKKeyMouseStates* settings = FITKGLODATA->getKeyMouseStates();
|
|
|
bool shiftOrCtrlPick = (settings->keyPressed(Qt::Key_Shift) && !settings->keyPressed(Qt::Key_Control))
|
|
|
|| (!settings->keyPressed(Qt::Key_Shift) && settings->keyPressed(Qt::Key_Control));
|
|
|
if (!shiftOrCtrlPick)
|
|
|
{
|
|
|
m_operPick->clear(graphWindow);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void PreWindowInteractionStyle::pickCell(Comp::FITKGraph3DWindowVTK* graphWindow, int* pos, bool isPreview, double tol)
|
|
|
{
|
|
|
// 单元拾取器。
|
|
|
vtkSmartPointer<vtkCellPicker> picker = vtkSmartPointer<vtkCellPicker>::New();
|
|
|
|
|
|
picker->SetTolerance(tol);
|
|
|
|
|
|
// 优先拾取最后一层,反向遍历。
|
|
|
for (int i = graphWindow->getRenderCount() - 1; i >= 0 ; i--)
|
|
|
{
|
|
|
vtkRenderer* renderer = graphWindow->getRenderer(i)->getRenderer();
|
|
|
|
|
|
// 优先进行参考点标签与符号拾取。
|
|
|
int ret = picker->Pick(pos[0], pos[1], 0, renderer);
|
|
|
|
|
|
// 是否拾取到对象。
|
|
|
if (!ret)
|
|
|
{
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
// 获取拾取单元索引。
|
|
|
vtkActor* actor = picker->GetActor();
|
|
|
int index = picker->GetCellId();
|
|
|
if (index < 0)
|
|
|
{
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
double* pickedWorldPos = picker->GetPickPosition();
|
|
|
|
|
|
if (isPreview)
|
|
|
{
|
|
|
m_operPreview->picked(graphWindow, actor, index, pickedWorldPos);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
m_operPick->picked(graphWindow, actor, index, pickedWorldPos);
|
|
|
}
|
|
|
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// 没有拾取到则清除拾取。
|
|
|
if (isPreview)
|
|
|
{
|
|
|
m_operPreview->clear(graphWindow);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
// 没有拾取到,且不是Shift与Ctrl拾取模式则清除拾取。
|
|
|
AppFrame::FITKKeyMouseStates* settings = FITKGLODATA->getKeyMouseStates();
|
|
|
bool shiftOrCtrlPick = (settings->keyPressed(Qt::Key_Shift) && !settings->keyPressed(Qt::Key_Control))
|
|
|
|| (!settings->keyPressed(Qt::Key_Shift) && settings->keyPressed(Qt::Key_Control));
|
|
|
if (!shiftOrCtrlPick)
|
|
|
{
|
|
|
m_operPick->clear(graphWindow);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void PreWindowInteractionStyle::slot_prePick()
|
|
|
{
|
|
|
// 预选高亮。
|
|
|
pick(true);
|
|
|
}
|
|
|
|
|
|
Comp::FITKGraph3DWindowVTK* PreWindowInteractionStyle::getCurrentGraphWindow()
|
|
|
{
|
|
|
GUI::MainWindow* mainWindow = FITKAPP->getGlobalData()->getMainWindowT<GUI::MainWindow>();
|
|
|
if (mainWindow == nullptr) return nullptr;
|
|
|
|
|
|
// 获取可视化区。
|
|
|
GUI::RenderWidget* renderWidget = mainWindow->getRenderWidget();
|
|
|
if (!renderWidget)
|
|
|
{
|
|
|
return nullptr;
|
|
|
}
|
|
|
|
|
|
Comp::FITKMdiArea* mdiArea = renderWidget->getMdiArea();
|
|
|
if (!mdiArea)
|
|
|
{
|
|
|
return nullptr;
|
|
|
}
|
|
|
|
|
|
// 获取当前窗口,尝试转换为三维窗口。
|
|
|
QWidget* w = mdiArea->getCurrentWidget();
|
|
|
Comp::FITKGraph3DWindowVTK* graphWindow = dynamic_cast<Comp::FITKGraph3DWindowVTK*>(w);
|
|
|
return graphWindow;
|
|
|
} |