38 #include <vtkCellData.h>
39 #include <vtkCellType.h>
40 #include <vtkCommand.h>
41 #include <vtkDataArray.h>
42 #include <vtkFieldData.h>
43 #include <vtkHardwareSelector.h>
44 #include <vtkIdTypeArray.h>
45 #include <vtkIntArray.h>
46 #include <vtkInteractorStyle.h>
47 #include <vtkInteractorStyleDrawPolygon.h>
48 #include <vtkInteractorStyleRubberBand3D.h>
49 #include <vtkInteractorStyleRubberBandPick.h>
50 #include <vtkInteractorStyleRubberBandZoom.h>
51 #include <vtkInteractorStyleTrackballCamera.h>
52 #include <vtkPointData.h>
53 #include <vtkPolyData.h>
54 #include <vtkRenderWindow.h>
55 #include <vtkRenderWindowInteractor.h>
56 #include <vtkRenderer.h>
57 #include <vtkStringArray.h>
58 #include <vtkVector.h>
61 #include <QActionGroup>
62 #include <QApplication>
64 #include <QKeySequence>
65 #include <QMainWindow>
66 #include <QMessageBox>
79 QPointer<cvRenderViewSelectionReaction>
80 cvRenderViewSelectionReaction::ActiveReaction;
87 QAction* parentAction,
SelectionMode mode, QActionGroup* modifierGroup)
88 : QObject(parentAction),
89 m_parentAction(parentAction),
90 m_modifierGroup(modifierGroup),
92 m_zoomCursor(QCursor(QPixmap((const char**)zoom_xpm))),
93 m_mouseMovingTimer(this) {
95 for (
size_t i = 0; i <
sizeof(m_observerIds) /
sizeof(m_observerIds[0]);
135 m_mouseMovingTimer.setSingleShot(
true);
136 connect(&m_mouseMovingTimer, &QTimer::timeout,
this,
145 QWidget* parentWidget =
nullptr;
147 for (QWidget* widget : QApplication::topLevelWidgets()) {
148 if (widget->isWindow() && widget->isVisible() &&
149 qobject_cast<QMainWindow*>(widget)) {
150 parentWidget = widget;
156 for (QWidget* widget : QApplication::topLevelWidgets()) {
157 if (widget->isWindow() && qobject_cast<QMainWindow*>(widget)) {
158 parentWidget = widget;
164 m_copyTooltipShortcut =
new QShortcut(parentWidget);
165 connect(m_copyTooltipShortcut, &QShortcut::activated,
this, [
this]() {
166 if (!m_plainTooltipText.isEmpty()) {
167 QApplication::clipboard()->setText(m_plainTooltipText);
170 m_copyTooltipShortcut->setEnabled(
false);
183 if (m_copyTooltipShortcut) {
184 delete m_copyTooltipShortcut;
185 m_copyTooltipShortcut =
nullptr;
195 if (m_viewer == viewer) {
205 m_interactor =
nullptr;
206 m_renderer =
nullptr;
222 return ActiveReaction ==
this;
227 if (ActiveReaction) {
228 ActiveReaction->endSelection();
237 vtkObject* caller,
unsigned long eventId,
void* callData) {
267 unsigned long eventId,
328 QAction* actn = m_parentAction;
333 if (actn->isCheckable()) {
353 if (!m_parentAction) {
381 m_parentAction->setEnabled(m_viewer !=
nullptr);
390 m_parentAction->setEnabled(
true);
395 m_parentAction->setEnabled(m_viewer !=
nullptr);
414 if (requiresViewer && (!m_viewer || !m_interactor)) {
416 "[cvRenderViewSelectionReaction::beginSelection] No viewer or "
423 if (ActiveReaction ==
this) {
429 if (ActiveReaction) {
430 if (!ActiveReaction->isCompatible(m_mode)) {
434 ActiveReaction->endSelection();
439 ActiveReaction =
this;
445 m_previousRenderViewMode = 0;
489 if (pclVis->isPointPickingEnabled()) {
490 pclVis->setPointPickingEnabled(
false);
496 pipeline->enterSelectionMode();
512 if (m_parentAction) {
513 m_parentAction->setChecked(
true);
528 if (ActiveReaction !=
this || m_previousRenderViewMode == -1) {
534 ActiveReaction =
nullptr;
535 m_previousRenderViewMode = -1;
539 m_mouseMovingTimer.stop();
540 m_mouseMoving =
false;
544 m_currentPolyData =
nullptr;
548 if (m_copyTooltipShortcut) {
549 m_copyTooltipShortcut->setKey(QKeySequence());
550 m_copyTooltipShortcut->setEnabled(
false);
558 QTimer::singleShot(0,
this, [
this]() {
561 bool newModeActive = (ActiveReaction !=
nullptr);
602 if (m_parentAction && m_parentAction->isCheckable() &&
603 m_parentAction->isChecked()) {
604 m_parentAction->blockSignals(
true);
605 m_parentAction->setChecked(
false);
606 m_parentAction->blockSignals(
false);
610 QString(
"[cvRenderViewSelectionReaction] Selection mode %1 ended")
611 .arg(
static_cast<int>(m_mode)));
618 m_mouseMoving =
false;
626 if (ActiveReaction ==
this) {
639 unsigned long eventId,
644 if (ActiveReaction !=
this) {
663 vtkInteractorStyleDrawPolygon* polygonStyle =
664 vtkInteractorStyleDrawPolygon::SafeDownCast(m_selectionStyle);
667 "[cvRenderViewSelectionReaction] Polygon mode but style is "
668 "not vtkInteractorStyleDrawPolygon");
672 vtkInteractorObserver* currentStyle =
673 m_interactor->GetInteractorStyle();
674 polygonStyle = vtkInteractorStyleDrawPolygon::SafeDownCast(
684 std::vector<vtkVector2i>
points = polygonStyle->GetPolygonPoints();
689 "vertices (%1), ignoring")
697 polygonPointsArray->SetNumberOfComponents(2);
698 polygonPointsArray->SetNumberOfTuples(
699 static_cast<vtkIdType
>(
points.size()));
700 for (
unsigned int j = 0; j <
points.size(); ++j) {
701 const vtkVector2i& v =
points[j];
702 int pos[2] = {v[0], v[1]};
703 polygonPointsArray->SetTypedTuple(j, pos);
731 "[cvRenderViewSelectionReaction] selectionChanged: callData is "
736 int* region =
reinterpret_cast<int*
>(callData);
793 if (m_disablePreSelection) {
800 m_mouseMovingTimer.start(TOOLTIP_WAITING_TIME);
801 m_mouseMoving =
true;
822 "[cvRenderViewSelectionReaction] Invalid call to "
831 if (ActiveReaction !=
this) {
841 int* pos = m_interactor->GetEventPosition();
843 m_zoomStartPosition[0] = pos[0];
844 m_zoomStartPosition[1] = pos[1];
845 m_zoomTracking =
true;
855 if (ActiveReaction !=
this) {
863 int x = m_interactor->GetEventPosition()[0];
864 int y = m_interactor->GetEventPosition()[1];
866 if (
x < 0 ||
y < 0) {
872 if (m_zoomTracking) {
876 int xmin = std::min(m_zoomStartPosition[0],
x);
877 int ymin = std::min(m_zoomStartPosition[1],
y);
878 int xmax = std::max(m_zoomStartPosition[0],
x);
879 int ymax = std::max(m_zoomStartPosition[1],
y);
882 m_zoomTracking =
false;
893 if (selectionModifier ==
899 int region[4] = {
x,
y,
x,
y};
914 "onLeftButtonRelease] "
915 "Mode %1 not handled in switch")
916 .arg(
static_cast<int>(m_mode)));
925 if (ActiveReaction ==
this) {
940 m_disablePreSelection =
true;
947 m_disablePreSelection =
false;
960 m_disablePreSelection =
true;
966 m_disablePreSelection =
false;
981 if (ActiveReaction !=
this || !m_interactor || !m_renderer) {
985 int x = m_interactor->GetEventPosition()[0];
986 int y = m_interactor->GetEventPosition()[1];
987 int*
size = m_interactor->GetSize();
989 m_mousePosition[0] =
x;
990 m_mousePosition[1] =
y;
993 if (
x < 0 || y < 0 || x >=
size[0] ||
y >=
size[1]) {
1019 if (highlighter && info.
polyData) {
1021 int fieldAssociation = selectCells ? 0 : 1;
1027 m_currentPolyData =
nullptr;
1038 vtkRenderWindow* renWin = m_interactor->GetRenderWindow();
1067 if (m_mouseMoving) {
1068 QToolTip::hideText();
1073 if (m_hoveredId < 0) {
1074 QToolTip::hideText();
1078 if (!m_currentPolyData) {
1079 QToolTip::hideText();
1084 QString tooltipText;
1091 auto formatArrayValue = [](vtkDataArray* arr, vtkIdType id) -> QString {
1092 if (!arr || !arr->GetName())
return QString();
1094 QString
name = QString::fromUtf8(arr->GetName());
1095 int numComp = arr->GetNumberOfComponents();
1099 name ==
"vtkOriginalPointIds" ||
name ==
"vtkOriginalCellIds") {
1107 double value = arr->GetTuple1(
id);
1108 return QString(
"\n %1: %2").arg(
name).arg(value, 0,
'g', 6);
1112 double* tuple = arr->GetTuple(
id);
1115 if ((numComp == 3 || numComp == 4) &&
1119 QString
result = QString(
"\n %1: (").arg(
name);
1120 for (
int i = 0; i < numComp; ++i) {
1121 if (i > 0)
result +=
", ";
1122 result += QString::number(
static_cast<int>(tuple[i]));
1130 QString
result = QString(
"\n %1: (").arg(
name);
1131 for (
int i = 0; i < numComp; ++i) {
1132 if (i > 0)
result +=
", ";
1133 result += QString::number(tuple[i],
'g', 6);
1140 QString datasetName;
1141 vtkFieldData* fieldData = m_currentPolyData->GetFieldData();
1143 vtkStringArray* nameArray = vtkStringArray::SafeDownCast(
1144 fieldData->GetAbstractArray(
"DatasetName"));
1145 if (nameArray && nameArray->GetNumberOfTuples() > 0) {
1146 datasetName = QString::fromStdString(nameArray->GetValue(0));
1151 vtkIdType numCells = m_currentPolyData->GetNumberOfCells();
1152 if (m_hoveredId >= 0 && m_hoveredId < numCells) {
1154 if (!datasetName.isEmpty()) {
1155 tooltipText = datasetName;
1156 tooltipText += QString(
"\n Id: %1").arg(m_hoveredId);
1158 tooltipText = QString(
"Cell ID: %1").arg(m_hoveredId);
1162 vtkCell* cell = m_currentPolyData->GetCell(m_hoveredId);
1165 switch (cell->GetCellType()) {
1167 cellType =
"Vertex";
1169 case VTK_POLY_VERTEX:
1170 cellType =
"Poly Vertex";
1176 cellType =
"Poly Line";
1179 cellType =
"Triangle";
1181 case VTK_TRIANGLE_STRIP:
1182 cellType =
"Triangle Strip";
1185 cellType =
"Polygon";
1193 case VTK_HEXAHEDRON:
1194 cellType =
"Hexahedron";
1197 cellType = QString(
"Type %1").arg(cell->GetCellType());
1200 tooltipText += QString(
"\n Type: %1").arg(cellType);
1203 vtkIdType npts = cell->GetNumberOfPoints();
1204 tooltipText += QString(
"\n Number of Points: %1").arg(npts);
1208 double center[3] = {0, 0, 0};
1209 for (vtkIdType i = 0; i < npts; ++i) {
1211 m_currentPolyData->GetPoint(cell->GetPointId(i), pt);
1219 tooltipText += QString(
"\n Center: (%1, %2, %3)")
1220 .arg(center[0], 0,
'g', 6)
1221 .arg(center[1], 0,
'g', 6)
1222 .arg(center[2], 0,
'g', 6);
1229 vtkCellData* cellData = m_currentPolyData->GetCellData();
1231 bool hasShownColorArray =
false;
1232 for (
int i = 0; i < cellData->GetNumberOfArrays(); ++i) {
1233 vtkDataArray* arr = cellData->GetArray(i);
1234 if (!arr || !arr->GetName())
continue;
1236 QString arrName = QString::fromUtf8(arr->GetName());
1237 int numComp = arr->GetNumberOfComponents();
1241 if ((numComp == 3 || numComp == 4) &&
1245 if (hasShownColorArray) {
1248 hasShownColorArray =
true;
1251 QString arrayText = formatArrayValue(arr, m_hoveredId);
1252 if (!arrayText.isEmpty()) {
1253 tooltipText += arrayText;
1259 vtkIdType numPoints = m_currentPolyData->GetNumberOfPoints();
1260 if (m_hoveredId >= 0 && m_hoveredId < numPoints) {
1262 m_currentPolyData->GetPoint(m_hoveredId, pt);
1265 if (!datasetName.isEmpty()) {
1266 tooltipText = datasetName;
1267 tooltipText += QString(
"\n Id: %1").arg(m_hoveredId);
1268 tooltipText += QString(
"\n Coords: (%1, %2, %3)")
1269 .arg(pt[0], 0,
'g', 6)
1270 .arg(pt[1], 0,
'g', 6)
1271 .arg(pt[2], 0,
'g', 6);
1273 tooltipText = QString(
"Point ID: %1\nPosition: (%2, %3, %4)")
1275 .arg(pt[0], 0,
'f', 6)
1276 .arg(pt[1], 0,
'f', 6)
1277 .arg(pt[2], 0,
'f', 6);
1283 vtkPointData* pointData = m_currentPolyData->GetPointData();
1285 bool hasShownColorArray =
false;
1286 for (
int i = 0; i < pointData->GetNumberOfArrays(); ++i) {
1287 vtkDataArray* arr = pointData->GetArray(i);
1288 if (!arr || !arr->GetName())
continue;
1290 QString arrName = QString::fromUtf8(arr->GetName());
1291 int numComp = arr->GetNumberOfComponents();
1295 if ((numComp == 3 || numComp == 4) &&
1299 if (hasShownColorArray) {
1302 hasShownColorArray =
true;
1305 QString arrayText = formatArrayValue(arr, m_hoveredId);
1306 if (!arrayText.isEmpty()) {
1307 tooltipText += arrayText;
1314 if (!tooltipText.isEmpty()) {
1320 qreal dpr = widget->devicePixelRatioF();
1324 QPoint localPos(
static_cast<int>(m_mousePosition[0] / dpr),
1326 static_cast<int>(m_mousePosition[1] / dpr));
1327 QPoint globalPos = widget->mapToGlobal(localPos);
1329 QToolTip::showText(globalPos, tooltipText);
1335 m_plainTooltipText = tooltipText;
1336 if (m_copyTooltipShortcut) {
1337 m_copyTooltipShortcut->setEnabled(
true);
1342 QToolTip::hideText();
1345 if (m_copyTooltipShortcut) {
1346 m_copyTooltipShortcut->setKey(QKeySequence());
1347 m_copyTooltipShortcut->setEnabled(
false);
1363 int selectionModifier =
1366 if (m_modifierGroup) {
1368 for (QAction* maction : m_modifierGroup->actions()) {
1369 if (maction && maction->isChecked() && maction->data().isValid()) {
1370 selectionModifier = maction->data().toInt();
1372 QString(
"[getSelectionModifier] From modifierGroup: "
1373 "action='%1', modifier=%2")
1374 .arg(maction->text())
1375 .arg(selectionModifier));
1383 bool ctrl = m_interactor->GetControlKey() == 1;
1384 bool shift = m_interactor->GetShiftKey() == 1;
1386 if (ctrl && shift) {
1398 return selectionModifier;
1406 if (m_mode == otherMode) {
1446 for (
size_t i = 0; i <
sizeof(m_observerIds) /
sizeof(m_observerIds[0]);
1448 if (m_observerIds[i] > 0 && m_observedObject) {
1449 m_observedObject->RemoveObserver(m_observerIds[i]);
1451 m_observerIds[i] = 0;
1455 if (m_styleObserverId > 0 && m_selectionStyle) {
1456 m_selectionStyle->RemoveObserver(m_styleObserverId);
1457 m_styleObserverId = 0;
1460 m_observedObject =
nullptr;
1465 if (m_modifierGroup) {
1466 QAction* checkedAction = m_modifierGroup->checkedAction();
1467 if (checkedAction) {
1468 checkedAction->setChecked(
false);
1478 int region[4],
int selectionModifier) {
1482 "[cvRenderViewSelectionReaction::selectCellsOnSurface] "
1483 "No pipeline available");
1508 int region[4],
int selectionModifier) {
1512 "[cvRenderViewSelectionReaction::selectPointsOnSurface] "
1513 "No pipeline available");
1538 int selectionModifier) {
1546 int selectionModifier) {
1558 int selectionModifier,
1559 const QString& description) {
1560 Q_UNUSED(description);
1574 currentSel, newSelection,
1576 selectionModifier));
1586 std::string viewID = pclVis->
getIdByActor(primaryActor);
1587 if (!viewID.empty()) {
1593 QString(
"[finalizeSelection] No source object "
1596 .arg(QString::fromStdString(viewID)));
1600 "[finalizeSelection] Could not find viewID for "
1612 if (highlighter && !combined.
isEmpty()) {
1615 }
else if (highlighter && combined.
isEmpty()) {
1625 int selectionModifier) {
1627 if (!pipeline || !
polygon)
return;
1646 int selectionModifier) {
1648 if (!pipeline || !
polygon)
return;
1667 int selectionModifier) {
1677 if (!m_viewer)
return nullptr;
1687 return manager ? manager->
getPipeline() :
nullptr;
1737 widget->setCursor(cursor);
1745 widget->setCursor(Qt::ArrowCursor);
1746 widget->unsetCursor();
1753 vtkInteractorObserver* currentStyle =
1754 m_interactor->GetInteractorStyle();
1755 vtkInteractorStyle* style =
1756 vtkInteractorStyle::SafeDownCast(currentStyle);
1764 bool isSelectionStyle =
1765 (vtkInteractorStyleRubberBand3D::SafeDownCast(style) !=
1767 (vtkInteractorStyleRubberBandZoom::SafeDownCast(style) !=
1769 (vtkInteractorStyleDrawPolygon::SafeDownCast(style) !=
1772 if (!isSelectionStyle) {
1773 m_previousStyle = style;
1775 "non-selection style: %1")
1776 .arg(style->GetClassName()));
1784 if (m_interactor && m_previousStyle) {
1785 m_interactor->SetInteractorStyle(m_previousStyle);
1786 m_previousStyle =
nullptr;
1787 }
else if (m_interactor) {
1796 defaultStyle->SetDefaultRenderer(m_renderer);
1798 m_interactor->SetInteractorStyle(defaultStyle);
1801 m_selectionStyle =
nullptr;
1806 bool renderOnMouseMove) {
1810 if (!renderOnMouseMove) {
1811 style->RenderOnMouseMoveOff();
1814 style->SetDefaultRenderer(m_renderer);
1816 m_selectionStyle = style;
1817 m_interactor->SetInteractorStyle(style);
1827 if (!m_interactor)
return;
1862 m_selectionStyle = zoomStyle;
1863 m_interactor->SetInteractorStyle(zoomStyle);
1875 polygonStyle->SetDefaultRenderer(m_renderer);
1877 m_selectionStyle = polygonStyle;
1878 m_interactor->SetInteractorStyle(polygonStyle);
1890 if (!m_interactor)
return;
1892 m_observedObject = m_interactor;
1903 m_observerIds[0] = m_interactor->AddObserver(
1904 vtkCommand::LeftButtonPressEvent,
this,
1906 m_observerIds[1] = m_interactor->AddObserver(
1907 vtkCommand::LeftButtonReleaseEvent,
this,
1917 m_observerIds[0] = m_interactor->AddObserver(
1918 vtkCommand::MouseMoveEvent,
this,
1920 m_observerIds[1] = m_interactor->AddObserver(
1921 vtkCommand::LeftButtonReleaseEvent,
this,
1930 m_observerIds[0] = m_interactor->AddObserver(
1931 vtkCommand::MouseMoveEvent,
this,
1940 if (m_selectionStyle) {
1941 m_styleObserverId = m_selectionStyle->AddObserver(
1942 vtkCommand::SelectionChangedEvent,
this,
1955 if (!m_interactor)
return;
1957 m_observerIds[startIndex++] = m_interactor->AddObserver(
1958 vtkCommand::MouseWheelForwardEvent,
this,
1960 m_observerIds[startIndex++] = m_interactor->AddObserver(
1961 vtkCommand::MouseWheelBackwardEvent,
this,
1963 m_observerIds[startIndex++] = m_interactor->AddObserver(
1964 vtkCommand::RightButtonPressEvent,
this,
1966 m_observerIds[startIndex++] = m_interactor->AddObserver(
1967 vtkCommand::RightButtonReleaseEvent,
this,
1969 m_observerIds[startIndex++] = m_interactor->AddObserver(
1970 vtkCommand::MiddleButtonPressEvent,
this,
1972 m_observerIds[startIndex] = m_interactor->AddObserver(
1973 vtkCommand::MiddleButtonReleaseEvent,
this,
1982 QString settingsKey, title, message;
1986 settingsKey =
"pqTooltipSelection";
1987 title = tr(
"Tooltip Selection Information");
1989 "You are entering tooltip selection mode to display cell "
1991 "Simply move the mouse point over the dataset to "
1992 "interactively highlight "
1993 "cells and display a tooltip with cell "
1995 "Use the 'Esc' key or the same toolbar button to exit this "
2000 settingsKey =
"pqTooltipSelection";
2001 title = tr(
"Tooltip Selection Information");
2003 tr(
"You are entering tooltip selection mode to display "
2004 "points information. "
2005 "Simply move the mouse point over the dataset to "
2006 "interactively highlight "
2007 "points and display a tooltip with points "
2009 "Use the 'Esc' key or the same toolbar button to exit "
2015 settingsKey =
"pqInteractiveSelection";
2016 title = tr(
"Interactive Selection Information");
2018 tr(
"You are entering interactive selection mode to "
2019 "highlight cells (or points). "
2020 "Simply move the mouse point over the dataset to "
2021 "interactively highlight elements.\n\n"
2022 "To add the currently highlighted element to the active "
2023 "selection, simply click on that element.\n\n"
2024 "You can click on selection modifier button or use "
2025 "modifier keys to subtract or "
2026 "even toggle the selection. Click outside of mesh to "
2027 "clear selection.\n\n"
2028 "Use the 'Esc' key or the same toolbar button to exit "
2038 if (!settingsKey.isEmpty()) {
boost::geometry::model::polygon< point_xy > polygon
static bool Warning(const char *format,...)
Prints out a formatted warning message in console.
static bool PrintVerbose(const char *format,...)
Prints out a verbose formatted message in console.
vtkRenderer * getCurrentRenderer(int viewport=0)
bool isPointPickingEnabled()
std::string getIdByActor(vtkProp *actor)
ccHObject * getSourceObject(const std::string &viewID) const
Get the source object for a given viewID.
vtkSmartPointer< vtkRenderWindowInteractor > getRenderWindowInteractor()
Get a pointer to the current interactor style used.
void setPointPickingEnabled(bool state)
Hierarchical CLOUDVIEWER Object.
virtual void onLeftButtonRelease()
Handle left button release (for interactive selection)
~cvRenderViewSelectionReaction() override
Q_INVOKABLE void handleRightButtonRelease()
Handle right button release (public for callback access)
bool isTooltipMode() const
Check if this is a tooltip mode.
void vtkOnRightButtonPressed(vtkObject *caller, unsigned long eventId, void *callData)
void zoomToBoxCompleted(int xmin, int ymin, int xmax, int ymax)
Emitted when zoom to box is completed.
void selectPolygonCells(vtkIntArray *polygon, int selectionModifier)
Select cells in polygon.
Q_INVOKABLE void handleWheelRotate()
Handle wheel rotation (public for callback access)
void vtkOnSelectionChanged(vtkObject *caller, unsigned long eventId, void *callData)
VTK callback functions for observer pattern.
virtual void beginSelection()
Starts the selection mode.
virtual void updateEnableState()
Updates the enabled state of the action.
void vtkOnLeftButtonRelease(vtkObject *caller, unsigned long eventId, void *callData)
::SelectionMode SelectionMode
void vtkOnMiddleButtonPressed(vtkObject *caller, unsigned long eventId, void *callData)
void selectCellsOnSurface(int region[4], int selectionModifier)
Select cells on surface.
void selectFrustumCells(int region[4], int selectionModifier)
Select cells in frustum.
void vtkOnMiddleButtonRelease(vtkObject *caller, unsigned long eventId, void *callData)
void finalizeSelection(const cvSelectionData &newSelection, int selectionModifier, const QString &description)
Unified selection finalization (ParaView-style) Combines new selection with existing,...
void setupInteractorStyle()
Set up interactor style for this selection mode.
PclUtils::PCLVis * getPCLVis() const
Get the PCLVis instance.
Q_INVOKABLE void handleLeftButtonPress()
Handle left button press (public for callback access)
void selectPointsOnSurface(int region[4], int selectionModifier)
Select points on surface.
cvRenderViewSelectionReaction(QAction *parentAction, SelectionMode mode, QActionGroup *modifierGroup=nullptr)
Constructor.
Q_INVOKABLE void handleMouseMove()
Handle mouse move event (public for callback access)
void unsetCursor()
Restore default cursor.
void vtkOnLeftButtonPress(vtkObject *caller, unsigned long eventId, void *callData)
void selectedCustomPolygon(vtkIntArray *polygon)
Emitted for custom polygon selection.
virtual void onMiddleButtonPressed()
Handle middle button press (disable pre-selection during pan)
void vtkOnMouseMove(vtkObject *caller, unsigned long eventId, void *callData)
void selectFrustumPoints(int region[4], int selectionModifier)
Select points in frustum.
void uncheckSelectionModifiers()
Uncheck selection modifier buttons.
void vtkOnRightButtonRelease(vtkObject *caller, unsigned long eventId, void *callData)
virtual void onMouseMove()
Handle mouse move events (for interactive selection)
QAction * parentAction() const
Get the parent action.
virtual void cleanupObservers()
Clean up event observers.
void selectPolygonPoints(vtkIntArray *polygon, int selectionModifier)
Select points in polygon.
bool isInteractiveMode() const
Check if this is an interactive selection mode.
void selectionFinished(const cvSelectionData &selectionData)
Emitted when selection is finished.
void vtkOnWheelRotate(vtkObject *caller, unsigned long eventId, void *callData)
Q_INVOKABLE void handleRightButtonPressed()
Handle right button press (public for callback access)
virtual void updateTooltip()
Update tooltip display.
virtual void onRightButtonPressed()
Handle right button press (disable pre-selection)
virtual void endSelection()
Ends the selection mode.
void setupObservers()
Set up event observers for this selection mode.
virtual void onWheelRotate()
Handle wheel rotation events.
cvSelectionHighlighter * getSelectionHighlighter() const
Get the selection highlighter.
virtual void preSelection()
Perform pre-selection highlighting.
virtual void onRightButtonRelease()
Handle right button release (re-enable pre-selection)
void setRubberBand3DStyle(bool renderOnMouseMove)
Set vtkInteractorStyleRubberBand3D as the interactor style.
bool isSelectingCells() const
Check if currently selecting cells (vs points)
virtual void clearSelectionCache()
Clear selection cache when data changes.
virtual void onMiddleButtonRelease()
Handle middle button release (re-enable pre-selection, invalidate cache)
virtual int getSelectionModifier()
Get the selection modifier from keyboard state.
void setCursor(const QCursor &cursor)
Set cursor on the view.
void handleSelectionChanged(vtkObject *caller, unsigned long eventId, void *callData)
Handle selection changed event from VTK (public for callback access)
void storeCurrentStyle()
Store current interactor style.
virtual void fastPreSelection()
Perform fast pre-selection using cached buffers.
cvSelectionPipeline * getSelectionPipeline() const
Get the selection pipeline.
virtual void onMouseStop()
Handle mouse stop event (for tooltip display)
void showInstructionDialog()
Show instruction dialog for interactive modes.
void selectBlock(int region[4], int selectionModifier)
Select blocks.
bool isActive() const
Check if this reaction's selection is currently active.
virtual void actionTriggered(bool val)
Called when the action is triggered.
virtual void onLeftButtonPress()
Handle left button press (for zoom tracking)
virtual bool isCompatible(SelectionMode mode)
Check if this selection is compatible with another mode.
virtual void selectionChanged(vtkObject *caller, unsigned long eventId, void *callData)
Callback for selection changed event from VTK.
void setVisualizer(ecvGenericVisualizer3D *viewer)
Set the visualizer for selection operations.
static void endActiveSelection()
Force end any active selection.
void addCameraMovementObservers(int startIndex)
Add camera movement observers for cache invalidation.
void restoreStyle()
Restore previous interactor style.
Q_INVOKABLE void handleLeftButtonRelease()
Handle left button release (public for callback access)
Encapsulates selection data without exposing VTK types.
bool isEmpty() const
Check if selection is empty.
bool hasActorInfo() const
Check if actor information is available.
vtkActor * primaryActor() const
Get the primary (front-most) actor.
Helper class for highlighting selected elements in the visualizer.
bool highlightSelection(const vtkSmartPointer< vtkIdTypeArray > &selection, int fieldAssociation, HighlightMode mode=SELECTED)
Highlight selected elements (automatically gets polyData from visualizer)
void setHighlightsVisible(bool visible)
Set visibility of all highlight actors.
bool highlightElement(vtkPolyData *polyData, vtkIdType elementId, int fieldAssociation)
Highlight a single element (for hover preview)
void clearHoverHighlight()
Clear only hover highlight (keep selected/preselected)
void clearHighlights()
Clear all highlights.
Selection pipeline abstraction layer.
void invalidateCachedSelection()
Clear selection cache and invalidate cached buffers.
PixelSelectionInfo getPixelSelectionInfo(int x, int y, bool selectCells)
Get complete pixel selection information at a screen position.
cvSelectionData selectCellsOnSurface(const int region[4])
High-level selection API (ParaView-style)
cvSelectionData selectPointsInPolygon(vtkIntArray *polygon)
Select points in polygon region.
static cvSelectionData combineSelections(const cvSelectionData &sel1, const cvSelectionData &sel2, CombineOperation operation)
Combine two selections.
cvSelectionData selectCellsInPolygon(vtkIntArray *polygon)
Select cells in polygon region.
cvSelectionData selectPointsOnSurface(const int region[4])
Select points on surface in a rectangular region.
static bool promptUser(const QString &settingsKey, const QString &title, const QString &message, QWidget *parent=nullptr)
Shows instruction dialog if not disabled by user (ParaView-style)
void exitSelectionMode()
Exit selection mode and release cached buffers.
CombineOperation
Selection combination methods (ParaView-style)
Central manager for all selection operations in the view.
bool canShrinkSelection() const
Check if the selection can be shrunk.
void setCurrentSelection(const cvSelectionData &selectionData, bool resetLayers=true)
Set the current selection data.
void shrinkSelection()
Shrink the current selection by one layer.
bool hasSelection() const
Check if there is a current selection.
cvSelectionPipeline * getPipeline()
Get the selection pipeline.
void clearSelection()
Clear all selections.
static cvViewSelectionManager * instance()
Get the singleton instance.
void growSelection()
Grow the current selection by one layer.
const cvSelectionData & currentSelection() const
Get the current selection data (VTK-independent)
void setSourceObject(ccHObject *obj)
Set the source object for selection operations.
cvSelectionHighlighter * getHighlighter()
Get the shared highlighter.
void selectionChanged()
Emitted when the selection has changed (legacy - for backward compatibility)
Generic visualizer 3D interface.
Simplified selection reaction class aligned with ParaView architecture.
@ SELECT_BLOCKS
Select blocks (rectangle)
@ SELECT_FRUSTUM_BLOCKS
Select blocks in frustum.
@ SELECT_FRUSTUM_POINTS
Select points in frustum.
@ SELECT_SURFACE_POINTS
Select points on surface (rectangle)
@ HOVER_CELLS_TOOLTIP
Show cell data tooltip on hover (read-only)
@ SELECT_SURFACE_POINTS_POLYGON
Select points on surface (polygon)
@ GROW_SELECTION
Expand selection by one layer.
@ SELECT_CUSTOM_POLYGON
Custom polygon selection (signal only)
@ SHRINK_SELECTION
Shrink selection by one layer.
@ SELECT_SURFACE_POINTS_INTERACTIVELY
@ SELECT_SURFACE_CELLS
Select cells on surface (rectangle)
@ SELECT_SURFACE_CELLS_INTERACTIVELY
@ HOVER_POINTS_TOOLTIP
Show point data tooltip on hover (read-only)
@ SELECT_SURFACE_CELLDATA_INTERACTIVELY
Hover highlight cell data.
@ SELECT_SURFACE_POINTDATA_INTERACTIVELY
Hover highlight point data.
@ ZOOM_TO_BOX
Zoom to box region.
@ SELECT_SURFACE_CELLS_POLYGON
Select cells on surface (polygon)
@ SELECT_FRUSTUM_CELLS
Select cells in frustum.
@ CLEAR_SELECTION
Clear current selection.
@ SELECTION_TOGGLE
Toggle selection (Ctrl+Shift)
@ SELECTION_DEFAULT
Replace selection (default)
@ SELECTION_ADDITION
Add to selection (Ctrl)
@ SELECTION_SUBTRACTION
Subtract from selection (Shift)
constexpr QRegularExpression::PatternOption CaseInsensitive
bool Copy(const std::string &from, const std::string &to, bool include_parent_dir=false, const std::string &extname="")
Copy a file or directory.
Fast Pre-Selection API (ParaView-aligned)