三维设置加箭头阈值,静默处理网格冲突
对话框写回 flow_on_px(二维三维共用),去掉 analysis_grid_mismatch 告警,缩短 UV/形变等工程腔文案并认 source=analysis。已用 pane UI 与 controller 单测验证。
This commit is contained in:
@@ -51,7 +51,6 @@ from orisys_studio.replay_analysis import (
|
||||
AnalysisSession,
|
||||
ResultLibrary,
|
||||
ResultPolicyError,
|
||||
policy_divergence,
|
||||
)
|
||||
from orisys_studio.shell_ports import ReplayShell
|
||||
|
||||
@@ -776,27 +775,19 @@ class ReplayController(QObject):
|
||||
state this view is served in.
|
||||
|
||||
A policy that moves the sample *grid* cannot be served by the stored candidate
|
||||
locations; :meth:`AnalysisSession.serve_policy` refuses it, the message names the
|
||||
keys, and the frame is still redrawn from the result's own grid, because
|
||||
re-gridding it would draw samples nothing measured.
|
||||
locations; :meth:`AnalysisSession.serve_policy` refuses it and the frame is
|
||||
still redrawn from the result's own grid — without a status-bar warning —
|
||||
because re-gridding it would draw samples nothing measured.
|
||||
"""
|
||||
session = self.available_result()
|
||||
if session is None:
|
||||
return
|
||||
from orisys_app_shared.scene3d.visual_policy import policy_for_settings
|
||||
|
||||
policy = policy_for_settings(settings)
|
||||
if not session.serve_policy(policy):
|
||||
# A box result's grid is the live painter's, not a display preference.
|
||||
# The display policy is the shared selector's, so the two always differ,
|
||||
# and saying so would scold the operator for a grid they cannot change.
|
||||
from orisys_app_shared.acquisition.arrows import uses_sdk_box_grid
|
||||
|
||||
if not uses_sdk_box_grid(session.stored_policy()):
|
||||
moved = policy_divergence(session.stored_policy(), policy)
|
||||
self._host.notify(
|
||||
t("playback.analysis_grid_mismatch", keys="·".join(moved))
|
||||
)
|
||||
# A policy that moves the sample grid is refused inside ``serve_policy``;
|
||||
# the frame is still redrawn from the result's own grid. No status-bar
|
||||
# lecture: the operator cannot change the stored locations from here.
|
||||
session.serve_policy(policy_for_settings(settings))
|
||||
self._engine.redraw()
|
||||
|
||||
def on_analysis_requested(self) -> None:
|
||||
|
||||
@@ -155,6 +155,10 @@ class ThreeDPanel(QFrame):
|
||||
#: Whether the pane explains the pipeline around the picture (the window's
|
||||
#: 「诊断信息」 switch). Off by default: the picture and what it *is* stay.
|
||||
self._show_diagnostics = False
|
||||
#: Sample-grid fields have no controls: they stay at the values restored from
|
||||
#: prefs (or the dataclass defaults) so a colour-scale click cannot reset them.
|
||||
self._flow_grid_spacing = 10
|
||||
self._max_arrows = 400
|
||||
|
||||
root = QVBoxLayout(self)
|
||||
root.setContentsMargins(8, 6, 8, 6)
|
||||
@@ -244,6 +248,20 @@ class ThreeDPanel(QFrame):
|
||||
self.contact_arrow_check.toggled.connect(self._emit_settings)
|
||||
form.addRow(self.contact_arrow_check)
|
||||
|
||||
# One threshold for both the 2D canvas and the 3D overlays. ``flow_off_px``
|
||||
# is derived (on − 0.1): neither view applies hysteresis today, and a band
|
||||
# only one side honoured was the 2D/3D arrow-count mismatch.
|
||||
self.flow_threshold_label = QLabel()
|
||||
self.flow_threshold_spin = QDoubleSpinBox()
|
||||
self.flow_threshold_spin.setRange(0.0, 50.0)
|
||||
self.flow_threshold_spin.setDecimals(2)
|
||||
self.flow_threshold_spin.setSingleStep(0.1)
|
||||
self.flow_threshold_spin.setSuffix(" px")
|
||||
self.flow_threshold_spin.setValue(0.4)
|
||||
self.flow_threshold_spin.setMaximumWidth(SPIN_WIDTH)
|
||||
self.flow_threshold_spin.valueChanged.connect(self._emit_settings)
|
||||
form.addRow(self.flow_threshold_label, self.flow_threshold_spin)
|
||||
|
||||
self.scale_label = QLabel()
|
||||
self.scale_combo = QComboBox()
|
||||
self.scale_combo.addItem("fixed", "fixed")
|
||||
@@ -539,20 +557,15 @@ class ThreeDPanel(QFrame):
|
||||
self.state_label.setVisible(self._show_diagnostics and state != "live")
|
||||
|
||||
def set_source_kind(self, kind: str) -> None:
|
||||
"""Say where the field comes from: ``live``, ``replay`` or ``recompute``.
|
||||
|
||||
Three states, and the difference between the last two is the point of the
|
||||
whole replay story:
|
||||
"""Say where the field comes from: live, replay, recompute or analysis.
|
||||
|
||||
* ``live`` — acquired from the device now;
|
||||
* ``replay`` — a recording is open and **no** 3D field is stored in it, so the
|
||||
pane is showing the surface model only;
|
||||
* ``recompute`` — a recompute pass is running over the recording's video, so
|
||||
what is on screen is what *this* algorithm version says about that footage.
|
||||
It is not the recorded measurement, and the label says so.
|
||||
* ``replay`` — a recording is open and **no** 3D field is stored in it;
|
||||
* ``recompute`` — a recompute pass is running over the recording's video;
|
||||
* ``analysis`` — a finished stored result is being read frame by frame.
|
||||
"""
|
||||
kind = str(kind)
|
||||
if kind not in ("live", "replay", "recompute"):
|
||||
if kind not in ("live", "replay", "recompute", "analysis"):
|
||||
kind = "live"
|
||||
self._source_kind = kind
|
||||
self.source_label.setText(t(f"scene3d.source_{kind}"))
|
||||
@@ -661,6 +674,7 @@ class ThreeDPanel(QFrame):
|
||||
self.gain_spin,
|
||||
self.flow_arrows_check,
|
||||
self.contact_arrow_check,
|
||||
self.flow_threshold_spin,
|
||||
self.scale_combo,
|
||||
self.fps_combo,
|
||||
self.reset_button,
|
||||
@@ -694,6 +708,9 @@ class ThreeDPanel(QFrame):
|
||||
self.field_combo.setCurrentIndex(index)
|
||||
self.flow_arrows_check.setChecked(bool(settings.flow_arrows_enabled))
|
||||
self.contact_arrow_check.setChecked(bool(settings.contact_arrow_enabled))
|
||||
self.flow_threshold_spin.setValue(float(settings.flow_on_px))
|
||||
self._flow_grid_spacing = max(1, int(settings.flow_grid_spacing))
|
||||
self._max_arrows = max(1, int(settings.max_arrows))
|
||||
self.depth_adaptive_check.setChecked(bool(settings.depth_scale_adaptive))
|
||||
scale = settings.color_scale
|
||||
if scale is not None:
|
||||
@@ -725,6 +742,9 @@ class ThreeDPanel(QFrame):
|
||||
deform = bool(self.deform_check.isChecked()) and bool(
|
||||
self._capabilities and self._capabilities.displacement_available
|
||||
)
|
||||
flow_on = max(0.0, float(self.flow_threshold_spin.value()))
|
||||
# Derived off band: kept for prefs / VisualPolicy, not applied as hysteresis.
|
||||
flow_off = max(0.0, flow_on - 0.1)
|
||||
return DisplaySettings(
|
||||
display_gain=float(self.gain_spin.value()),
|
||||
deform_enabled=deform,
|
||||
@@ -740,6 +760,10 @@ class ThreeDPanel(QFrame):
|
||||
field=self.field(),
|
||||
flow_arrows_enabled=bool(self.flow_arrows_check.isChecked()),
|
||||
contact_arrow_enabled=bool(self.contact_arrow_check.isChecked()),
|
||||
flow_on_px=flow_on,
|
||||
flow_off_px=flow_off,
|
||||
flow_grid_spacing=int(self._flow_grid_spacing),
|
||||
max_arrows=int(self._max_arrows),
|
||||
depth_scale_adaptive=bool(self.depth_adaptive_check.isChecked()),
|
||||
)
|
||||
|
||||
@@ -810,6 +834,9 @@ class ThreeDPanel(QFrame):
|
||||
self._render_field_note()
|
||||
self.flow_arrows_check.setText(t("scene3d.flow_arrows"))
|
||||
self.contact_arrow_check.setText(t("scene3d.contact_arrow"))
|
||||
self.flow_threshold_label.setText(t("scene3d.flow_threshold"))
|
||||
self.flow_threshold_label.setToolTip(t("scene3d.flow_threshold_tip"))
|
||||
self.flow_threshold_spin.setToolTip(t("scene3d.flow_threshold_tip"))
|
||||
self.scale_label.setText(t("scene3d.scale"))
|
||||
self.range_label.setText(t("scene3d.scale_range"))
|
||||
self.range_label.setToolTip(t("scene3d.scale_range_tip"))
|
||||
|
||||
@@ -49,7 +49,8 @@ class FingerOrientationDialog(QDialog):
|
||||
self.orientation_note.setWordWrap(True)
|
||||
|
||||
form.addRow(self.orientation_label, self.orientation_combo)
|
||||
form.addRow(self.orientation_note)
|
||||
# Tip lives on the combo; the note repeated the same sentence.
|
||||
self.orientation_note.setVisible(False)
|
||||
root.addLayout(form)
|
||||
|
||||
self.button_box = QDialogButtonBox(
|
||||
|
||||
Reference in New Issue
Block a user