Skip to content

Visualization - Expose SelectMgr pixel tolerance via IVtk picker#1204

Open
soilSpoon wants to merge 1 commit intoOpen-Cascade-SAS:masterfrom
soilSpoon:fix/ivtk-pixel-tolerance
Open

Visualization - Expose SelectMgr pixel tolerance via IVtk picker#1204
soilSpoon wants to merge 1 commit intoOpen-Cascade-SAS:masterfrom
soilSpoon:fix/ivtk-pixel-tolerance

Conversation

@soilSpoon
Copy link
Copy Markdown

@soilSpoon soilSpoon commented Apr 17, 2026

Summary

IVtkTools_ShapePicker::SetTolerance(float) has been effectively a dead setter: it stored the value in myTolerance but nothing read it. The actual pick radius was taken from IVtkOCC_ViewerSelector::myPixTol, hardcoded to 2 in its constructor, guarded by a one-shot myToUpdateTol flag that was flipped to false on the first Pick and never reset, and exposed through no public accessor.

As a result, no code path — public API, Draw command, or subclass — could change the pick radius after the first Pick. This matters most on high-DPI displays where 2 physical pixels are a small fraction of a CSS pixel, making edge and vertex selection practically unusable.

Root cause

IVtkOCC_ViewerSelector was introduced in 2011 modeled on StdSelect_ViewerSelector3d. It kept its own myPixTol/myToUpdateTol fields and a Pick() override that consulted them, instead of reading the base SelectMgr_ViewerSelector::myTolerances. Meanwhile StdSelect_ViewerSelector3d was simplified to a typedef over SelectMgr_ViewerSelector and AIS now uses the canonical flow at SelectMgr_ViewerSelector.cxx:1239:

mySelectingVolumeMgr.SetPixelTolerance(myTolerances.Tolerance());

IVtkOCC_ViewerSelector::Pick never migrated to this pattern, leaving the IVtk picker with a dead external API.

Change

Align IVtk with the existing AIS tolerance flow:

  • Remove myPixTol and myToUpdateTol from IVtkOCC_ViewerSelector.
  • Replace the caching branch in all three Pick overloads with mySelectingVolumeMgr.SetPixelTolerance(myTolerances.Tolerance()), read on every Pick, matching the base SelectMgr path.
  • Add SetPixelTolerance(int) / PixelTolerance() const on both IVtkOCC_ShapePickerAlgo and IVtkTools_ShapePicker, forwarding to SelectMgr_ViewerSelector's public API. Signatures match SelectMgr_ViewerSelector's exactly (same const int theTolerance param name).
  • Remove the dead SetTolerance(float) / GetTolerance() pair and the unused myTolerance field from IVtkTools_ShapePicker. Targeting the 8.0 major release window permits this API break; retaining them as deprecated would only preserve misleading no-ops and produce compile-silent bugs.
  • Update ivtkinit in TKIVtkDraw to use the new SetPixelTolerance(2) call, matching the historical hardcoded default.

After this change, IVtkTools_ShapePicker::SetPixelTolerance(n) behaves exactly like AIS_InteractiveContext::SetPixelTolerance(n).

Verification

Built vanilla OCCT master (commit 0ebbbedb23) on macOS and wrote a minimal C++ reproducer that drives IVtkTools_ShapePicker::Pick at increasing pixel offsets from a projected box edge. Results (same test, same renderer, only libTKIVtk swapped):

offset from edge vanilla master after fix, default after fix, SetPixelTolerance(20)
+0 px ✅ 1 ✅ 1 ✅ 1
+1 px ✅ 1 ✅ 1 ✅ 1
+2 px ❌ 0 ✅ 1 ✅ 1
+3 px ❌ 0 ❌ 0 ✅ 1
+5 px ❌ 0 ❌ 0 ✅ 1
+10 px ❌ 0 ❌ 0 ✅ 2
+20 px ✅ 1 ✅ 1 ✅ 1
+40 px ❌ 0 ❌ 0 ❌ 0

