Skip to content

Add Edge Enhancement visual preset for D435/D435I - #15665

Merged
Nir-Az merged 5 commits into
realsenseai:developmentfrom
Binyaminp:RSDSO-21893
Sep 17, 2026
Merged

Nir-Az merged 5 commits into
realsenseai:developmentfrom
Binyaminp:RSDSO-21893

Conversation

@Binyaminp

@Binyaminp Binyaminp commented Sep 9, 2026 •

Copy link
Copy Markdown
Contributor

Overview: Adds a new "Edge Enhancement" visual preset, tuned for stronger edge preservation, available on all D400 devices.

Tracked on [RSDSO-21893]

Why

D400 devices lacked a preset tuned for stronger edge preservation in the depth map.

Summary

  • Added RS2_RS400_VISUAL_PRESET_EDGE_ENHANCEMENT to rs2_rs400_visual_preset (appended before _COUNT, no existing values changed)
  • Added edge_enhancement() in presets.cpp/.h, populated from a validated EdgeMap tuning JSON for D400 devices
  • Wired the new preset into apply_preset() in advanced_mode.cpp and into the rs2_rs400_visual_preset_to_string() mapping
  • get_preset_max_value() in d400-device.cpp now returns EDGE_ENHANCEMENT for all D400 devices (not just D435/D435I) so the preset is reachable via RS2_OPTION_VISUAL_PRESET everywhere
  • Added ds_advanced_mode_base::is_preset_supported(), checked against both firmware-registered feature support and device pid, so a preset a device doesn't support (e.g. REMOVE_IR_PATTERN on anything but D400/410/415/460) is no longer listed as a selectable option in the Visual Preset dropdown, instead of only failing at apply time
  • option_model::get_combo_labels() now skips option values with no description instead of assuming every value in [min, max] is valid

Test plan

  • Built realsense2 core library (Release, x64) — compiles cleanly, no new warnings
  • Built and launched realsense-viewer with the change
  • Manually verified "Edge Enhancement" appears in the Visual Preset dropdown in Advanced Mode on a D435i and applies correctly; Depth Clamp Max reads 65536 as expected
  • Verified on real hardware (D405, a passive/laser-less D400 SKU, FW 5.16.0.1): REMOVE_IR_PATTERN is correctly hidden from the option's enumerated values, and applying EDGE_ENHANCEMENT (laser_state=0) succeeds with no exception

🤖 Generated by AI

@sysrsbuild-gh-agentic sysrsbuild-gh-agentic left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Auto-generated review by rs-agentic bot. Found 2 bugs and 1 note below.

Comment thread src/ds/advanced_mode/presets.cpp Resolved
Comment thread src/ds/advanced_mode/presets.cpp Resolved
Comment thread src/ds/d400/d400-device.cpp Resolved

@sysrsbuild-gh-agentic sysrsbuild-gh-agentic left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 [rs-agentic] Reviewed new commit — one new bug noted inline; prior PID-coverage fix approved.

Comment thread src/ds/d400/d400-device.cpp Resolved
Comment thread src/ds/advanced_mode/presets.cpp Resolved
Comment thread src/ds/d400/d400-device.cpp Resolved
@Nir-Az

Nir-Az commented Sep 16, 2026

Copy link
Copy Markdown
Collaborator

get_preset_max_value() now returns EDGE_ENHANCEMENT for every D400, so REMOVE_IR_PATTERN (5) is inside [min,max] on devices that were previously capped below it. VALIDATE_RANGE in rs2_set_option (src/rs.cpp:949) no longer rejects it — rejection now depends on apply_preset() being reached.

The viewer half is handled by skipping null labels in get_combo_labels, but option_model::is_enum() (common/option-model.cpp:247) still returns false when any value in range lacks a description, so is_enum() gates the combo upstream and Visual Preset renders as a slider instead of a dropdown on D435/D455/D405. tools/dds/dds-adapter/lrs-device-controller.cpp:178 bails the same way for DDS.

Suggested:

  1. is_enum() — skip undescribed values rather than rejecting the option. Checked every enum option in the tree; all describe their full range, so nothing else changes rendering. Same one-line change at lrs-device-controller.cpp:178.
  2. Add the is_preset_supported() check to advanced_mode_preset_option::set() (src/ds/advanced_mode/advanced_mode.cpp:1120), right after is_valid(value), so an unsupported preset fails deterministically instead of depending on apply_preset() — today an advanced-mode-disabled device throws wrong_api_call_sequence_exception first.

(1) is the blocking one; (2) is hardening.

🤖 Generated by AI

@Binyaminp

Copy link
Copy Markdown
Contributor Author

✅ Fixed in d3a1621, both points.

  1. is_enum() now returns true if at least one value in range describes itself, instead of bailing to false on the first null — same one-line fix applied to get_option_enum_values() in lrs-device-controller.cpp:178 (return {} → continue).
  2. Added the is_preset_supported() check to advanced_mode_preset_option::set() right after is_valid(value), before the advanced-mode check.

Verified on the D405: attempting RS2_RS400_VISUAL_PRESET_REMOVE_IR_PATTERN now throws immediately with "set(advanced_mode_preset_option) failed! Device does not support preset Remove Ir Pattern" (the new deterministic error), and EDGE_ENHANCEMENT still applies cleanly with no regression.

🤖 Generated by AI

@sysrsbuild-gh-agentic sysrsbuild-gh-agentic left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 [rs-agentic] Reviewed the latest synchronize commit. Two new bugs found in the changes.

<< "apply_preset(...) failed! Given device doesn't support Remove IR Pattern Preset (pid=0x"
<< std::hex << device_pid << ")" );
break;
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 [rs-agentic] BUG: The default: throw was removed from the inner switch(device_pid) inside the REMOVE_IR_PATTERN case. is_preset_supported() and the dispatch switch now maintain two separate PID lists — if a PID is added to is_preset_supported() but omitted from the dispatch switch, the check passes, the switch matches no case, and apply_preset() silently continues with an uninitialised/default preset instead of throwing. Add back default: throw (or a default: assert(false)) to make the mismatch visible at runtime.

auto label = sensor.get_option_value_description( opt, i );
if( ! label )
return {}; // Missing value - not an enum
continue; // Value hidden for this device, not evidence the option isn't an enum

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 [rs-agentic] BUG: If current_value equals a value whose label is nullptr (hidden for this device), the continue skips the current_index = labels.size() assignment. The caller receives a stale/wrong current_index, misidentifying the currently-active option in the combo box. Consider checking i == current_value before the continue and either logging a warning or falling back to index 0 when the live value has no visible description.

@Nir-Az Nir-Az left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Enum appended before _COUNT so no ABI change, and apply_preset()/get_value_description() share one supported-check instead of duplicating the pid logic.

Checked the relaxed is_enum() against every enum option in the tree — all describe their full range, so nothing else changes between slider and dropdown rendering.

One thing still worth eyeballing before merge: the viewer itself on a device without Remove IR Pattern, that Visual Preset still draws as a dropdown. Verification so far is API-level on a D405.

@Nir-Az
Nir-Az merged commit b639336 into realsenseai:development Sep 17, 2026
52 of 53 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants