22 #include <vtkCellPicker.h>
23 #include <vtkDataObject.h>
24 #include <vtkDataSetMapper.h>
25 #include <vtkHardwareSelector.h>
26 #include <vtkIdTypeArray.h>
27 #include <vtkInformation.h>
28 #include <vtkMapper.h>
29 #include <vtkPointPicker.h>
30 #include <vtkPolyData.h>
31 #include <vtkPolyDataMapper.h>
33 #include <vtkPropCollection.h>
34 #include <vtkRenderWindow.h>
35 #include <vtkRenderWindowInteractor.h>
36 #include <vtkRenderer.h>
37 #include <vtkSelection.h>
38 #include <vtkSelectionNode.h>
39 #include <vtkSmartPointer.h>
71 "[cvGenericSelectionTool] Using polyData from provided "
72 "selection actor info");
82 "[cvGenericSelectionTool] Using polyData from current "
83 "selection actor info");
99 int region[4] = {
x,
y,
x,
y};
115 "[hardwareSelectInRegion] Using cvSelectionPipeline");
190 "[hardwareSelectInRegion] Pipeline not available, using direct "
194 int fieldAssociation = vtkDataObject::FIELD_ASSOCIATION_CELLS;
198 fieldAssociation = vtkDataObject::FIELD_ASSOCIATION_POINTS;
205 vtkHardwareSelector* selector =
206 configureHardwareSelector(region, fieldAssociation);
209 "[hardwareSelectInRegion] Failed to configure hardware "
222 QVector<cvActorSelectionInfo> actorInfos =
223 extractActorInfo(selector, vtkSel);
248 return QVector<cvActorSelectionInfo>();
251 int region[4] = {
x,
y,
x,
y};
252 vtkHardwareSelector* selector = configureHardwareSelector(
253 region, vtkDataObject::FIELD_ASSOCIATION_CELLS);
256 return QVector<cvActorSelectionInfo>();
260 QVector<cvActorSelectionInfo> actorInfos;
263 actorInfos = extractActorInfo(selector, vtkSel);
272 vtkHardwareSelector* cvGenericSelectionTool::getHardwareSelector() {
276 "[getHardwareSelector] Created new hardware selector instance");
282 vtkHardwareSelector* cvGenericSelectionTool::configureHardwareSelector(
283 const int region[4],
int fieldAssociation) {
284 vtkRenderer* renderer = getRenderer();
286 CVLog::Warning(
"[configureHardwareSelector] No renderer available");
291 vtkHardwareSelector* selector = getHardwareSelector();
294 "[configureHardwareSelector] Failed to get hardware selector");
299 selector->SetRenderer(renderer);
300 selector->SetArea(region[0], region[1], region[2], region[3]);
301 selector->SetFieldAssociation(fieldAssociation);
307 "region=[%1,%2,%3,%4], "
308 "fieldAssoc=%5, captureZ=%6")
313 .arg(fieldAssociation)
320 QVector<cvActorSelectionInfo> cvGenericSelectionTool::extractActorInfo(
321 vtkHardwareSelector* selector, vtkSelection* vtkSel) {
322 QVector<cvActorSelectionInfo> actorInfos;
324 if (!selector || !vtkSel) {
329 vtkRenderer* renderer = getRenderer();
335 std::map<int, cvActorSelectionInfo> propInfoMap;
338 for (
unsigned int i = 0; i < vtkSel->GetNumberOfNodes(); ++i) {
339 vtkSelectionNode* node = vtkSel->GetNode(i);
344 if (node->GetProperties()->Has(vtkSelectionNode::PROP_ID())) {
345 propId = node->GetProperties()->Get(vtkSelectionNode::PROP_ID());
348 if (propId < 0)
continue;
351 vtkProp* prop = selector->GetPropFromID(propId);
352 vtkActor* actor = vtkActor::SafeDownCast(prop);
354 if (!actor)
continue;
363 unsigned int centerPos[2] = {
364 (selector->GetArea()[0] + selector->GetArea()[2]) / 2,
365 (selector->GetArea()[1] + selector->GetArea()[3]) / 2};
366 vtkHardwareSelector::PixelInformation pixelInfo =
367 selector->GetPixelInformation(centerPos, 0);
369 if (pixelInfo.Valid && pixelInfo.PropID == propId) {
372 pixelInfo.AttributeID >= 0
373 ?
static_cast<double>(pixelInfo.AttributeID) /
380 vtkMapper* mapper = actor->GetMapper();
383 if (vtkPolyDataMapper* pdMapper =
384 vtkPolyDataMapper::SafeDownCast(mapper)) {
385 info.
polyData = vtkPolyData::SafeDownCast(pdMapper->GetInput());
388 else if (vtkDataSetMapper* dsMapper =
389 vtkDataSetMapper::SafeDownCast(mapper)) {
390 vtkDataSet* dataset = dsMapper->GetInput();
392 info.
polyData = vtkPolyData::SafeDownCast(dataset);
398 if (node->GetProperties()->Has(vtkSelectionNode::COMPOSITE_INDEX())) {
400 vtkSelectionNode::COMPOSITE_INDEX());
404 propInfoMap[propId] = info;
408 actorInfos.reserve(propInfoMap.size());
409 for (
const auto& pair : propInfoMap) {
410 actorInfos.append(pair.second);
414 std::sort(actorInfos.begin(), actorInfos.end(),
416 return a.zValue < b.zValue;
420 .arg(actorInfos.size()));
427 vtkSelection* vtkSel,
const QVector<cvActorSelectionInfo>& actorInfos) {
430 if (!vtkSel || vtkSel->GetNumberOfNodes() == 0) {
435 vtkSelectionNode* node = vtkSel->GetNode(0);
441 vtkIdTypeArray* selectionIds =
442 vtkIdTypeArray::SafeDownCast(node->GetSelectionList());
449 int fieldAssociation = node->GetFieldType();
460 QString(
"[convertSelection] Selection: %1 items, %2 actors")
461 .arg(selection.
count())
473 return currentSelection;
476 if (currentSelection.
isEmpty() ||
482 QVector<qint64> newIds = newSelection.
ids();
483 QVector<qint64> currentIds = currentSelection.
ids();
489 for (qint64
id : newIds) {
490 resultSet.insert(
id);
497 for (qint64
id : newIds) {
498 resultSet.remove(
id);
505 for (qint64
id : newIds) {
506 if (resultSet.contains(
id)) {
507 resultSet.remove(
id);
509 resultSet.insert(
id);
528 for (
int i = 0; i < currentSelection.
actorCount(); ++i) {
532 for (
int i = 0; i < newSelection.
actorCount(); ++i) {
540 vtkRenderer* cvGenericSelectionTool::getRenderer() {
577 renderer = getRenderer();
585 vtkIdType pickedId = -1;
596 QString(
"[pickAtPosition] Picked cell ID: %1 from actor %2")
598 .arg((quintptr)pickedActor, 0, 16));
611 .arg((quintptr)pickedActor, 0, 16));
632 double pointTolerance) {
645 .arg(pointTolerance));
665 vtkMapper* mapper = actor->GetMapper();
671 vtkPolyDataMapper* pdMapper = vtkPolyDataMapper::SafeDownCast(mapper);
673 return vtkPolyData::SafeDownCast(pdMapper->GetInput());
677 vtkDataSetMapper* dsMapper = vtkDataSetMapper::SafeDownCast(mapper);
679 vtkDataSet* dataset = dsMapper->GetInput();
680 return vtkPolyData::SafeDownCast(dataset);
701 vtkIdType pickedId,
bool selectCells) {
710 ids.append(pickedId);
721 if (actor && polyData) {
732 info.
zValue = worldPos[2];
737 "selection: ID=%1, actor=%2")
739 .arg((quintptr)actor, 0, 16));
750 int fieldAssociation) {
755 "applySelectionModifierUnified: modifier=%1")
775 QString(
"[cvGenericSelectionTool] Unknown modifier: %1")
782 newSelection, operation);
QSet< T > qSetFromVector(const QVector< T > &vec)
QVector< T > qVectorFromSet(const QSet< T > &set)
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)
PclUtils::PCLVis * getPCLVis() const
Get PCLVis instance (for VTK-specific operations)
virtual vtkPolyData * getPolyDataForSelection(const cvSelectionData *selectionData=nullptr)
Get polyData using ParaView-style priority (centralized method)
bool hasValidPCLVis() const
Check if visualizer is valid and is PCLVis.
Encapsulates selection data without exposing VTK types.
FieldAssociation fieldAssociation() const
Get field association.
void addActorInfo(const cvActorSelectionInfo &info)
Actor/Representation information (ParaView-style)
FieldAssociation
Field association for selection.
@ CELLS
Selection applies to cells.
@ POINTS
Selection applies to points.
bool isEmpty() const
Check if selection is empty.
QVector< qint64 > ids() const
Get selected IDs as a vector (copy)
bool hasActorInfo() const
Check if actor information is available.
int actorCount() const
Get number of actors in this selection.
int count() const
Get number of selected items.
cvActorSelectionInfo actorInfo(int index=0) const
Get actor info at index.
vtkPolyData * primaryPolyData() const
Get the primary (front-most) polyData.
Selection pipeline abstraction layer.
static cvSelectionData convertToCvSelectionData(vtkSelection *selection, FieldAssociation fieldAssociation)
Convert vtkSelection to cvSelectionData with actor info (ParaView-style)
vtkSmartPointer< vtkSelection > executeRectangleSelection(int region[4], SelectionType type)
Execute a rectangular selection.
FieldAssociation
Field association type.
@ FIELD_ASSOCIATION_CELLS
@ FIELD_ASSOCIATION_POINTS
static cvSelectionData combineSelections(const cvSelectionData &sel1, const cvSelectionData &sel2, CombineOperation operation)
Combine two selections.
SelectionType
Selection type.
@ FRUSTUM_POINTS
Frustum points.
@ FRUSTUM_CELLS
Frustum cells.
@ SURFACE_CELLS
Surface cells (rectangle)
@ SURFACE_POINTS
Surface points (rectangle)
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)
cvSelectionPipeline * getPipeline()
Get the selection pipeline.
@ SELECT_FRUSTUM_POINTS
Select points in frustum.
@ SELECT_SURFACE_POINTS
Select points on surface (rectangle)
@ SELECT_SURFACE_CELLS
Select cells on surface (rectangle)
@ SELECT_FRUSTUM_CELLS
Select cells in frustum.
SelectionModifier
Selection modifiers for combining selections.
@ SELECTION_TOGGLE
Toggle selection (Ctrl+Shift)
@ SELECTION_DEFAULT
Replace selection (default)
@ SELECTION_ADDITION
Add to selection (Ctrl)
@ SELECTION_SUBTRACTION
Subtract from selection (Shift)
Information about a selected actor/representation.
double zValue
Z-buffer depth value (for front-to-back ordering)
unsigned int blockIndex
Block index for composite datasets.
int propId
Unique prop ID (from hardware selector)
vtkPolyData * polyData
The associated polyData (weak pointer)
vtkActor * actor
The selected actor (weak pointer)