Observations:

  1. Default behavior preserved — base myTolerances.Tolerance() defaults produce essentially the same small pick radius as the old myPixTol = 2. No regression for existing users.
  2. SetPixelTolerance(20) works — hits at 3, 5, 10 px that previously missed, and PixelTolerance() returns 23 (= 20 custom + edge sensitivity contribution from the base myTolerances sum), exactly like AIS.
  3. Boundary correct — offset 40 still misses (off the box). Tolerance does not extend infinitely.
  4. Deletion confirmed empirically — relinking the test binary against the rebuilt library, the old reference to SetTolerance(float) fails with dyld: Symbol not found: __ZN21IVtkTools_ShapePicker12SetToleranceEf, i.e. the deletion reached ABI.

Scope

  • 7 files changed, +41 / −57 (net −16 lines of dead caching + dead setter code removed).
  • IVtkOCC_ShapePickerAlgo.{hxx,cxx}, IVtkOCC_ViewerSelector.{hxx,cxx}, IVtkTools_ShapePicker.{hxx,cxx}, IVtkDraw.cxx.
  • No changes to Draw tests or samples in this PR.

API break notice

The removal of IVtkTools_ShapePicker::SetTolerance(float) / GetTolerance() is a source-level break for downstream consumers that were calling them. Since these methods never affected picking behaviour, the migration is a one-line replacement:

- picker->SetTolerance(someFloat);
+ picker->SetPixelTolerance(someInt);

For downstream code that was relying on GetTolerance() to echo back the last value it set, the new PixelTolerance() returns the effective pixel tolerance (possibly adjusted by the base myTolerances sum).

Notes

  • I could add a Draw command (e.g. ivtksetpixtol <n>) and a tests/vtk/ivtk/ regression script as a follow-up. It was omitted here because TKIVtkDraw does not build on macOS (X11-only interactor path in IVtkDraw_Interactor.cxx). Happy to add it if preferred — Linux CI would cover it.
  • Branch name does not follow the CR<issue_id> convention since there is no Mantis ticket; can rename if required.

IVtkTools_ShapePicker::SetTolerance(float) was effectively a dead
setter: it stored the value in myTolerance but nothing read it. The
actual pick radius was taken from IVtkOCC_ViewerSelector::myPixTol,
hardcoded to 2 in its constructor, guarded by a one-shot myToUpdateTol
flag that was flipped to false on the first Pick and never reset, and
exposed through no public accessor.

The result: no code path — public API, Draw command, or subclass —
could change the pick radius after the first Pick. This matters most
on high-DPI displays where 2 physical pixels are a small fraction of
a CSS pixel, making edge and vertex selection practically unusable.

Align IVtk with the AIS tolerance flow already established in
SelectMgr_ViewerSelector::Pick (line 1239):

* Remove myPixTol and myToUpdateTol from IVtkOCC_ViewerSelector.
* Replace the caching branch in all three Pick overloads with
  mySelectingVolumeMgr.SetPixelTolerance(myTolerances.Tolerance()),
  read on every Pick, matching the base SelectMgr path.
* Add SetPixelTolerance(int) / PixelTolerance() on both
  IVtkOCC_ShapePickerAlgo and IVtkTools_ShapePicker, forwarding to
  SelectMgr_ViewerSelector's public API.
* Remove the dead SetTolerance(float) / GetTolerance() pair and the
  unused myTolerance field from IVtkTools_ShapePicker. Targeting the
  8.0 major release window permits this API break; retaining them as
  deprecated would only preserve misleading no-ops.
* Update ivtkinit in TKIVtkDraw to use the new SetPixelTolerance(2)
  call, matching the historical hardcoded default.

After this change, IVtkTools_ShapePicker::SetPixelTolerance(n) behaves
exactly like AIS_InteractiveContext::SetPixelTolerance(n): the value
is written to myTolerances via the base setter and read on every
subsequent Pick.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@soilSpoon soilSpoon force-pushed the fix/ivtk-pixel-tolerance branch from 8ba5886 to c5cf754 Compare April 17, 2026 12:48
@dpasukhi
Copy link
Copy Markdown
Member

dpasukhi commented Apr 17, 2026

Dear @soilSpoon

Thank you for your patch. To proceed with integration, please complete signing CLA process:
The links: Contribution Guide
Or https://dev.opencascade.org/get_involved
Please validate the filled fields, all fields are requiered, only with exception if written (optional).

In case if you already have signed CLA, please share ID that OCCT team shared with your by email after accepting of CLA.

@dpasukhi dpasukhi added the 3. CLA waited User need to process with CLA before review or integration processes label Apr 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

3. CLA waited User need to process with CLA before review or integration processes

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

2 participants