ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
cvSelectionPipeline.h
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
8 #pragma once
9 
10 // clang-format off
11 // Qt - must be included first for MOC to work correctly on Windows
12 #include <QtCore/QObject>
13 #include <QtCore/QHash>
14 #include <QtCore/QMap>
15 #include <QtCore/QString>
16 #include <QWidget>
17 // clang-format on
18 
19 #include "cvSelectionData.h"
20 #include "qPCL.h"
21 
22 // VTK
23 #include <vtkSmartPointer.h>
24 
25 // Forward declarations
26 class cvHardwareSelector;
27 class vtkSelection;
28 class vtkIntArray;
29 class vtkIdTypeArray;
30 class vtkDataObject;
31 class vtkDataSet;
32 class vtkRenderer;
33 class vtkProp;
34 
35 namespace PclUtils {
36 class PCLVis;
37 }
38 
53 class QPCL_ENGINE_LIB_API cvSelectionPipeline : public QObject {
54  Q_OBJECT
55 
56 public:
66  POLYGON_POINTS
67  };
68 
73  FIELD_ASSOCIATION_CELLS = 0,
74  FIELD_ASSOCIATION_POINTS = 1
75  };
76 
77  explicit cvSelectionPipeline(QObject* parent = nullptr);
78  ~cvSelectionPipeline() override;
79 
80  //=========================================================================
81  // Static Utility Methods (merged from cvSelectionToolHelper)
82  //=========================================================================
83 
95  static bool promptUser(const QString& settingsKey,
96  const QString& title,
97  const QString& message,
98  QWidget* parent = nullptr);
99 
103  void setVisualizer(PclUtils::PCLVis* viewer);
104 
111  vtkSmartPointer<vtkSelection> executeRectangleSelection(int region[4],
113 
120  vtkSmartPointer<vtkSelection> executePolygonSelection(vtkIntArray* polygon,
122 
129  static vtkSmartPointer<vtkIdTypeArray> extractSelectionIds(
130  vtkSelection* selection, FieldAssociation fieldAssociation);
131 
141  static QMap<vtkProp*, vtkDataSet*> extractDataFromSelection(
142  vtkSelection* selection);
143 
152  static vtkDataSet* getPrimaryDataFromSelection(vtkSelection* selection);
153 
165  static cvSelectionData convertToCvSelectionData(
166  vtkSelection* selection, FieldAssociation fieldAssociation);
167 
176  static bool pointInPolygon(const int point[2],
177  vtkIntArray* polygon,
178  vtkIdType numPoints);
179 
187  vtkSmartPointer<vtkSelection> refinePolygonSelection(
188  vtkSelection* selection, vtkIntArray* polygon, vtkIdType numPoints);
189 
196  return m_lastSelection;
197  }
198 
203  void setEnableCaching(bool enable);
204 
208  void clearCache();
209 
213  int getCacheSize() const;
214  int getCacheHits() const;
215  int getCacheMisses() const;
216 
225  void enterSelectionMode();
226 
230  void exitSelectionMode();
231 
235  bool isInSelectionMode() const { return m_inSelectionMode; }
236 
244  void invalidateCachedSelection();
245 
247 
265  void setPointPickingRadius(unsigned int radius);
266 
271  unsigned int getPointPickingRadius() const { return m_pointPickingRadius; }
273 
275 
290  bool valid; // Whether selection is valid
291  vtkIdType attributeID; // Element ID (point or cell) within the actor
292  vtkProp* prop; // The selected actor/prop
293  vtkPolyData* polyData; // PolyData from the selected actor
294 
296  : valid(false), attributeID(-1), prop(nullptr), polyData(nullptr) {}
297  };
298 
310  PixelSelectionInfo getPixelSelectionInfo(int x, int y, bool selectCells);
311 
326  vtkIdType fastPreSelectAt(int x, int y, bool selectCells);
327 
332  bool hasCachedBuffers() const;
333 
341  bool captureBuffersForFastPreSelection();
343 
345 
357  cvSelectionData selectCellsOnSurface(const int region[4]);
358 
364  cvSelectionData selectPointsOnSurface(const int region[4]);
365 
371  cvSelectionData selectCellsInPolygon(vtkIntArray* polygon);
372 
378  cvSelectionData selectPointsInPolygon(vtkIntArray* polygon);
380 
382 
390  OPERATION_DEFAULT = 0,
391  OPERATION_ADDITION = 1,
392  OPERATION_SUBTRACTION = 2,
393  OPERATION_TOGGLE = 3
394  };
395 
403  static cvSelectionData combineSelections(const cvSelectionData& sel1,
404  const cvSelectionData& sel2,
405  CombineOperation operation);
407 
408 signals:
412  void selectionCompleted(vtkSelection* selection);
413 
417  void errorOccurred(const QString& message);
418 
419 private:
424  vtkSmartPointer<vtkSelection> performHardwareSelection(
425  int region[4], FieldAssociation fieldAssociation);
426 
431  vtkSmartPointer<vtkSelection> getCachedSelection(const QString& key);
432 
436  void cacheSelection(const QString& key, vtkSelection* selection);
437 
441  QString generateCacheKey(int region[4], SelectionType type) const;
442 
446  FieldAssociation getFieldAssociation(SelectionType type) const;
447 
456  cvSelectionData convertSelectionToData(vtkSelection* vtkSel,
457  FieldAssociation fieldAssoc,
458  const QString& errorContext);
459 
460 private:
461  PclUtils::PCLVis* m_viewer;
462  vtkRenderer* m_renderer;
463 
464  // Hardware selector (ParaView-style cvHardwareSelector)
465  // Reference: ParaView uses vtkPVHardwareSelector for optimized selection
466  vtkSmartPointer<cvHardwareSelector> m_hardwareSelector;
467 
468  // Last selection result (for getPolyData() operations)
469  vtkSmartPointer<vtkSelection> m_lastSelection;
470 
471  // Selection cache
472  bool m_cachingEnabled;
473  QHash<QString, vtkSmartPointer<vtkSelection>> m_selectionCache;
474 
475  // Cache statistics
476  int m_cacheHits;
477  int m_cacheMisses;
478 
479  // Maximum cache size
480  static const int MAX_CACHE_SIZE = 50;
481 
482  // Selection mode state (for cache optimization)
483  bool m_inSelectionMode = false;
484 
485  // Flag to prevent concurrent access during invalidation
486  // Set to true while invalidateCachedSelection() is running
487  bool m_invalidating = false;
488 
489  // Point picking radius (ParaView-style)
490  // When selecting a single point, search in this radius if no direct hit
491  // ParaView code default is 0 (disabled), but settings XML sets it to 50
492  // Range: 0-100, where 0 disables radius-based selection
493  // We use 50 as default for better usability (ParaView settings default)
494  unsigned int m_pointPickingRadius =
495  50; // ParaView settings default for usability
496 };
char type
#define signals
boost::geometry::model::polygon< point_xy > polygon
Definition: TreeIso.cpp:37
Hardware selector with ParaView-style buffer caching.
Encapsulates selection data without exposing VTK types.
Selection pipeline abstraction layer.
void errorOccurred(const QString &message)
Emitted when an error occurs.
void selectionCompleted(vtkSelection *selection)
Emitted when selection is completed.
bool isInSelectionMode() const
Check if currently in selection mode.
FieldAssociation
Field association type.
vtkSmartPointer< vtkSelection > getLastSelection() const
Get the last selection result.
SelectionType
Selection type.
@ FRUSTUM_POINTS
Frustum points.
@ FRUSTUM_CELLS
Frustum cells.
@ SURFACE_CELLS
Surface cells (rectangle)
@ SURFACE_POINTS
Surface points (rectangle)
@ POLYGON_CELLS
Polygon cells.
unsigned int getPointPickingRadius() const
Get the current point picking radius.
CombineOperation
Selection combination methods (ParaView-style)
normal_z y
normal_z x
SelectionType
Definition: qcustomplot.h:402
#define QPCL_ENGINE_LIB_API
Definition: qPCL.h:15
Fast Pre-Selection API (ParaView-aligned)