23 #include <QApplication>
26 #include <QDialogButtonBox>
31 #include <QVBoxLayout>
35 #include <vtkCellData.h>
36 #include <vtkDataObject.h>
37 #include <vtkDataSet.h>
38 #include <vtkIdTypeArray.h>
39 #include <vtkInformation.h>
40 #include <vtkIntArray.h>
41 #include <vtkMapper.h>
42 #include <vtkPointData.h>
44 #include <vtkRenderWindow.h>
45 #include <vtkRenderer.h>
46 #include <vtkSelection.h>
47 #include <vtkSelectionNode.h>
57 m_cachingEnabled(true),
67 QString(
"[cvSelectionPipeline] Destroyed - Cache stats: %1 "
75 if (m_viewer == viewer) {
90 .arg((quintptr)viewer, 0, 16));
96 if (!m_viewer || !m_renderer) {
97 CVLog::Warning(
"[cvSelectionPipeline] Invalid viewer or renderer");
103 if (m_cachingEnabled) {
104 QString cacheKey = generateCacheKey(region,
type);
109 QString(
"[cvSelectionPipeline] Cache hit! Total: %1/%2")
111 .arg(m_cacheHits + m_cacheMisses));
116 copy->DeepCopy(cached);
125 performHardwareSelection(region, fieldAssoc);
128 CVLog::Warning(
"[cvSelectionPipeline] Hardware selection failed");
134 if (m_cachingEnabled) {
135 QString cacheKey = generateCacheKey(region,
type);
136 cacheSelection(cacheKey, selection);
146 if (!m_viewer || !m_renderer || !
polygon) {
148 "[cvSelectionPipeline] Invalid viewer, renderer, or polygon");
157 vtkIdType numPoints =
polygon->GetNumberOfTuples();
160 CVLog::Warning(
"[cvSelectionPipeline] Polygon needs at least 3 points");
161 emit
errorOccurred(
"Invalid polygon: needs at least 3 points");
170 int minX = INT_MAX, minY = INT_MAX;
171 int maxX = INT_MIN, maxY = INT_MIN;
173 for (vtkIdType i = 0; i < numPoints; ++i) {
175 int y =
polygon->GetValue(i * 2 + 1);
176 minX = std::min(minX,
x);
177 minY = std::min(minY,
y);
178 maxX = std::max(maxX,
x);
179 maxY = std::max(maxY,
y);
183 if (minX >= maxX || minY >= maxY) {
184 CVLog::Warning(
"[cvSelectionPipeline] Invalid polygon bounding box");
190 vtkRenderWindow* renderWindow = m_viewer->getRenderWindow();
198 if (!m_hardwareSelector) {
200 m_hardwareSelector->SetPointPickingRadius(m_pointPickingRadius);
203 m_hardwareSelector->SetRenderer(m_renderer);
204 m_hardwareSelector->SetArea(minX, minY, maxX, maxY);
209 m_hardwareSelector->SetFieldAssociation(
210 vtkDataObject::FIELD_ASSOCIATION_CELLS);
212 m_hardwareSelector->SetFieldAssociation(
213 vtkDataObject::FIELD_ASSOCIATION_POINTS);
218 bool captureSuccess = m_hardwareSelector->CaptureBuffers();
219 if (!captureSuccess) {
221 "[cvSelectionPipeline] Failed to capture buffers for polygon");
223 renderWindow->Render();
224 captureSuccess = m_hardwareSelector->CaptureBuffers();
225 if (!captureSuccess) {
235 std::vector<int> polygonArray(numPoints * 2);
236 for (vtkIdType i = 0; i < numPoints * 2; ++i) {
237 polygonArray[i] =
polygon->GetValue(i);
240 vtkSelection* selection = m_hardwareSelector->GeneratePolygonSelection(
241 polygonArray.data(),
static_cast<vtkIdType
>(numPoints * 2));
245 "[cvSelectionPipeline] Polygon selection returned no results");
249 m_lastSelection = emptySelection;
251 return emptySelection;
256 smartSelection.TakeReference(selection);
259 m_lastSelection = smartSelection;
263 for (
unsigned int i = 0; i < smartSelection->GetNumberOfNodes(); ++i) {
264 vtkSelectionNode* node = smartSelection->GetNode(i);
265 if (node && node->GetSelectionList()) {
266 totalItems += node->GetSelectionList()->GetNumberOfTuples();
271 return smartSelection;
282 if (selection->GetNumberOfNodes() == 0) {
283 CVLog::Print(
"[cvSelectionPipeline] Selection has no nodes");
287 vtkSelectionNode* node = selection->GetNode(0);
294 vtkIdTypeArray* selectionList =
295 vtkIdTypeArray::SafeDownCast(node->GetSelectionList());
296 if (!selectionList) {
303 copy->DeepCopy(selectionList);
309 if (m_cachingEnabled != enable) {
310 m_cachingEnabled = enable;
311 CVLog::Print(QString(
"[cvSelectionPipeline] Caching %1")
312 .arg(enable ?
"enabled" :
"disabled"));
323 m_selectionCache.clear();
330 return m_selectionCache.size();
343 return m_inSelectionMode && m_hardwareSelector !=
nullptr;
348 if (!m_viewer || !m_renderer) {
350 "[cvSelectionPipeline] Cannot capture buffers - no "
355 vtkRenderWindow* renderWindow = m_viewer->getRenderWindow();
358 "[cvSelectionPipeline] Cannot capture buffers - no render "
364 if (!m_hardwareSelector) {
366 m_hardwareSelector->SetPointPickingRadius(m_pointPickingRadius);
369 m_hardwareSelector->SetRenderer(m_renderer);
372 int*
size = m_renderer->GetSize();
373 int*
origin = m_renderer->GetOrigin();
378 bool success = m_hardwareSelector->CaptureBuffers();
381 m_inSelectionMode =
true;
383 "[cvSelectionPipeline] Captured buffers for fast "
386 CVLog::Warning(
"[cvSelectionPipeline] Failed to capture buffers");
399 if (m_invalidating) {
403 if (!m_viewer || !m_renderer) {
405 "[cvSelectionPipeline::getPixelSelectionInfo] Invalid viewer "
415 int region[4] = {
x,
y,
x,
y};
420 if (selection && selection->GetNumberOfNodes() > 0) {
421 vtkSelectionNode* node = selection->GetNode(0);
422 if (node && node->GetSelectionList() &&
423 node->GetSelectionList()->GetNumberOfTuples() > 0) {
424 vtkIdTypeArray* ids =
425 vtkIdTypeArray::SafeDownCast(node->GetSelectionList());
426 if (ids && ids->GetNumberOfTuples() > 0) {
428 result.attributeID = ids->GetValue(0);
431 vtkInformation* properties = node->GetProperties();
432 if (properties && properties->Has(vtkSelectionNode::PROP())) {
433 result.prop = vtkProp::SafeDownCast(
434 properties->Get(vtkSelectionNode::PROP()));
437 vtkActor* actor = vtkActor::SafeDownCast(
result.prop);
438 if (actor && actor->GetMapper()) {
439 vtkDataSet*
data = actor->GetMapper()->GetInput();
440 result.polyData = vtkPolyData::SafeDownCast(
data);
460 if (m_inSelectionMode) {
464 m_inSelectionMode =
true;
474 if (!m_inSelectionMode) {
478 m_inSelectionMode =
false;
487 m_hardwareSelector =
nullptr;
494 m_invalidating =
true;
503 m_hardwareSelector =
nullptr;
506 m_lastSelection =
nullptr;
509 m_invalidating =
false;
517 m_pointPickingRadius = radius;
520 if (m_hardwareSelector) {
521 m_hardwareSelector->SetPointPickingRadius(radius);
524 CVLog::Print(QString(
"[cvSelectionPipeline] Point picking radius set to %1 "
531 int region[4], FieldAssociation fieldAssociation) {
540 if (m_invalidating) {
544 if (!m_viewer || !m_renderer) {
548 vtkRenderWindow* renderWindow = m_viewer->getRenderWindow();
561 vtk_region[0] = std::min(region[0], region[2]);
562 vtk_region[1] = std::min(region[1], region[3]);
563 vtk_region[2] = std::max(region[0], region[2]);
564 vtk_region[3] = std::max(region[1], region[3]);
567 "Input[%1,%2,%3,%4] -> Normalized[%5,%6,%7,%8]")
575 .arg(vtk_region[3]));
580 int previousSwapBuffers = renderWindow->GetSwapBuffers();
581 renderWindow->SwapBuffersOff();
585 if (!m_hardwareSelector) {
587 m_hardwareSelector->SetPointPickingRadius(m_pointPickingRadius);
589 QString(
"[cvSelectionPipeline] Created cvHardwareSelector "
590 "(ParaView-style) with PointPickingRadius=%1")
591 .arg(m_pointPickingRadius));
595 m_hardwareSelector->SetRenderer(m_renderer);
599 m_hardwareSelector->SetFieldAssociation(
600 vtkDataObject::FIELD_ASSOCIATION_CELLS);
602 m_hardwareSelector->SetFieldAssociation(
603 vtkDataObject::FIELD_ASSOCIATION_POINTS);
608 QString(
"[cvSelectionPipeline] cvHardwareSelector config: "
609 "FieldAssociation=%1, PointPickingRadius=%2")
612 .arg(m_pointPickingRadius));
621 selection.TakeReference(m_hardwareSelector->Select(vtk_region));
624 renderWindow->SetSwapBuffers(previousSwapBuffers);
628 "[cvSelectionPipeline] cvHardwareSelector returned null");
633 if (selection->GetNumberOfNodes() > 0) {
634 vtkSelectionNode* node = selection->GetNode(0);
635 if (node && node->GetSelectionList()) {
636 vtkIdType numIds = node->GetSelectionList()->GetNumberOfTuples();
638 QString(
"[cvSelectionPipeline] Selection completed: %1 IDs")
644 m_lastSelection = selection;
651 const QString& key) {
652 auto it = m_selectionCache.find(key);
653 if (it != m_selectionCache.end()) {
660 void cvSelectionPipeline::cacheSelection(
const QString& key,
661 vtkSelection* selection) {
667 if (m_selectionCache.size() >= MAX_CACHE_SIZE) {
670 auto it = m_selectionCache.begin();
671 m_selectionCache.erase(it);
672 CVLog::Print(
"[cvSelectionPipeline] Cache full, removed oldest entry");
677 copy->DeepCopy(selection);
678 m_selectionCache.insert(key,
copy);
682 QString cvSelectionPipeline::generateCacheKey(
int region[4],
685 return QString(
"%1_%2_%3_%4_%5")
717 vtkSelection* selection) {
718 QMap<vtkProp*, vtkDataSet*>
result;
722 "[cvSelectionPipeline::extractDataFromSelection] selection is "
727 for (
unsigned int i = 0; i < selection->GetNumberOfNodes(); ++i) {
728 vtkSelectionNode* node = selection->GetNode(i);
732 vtkInformation* properties = node->GetProperties();
733 if (!properties || !properties->Has(vtkSelectionNode::PROP())) {
737 vtkProp* prop = vtkProp::SafeDownCast(
738 properties->Get(vtkSelectionNode::PROP()));
742 vtkActor* actor = vtkActor::SafeDownCast(prop);
744 vtkMapper* mapper = actor->GetMapper();
746 vtkDataSet*
data = mapper->GetInput();
750 QString(
"[cvSelectionPipeline] Extracted data from "
751 "actor: %1 points, %2 cells, type=%3")
752 .arg(
data->GetNumberOfPoints())
753 .arg(
data->GetNumberOfCells())
754 .arg(
data->GetClassName()));
759 QString(
"[cvSelectionPipeline] prop is not vtkActor: %1")
760 .arg(prop ? prop->GetClassName() :
"null"));
769 vtkSelection* selection) {
772 if (dataMap.isEmpty()) {
774 "[cvSelectionPipeline::getPrimaryDataFromSelection] No data "
775 "found in selection");
780 vtkDataSet* primaryData =
nullptr;
781 vtkIdType maxCount = 0;
783 for (
auto it = dataMap.begin(); it != dataMap.end(); ++it) {
784 vtkDataSet*
data = it.value();
785 vtkIdType
count =
data->GetNumberOfPoints() +
data->GetNumberOfCells();
786 if (
count > maxCount) {
794 QString(
"[cvSelectionPipeline::getPrimaryDataFromSelection] "
795 "Primary data: %1 points, %2 cells")
796 .arg(primaryData->GetNumberOfPoints())
797 .arg(primaryData->GetNumberOfCells()));
808 "[cvSelectionPipeline::convertToCvSelectionData] selection is "
816 if (!ids || ids->GetNumberOfTuples() == 0) {
818 "[cvSelectionPipeline::convertToCvSelectionData] No IDs in "
830 for (
auto it = dataMap.begin(); it != dataMap.end(); ++it) {
831 vtkProp* prop = it.key();
832 vtkDataSet*
data = it.value();
834 vtkActor* actor = vtkActor::SafeDownCast(prop);
839 vtkPolyData* polyData = vtkPolyData::SafeDownCast(
data);
842 if (!polyData && actor) {
843 vtkMapper* mapper = actor->GetMapper();
845 polyData = vtkPolyData::SafeDownCast(mapper->GetInput());
849 if (actor && polyData) {
854 for (
unsigned int i = 0; i < selection->GetNumberOfNodes(); ++i) {
855 vtkSelectionNode* node = selection->GetNode(i);
857 node->GetProperties()->Has(vtkSelectionNode::PROP())) {
859 vtkProp::SafeDownCast(node->GetProperties()->Get(
860 vtkSelectionNode::PROP()));
861 if (nodeProp == prop) {
867 zValue = 1.0 - (
static_cast<double>(i) /
868 selection->GetNumberOfNodes());
879 result.addActorInfo(info);
882 QString(
"[cvSelectionPipeline] Failed to add actor info: "
883 "actor=%1, polyData=%2")
884 .arg(actor ?
"valid" :
"null")
885 .arg(polyData ?
"valid" :
"null"));
890 QString(
"[cvSelectionPipeline::convertToCvSelectionData] "
891 "Created selection: %1 IDs, %2 actors")
893 .arg(
result.actorCount()));
903 vtkSelection* vtkSel,
904 FieldAssociation fieldAssoc,
905 const QString& errorContext) {
908 QString(
"[cvSelectionPipeline] %1 failed").arg(errorContext));
928 "selectCellsOnSurface");
933 const int region[4]) {
938 "selectPointsOnSurface");
945 QString(
"[cvSelectionPipeline] selectCellsInPolygon: %1 vertices")
957 "selectCellsInPolygon");
964 QString(
"[cvSelectionPipeline] selectPointsInPolygon: %1 vertices")
976 "selectPointsInPolygon");
988 QString(
"[cvSelectionPipeline] combineSelections: operation=%1")
1021 QSet<vtkIdType> set1, set2, resultSet;
1025 for (vtkIdType i = 0; i < arr1->GetNumberOfTuples(); ++i) {
1026 set1.insert(arr1->GetValue(i));
1032 for (vtkIdType i = 0; i < arr2->GetNumberOfTuples(); ++i) {
1033 set2.insert(arr2->GetValue(i));
1038 switch (operation) {
1041 resultSet = set1 + set2;
1043 QString(
"[cvSelectionPipeline] ADDITION: %1 + %2 = %3")
1046 .arg(resultSet.size()));
1051 resultSet = set1 - set2;
1053 QString(
"[cvSelectionPipeline] SUBTRACTION: %1 - %2 = %3")
1056 .arg(resultSet.size()));
1061 resultSet = (set1 - set2) + (set2 - set1);
1063 QString(
"[cvSelectionPipeline] TOGGLE: %1 ^ %2 = %3")
1066 .arg(resultSet.size()));
1071 QString(
"[cvSelectionPipeline] Unknown operation: %1")
1077 if (resultSet.isEmpty()) {
1083 for (vtkIdType
id : resultSet) {
1084 resultArray->InsertNextValue(
id);
1093 for (
int i = 0; i < sel2.
actorCount(); ++i) {
1099 for (
int i = 0; i < sel1.
actorCount(); ++i) {
1102 for (
int j = 0; j <
result.actorCount(); ++j) {
1115 QString(
"[cvSelectionPipeline] combineSelections result: %1 IDs, "
1118 .arg(
result.actorCount()));
1126 vtkIdType numPoints) {
1131 float px =
static_cast<float>(point[0]);
1132 float py =
static_cast<float>(point[1]);
1133 bool inside =
false;
1135 vtkIdType
count = numPoints * 2;
1137 for (vtkIdType i = 0; i <
count; i += 2) {
1138 float p1X =
static_cast<float>(
polygon->GetValue(i));
1139 float p1Y =
static_cast<float>(
polygon->GetValue(i + 1));
1140 float p2X =
static_cast<float>(
polygon->GetValue((i + 2) %
count));
1141 float p2Y =
static_cast<float>(
polygon->GetValue((i + 3) %
count));
1144 if (
py > std::min(p1Y, p2Y) &&
py <= std::max(p1Y, p2Y) && p1Y != p2Y) {
1145 if (px <= std::max(p1X, p2X)) {
1146 float xintersection =
1147 (
py - p1Y) * (p2X - p1X) / (p2Y - p1Y) + p1X;
1148 if (p1X == p2X || px <= xintersection) {
1161 vtkSelection* selection, vtkIntArray*
polygon, vtkIdType numPoints) {
1166 if (!selection || !
polygon || numPoints < 3) {
1168 "[cvSelectionPipeline::refinePolygonSelection] Invalid "
1176 for (
unsigned int nodeIdx = 0; nodeIdx < selection->GetNumberOfNodes();
1178 vtkSelectionNode* node = selection->GetNode(nodeIdx);
1179 if (!node)
continue;
1181 vtkIdTypeArray* selectionList =
1182 vtkIdTypeArray::SafeDownCast(node->GetSelectionList());
1183 if (!selectionList)
continue;
1186 vtkInformation* properties = node->GetProperties();
1187 if (!properties || !properties->Has(vtkSelectionNode::PROP())) {
1191 newNode->DeepCopy(node);
1192 refinedSelection->AddNode(newNode);
1196 vtkProp* prop = vtkProp::SafeDownCast(
1197 properties->Get(vtkSelectionNode::PROP()));
1198 vtkActor* actor = vtkActor::SafeDownCast(prop);
1204 newNode->DeepCopy(node);
1205 refinedSelection->AddNode(newNode);
1213 filteredList->SetName(selectionList->GetName());
1215 vtkMapper* mapper = actor->GetMapper();
1216 if (!mapper)
continue;
1218 vtkDataSet*
data = mapper->GetInput();
1219 if (!
data)
continue;
1221 int fieldAssociation = node->GetFieldType();
1223 for (vtkIdType i = 0; i < selectionList->GetNumberOfTuples(); ++i) {
1224 vtkIdType
id = selectionList->GetValue(i);
1227 double worldPos[3] = {0, 0, 0};
1228 if (fieldAssociation == vtkDataObject::FIELD_ASSOCIATION_POINTS) {
1229 if (
id >= 0 && id < data->GetNumberOfPoints()) {
1230 data->GetPoint(
id, worldPos);
1236 if (
id >= 0 && id < data->GetNumberOfCells()) {
1238 data->GetCellBounds(
id, bounds);
1239 worldPos[0] = (bounds[0] + bounds[1]) / 2.0;
1240 worldPos[1] = (bounds[2] + bounds[3]) / 2.0;
1241 worldPos[2] = (bounds[4] + bounds[5]) / 2.0;
1249 double displayPos[3];
1250 m_renderer->SetWorldPoint(worldPos[0], worldPos[1], worldPos[2],
1252 m_renderer->WorldToDisplay();
1253 m_renderer->GetDisplayPoint(displayPos);
1255 int screenPoint[2] = {
static_cast<int>(displayPos[0]),
1256 static_cast<int>(displayPos[1])};
1260 filteredList->InsertNextValue(
id);
1264 filteredList->InsertNextValue(
id);
1269 if (filteredList->GetNumberOfTuples() > 0) {
1272 newNode->DeepCopy(node);
1273 newNode->SetSelectionList(filteredList);
1274 refinedSelection->AddNode(newNode);
1278 CVLog::Print(QString(
"[cvSelectionPipeline::refinePolygonSelection] "
1279 "Refined from %1 to %2 nodes")
1280 .arg(selection->GetNumberOfNodes())
1281 .arg(refinedSelection->GetNumberOfNodes()));
1283 return refinedSelection;
1290 const QString& title,
1291 const QString& message,
1295 QString key = QString(
"SelectionTools/DontShowAgain/%1").arg(settingsKey);
1296 bool dontShow = settings.value(key,
false).toBool();
1303 QDialog dialog(parent);
1304 dialog.setWindowTitle(title);
1305 dialog.setModal(
true);
1307 QVBoxLayout* mainLayout =
new QVBoxLayout(&dialog);
1308 mainLayout->setContentsMargins(20, 20, 20, 20);
1309 mainLayout->setSpacing(15);
1312 QHBoxLayout* contentLayout =
new QHBoxLayout();
1315 QLabel* iconLabel =
new QLabel(&dialog);
1317 dialog.style()->standardIcon(QStyle::SP_MessageBoxInformation);
1318 iconLabel->setPixmap(infoIcon.pixmap(32, 32));
1319 iconLabel->setAlignment(Qt::AlignTop);
1320 contentLayout->addWidget(iconLabel);
1323 QLabel* textLabel =
new QLabel(message, &dialog);
1324 textLabel->setWordWrap(
true);
1325 textLabel->setTextFormat(Qt::RichText);
1326 textLabel->setMinimumWidth(400);
1327 contentLayout->addWidget(textLabel, 1);
1329 mainLayout->addLayout(contentLayout);
1332 QCheckBox* dontShowAgainCheckBox =
new QCheckBox(
1333 QObject::tr(
"Do not show this message again"), &dialog);
1334 mainLayout->addWidget(dontShowAgainCheckBox);
1337 QDialogButtonBox* buttonBox =
1338 new QDialogButtonBox(QDialogButtonBox::Ok, &dialog);
1339 QObject::connect(buttonBox, &QDialogButtonBox::accepted, &dialog,
1341 mainLayout->addWidget(buttonBox);
1347 if (dontShowAgainCheckBox->isChecked()) {
1348 settings.setValue(key,
true);
1349 CVLog::Print(QString(
"[cvSelectionPipeline::promptUser] User checked "
1350 "'don't show again' for key: %1")
boost::geometry::model::polygon< point_xy > polygon
static bool Warning(const char *format,...)
Prints out a formatted warning message in console.
static bool Print(const char *format,...)
Prints out a formatted message in console.
static bool PrintVerbose(const char *format,...)
Prints out a verbose formatted message in console.
vtkRenderer * getCurrentRenderer(int viewport=0)
Encapsulates selection data without exposing VTK types.
FieldAssociation fieldAssociation() const
Get field association.
vtkSmartPointer< vtkIdTypeArray > vtkArray() const
Get the underlying VTK array (for internal use only)
FieldAssociation
Field association for selection.
bool isEmpty() const
Check if selection is empty.
int actorCount() const
Get number of actors in this selection.
cvActorSelectionInfo actorInfo(int index=0) const
Get actor info at index.
void errorOccurred(const QString &message)
Emitted when an error occurs.
void setPointPickingRadius(unsigned int radius)
Point Picking Radius support (ParaView-aligned)
void invalidateCachedSelection()
Clear selection cache and invalidate cached buffers.
static bool pointInPolygon(const int point[2], vtkIntArray *polygon, vtkIdType numPoints)
Test if a 2D point is inside a polygon (ParaView-aligned) Uses the ray casting algorithm for robust p...
bool captureBuffersForFastPreSelection()
Capture buffers for fast pre-selection.
vtkSmartPointer< vtkSelection > refinePolygonSelection(vtkSelection *selection, vtkIntArray *polygon, vtkIdType numPoints)
Refine polygon selection with point-in-polygon testing.
vtkIdType fastPreSelectAt(int x, int y, bool selectCells)
Perform fast pre-selection at a screen position.
bool hasCachedBuffers() const
Check if fast pre-selection buffers are available.
static cvSelectionData convertToCvSelectionData(vtkSelection *selection, FieldAssociation fieldAssociation)
Convert vtkSelection to cvSelectionData with actor info (ParaView-style)
void selectionCompleted(vtkSelection *selection)
Emitted when selection is completed.
cvSelectionPipeline(QObject *parent=nullptr)
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.
vtkSmartPointer< vtkSelection > executeRectangleSelection(int region[4], SelectionType type)
Execute a rectangular selection.
void setVisualizer(PclUtils::PCLVis *viewer)
Set the visualizer for selection operations.
vtkSmartPointer< vtkSelection > executePolygonSelection(vtkIntArray *polygon, SelectionType type)
Execute a polygon selection.
FieldAssociation
Field association type.
@ FIELD_ASSOCIATION_CELLS
@ FIELD_ASSOCIATION_POINTS
void clearCache()
Clear the selection cache.
static cvSelectionData combineSelections(const cvSelectionData &sel1, const cvSelectionData &sel2, CombineOperation operation)
Combine two selections.
static QMap< vtkProp *, vtkDataSet * > extractDataFromSelection(vtkSelection *selection)
Get data objects from selection (ParaView-style)
cvSelectionData selectCellsInPolygon(vtkIntArray *polygon)
Select cells in polygon region.
static vtkDataSet * getPrimaryDataFromSelection(vtkSelection *selection)
Get the primary data object from selection.
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)
static vtkSmartPointer< vtkIdTypeArray > extractSelectionIds(vtkSelection *selection, FieldAssociation fieldAssociation)
Extract selected IDs from vtkSelection.
void exitSelectionMode()
Exit selection mode and release cached buffers.
~cvSelectionPipeline() override
int getCacheMisses() const
SelectionType
Selection type.
@ POLYGON_POINTS
Polygon points.
@ FRUSTUM_POINTS
Frustum points.
@ FRUSTUM_CELLS
Frustum cells.
@ SURFACE_CELLS
Surface cells (rectangle)
@ SURFACE_POINTS
Surface points (rectangle)
@ POLYGON_CELLS
Polygon cells.
void setEnableCaching(bool enable)
Enable/disable selection caching.
int getCacheSize() const
Get cache statistics.
CombineOperation
Selection combination methods (ParaView-style)
@ OPERATION_TOGGLE
XOR (sel1 ^ sel2)
@ OPERATION_ADDITION
Union (sel1 | sel2)
@ OPERATION_DEFAULT
Replace (sel2 only)
@ OPERATION_SUBTRACTION
Difference (sel1 & !sel2)
void enterSelectionMode()
Enter selection mode (ParaView-style cache optimization)
Information about a selected actor/representation.
double zValue
Z-buffer depth value (for front-to-back ordering)
vtkPolyData * polyData
The associated polyData (weak pointer)
vtkActor * actor
The selected actor (weak pointer)
Fast Pre-Selection API (ParaView-aligned)