Módulo 1: peine de curvatura + live cross-view durante drag (Tasks 17-18)

- viewer_lines.py: añade toggle curvatura (tecla C), señal offsets_dragging,
  método update_offsets (sin resetear zoom/pan), keyPressEvent, hint overlay,
  funciones _curvature_comb_data y _draw_curvature_comb para BodyPlan y Plan
- main_window.py: conecta offsets_dragging → slot ligero _on_offsets_dragging
  que actualiza vistas 2D en vivo; _on_offsets_edited_from_viewer usa
  update_offsets en lugar de set_hull para preservar zoom/pan al soltar

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-27 13:26:35 -04:00
parent 652fdca358
commit 62de89d63c
2 changed files with 189 additions and 16 deletions
+24 -13
View File
@@ -860,7 +860,10 @@ class MainWindow(QMainWindow):
if _vp is not None:
_vp.set_canvas(_widget)
# Conectar edición interactiva de control points → propagar a todos los visores
# Edición live durante drag → actualizar vistas cruzadas sin resetear zoom
self._viewer_bodyplan.offsets_dragging.connect(self._on_offsets_dragging)
self._viewer_plan.offsets_dragging.connect(self._on_offsets_dragging)
# Fin del drag → persistir + actualizar 3D + hidrostáticos
self._viewer_bodyplan.offsets_edited.connect(self._on_offsets_edited_from_viewer)
self._viewer_plan.offsets_edited.connect(self._on_offsets_edited_from_viewer)
@@ -1328,6 +1331,15 @@ class MainWindow(QMainWindow):
# ── Panel hidrostáticos ───────────────────────────────────
self._update_hydrostatics(hull)
def _on_offsets_dragging(self, offsets_table) -> None:
"""Slot ligero — actualiza vistas 2D durante drag sin resetear zoom ni actualizar 3D."""
hull = self._current_hull
if hull is None:
return
self._viewer_bodyplan.update_offsets(hull)
self._viewer_profile.update_offsets(hull)
self._viewer_plan.update_offsets(hull)
def _on_hull_changed_from_editor(self, hull) -> None:
"""Slot: el editor de offsets reconstruyo el Hull — propagar a visores y proyecto."""
self._current_hull = hull
@@ -1337,31 +1349,30 @@ class MainWindow(QMainWindow):
self.statusBar().showMessage(f"Offsets actualizados — {hull.name}")
def _on_offsets_edited_from_viewer(self, offsets_table) -> None:
"""Slot: un visor 2D editó un punto de control — sincronizar todos los visores.
"""Slot: fin del drag — persistir + actualizar 3D + hidrostáticos.
La OffsetsTable ya fue modificada in-place por el visor (durante el drag).
Aquí propagamos el cambio al visor 3D, al panel de hidrostáticos y al
editor de offsets, e informamos al proyecto del estado nuevo.
Usa update_offsets (no set_hull) para que los visores 2D NO reseteen
su zoom/pan al terminar una edición.
"""
hull = self._current_hull
if hull is None:
return
# hull.offsets ya contiene los cambios (modificación in-place del visor)
# hull.offsets ya fue modificado in-place durante el drag
if self._project is not None:
self._project.set_hull(hull)
# Refrescar la vista cruzada (edición body plan actualiza planta y viceversa)
self._viewer_bodyplan.set_hull(hull)
self._viewer_profile.set_hull(hull)
self._viewer_plan.set_hull(hull)
# Sincronizar editor de tabla de offsets
# Actualizar vistas 2D SIN resetear zoom/pan
self._viewer_bodyplan.update_offsets(hull)
self._viewer_profile.update_offsets(hull)
self._viewer_plan.update_offsets(hull)
# Sincronizar editor de tabla
self._offsets_editor.set_hull(hull)
# Actualizar visor 3D con la geometría nueva
# Visor 3D — sólo al soltar (no durante drag)
if self._viewer_3d is not None:
try:
self._viewer_3d.load_hull(hull)
except Exception as exc:
logger.warning("Error al actualizar visor 3D: %s", exc)
# Actualizar barra de hidrostáticos
# Barra de hidrostáticos
self._update_hydrostatics(hull)
self.statusBar().showMessage(f"Geometría editada — {hull.name}")