feat: AR-Shipdesign initial commit

This commit is contained in:
2026-07-03 12:23:25 -04:00
parent 588735ea64
commit 9a08526361
16 changed files with 4431 additions and 394 deletions
+50 -10
View File
@@ -18,7 +18,7 @@ from typing import Optional
import numpy as np
from PySide6.QtCore import Qt, QTimer, Signal
from PySide6.QtWidgets import QLabel, QVBoxLayout, QWidget
from PySide6.QtWidgets import QHBoxLayout, QLabel, QPushButton, QVBoxLayout, QWidget
logger = logging.getLogger("ui.viewer_3d")
@@ -57,6 +57,9 @@ class Viewer3DWidget(QWidget):
self._plotter: Optional["QtInteractor"] = None
self._ready = False
self._pending_hull = None # hull recibido antes de que el plotter esté listo
self._hull_actor = None # actor VTK del casco — para toggle de aristas
self._show_edges = False # mallas apagadas por defecto (como Delftship)
self._edge_btn: Optional[QPushButton] = None
self._build_ui()
# ------------------------------------------------------------------
@@ -96,7 +99,26 @@ class Viewer3DWidget(QWidget):
old.hide()
old.deleteLater()
# Crear el interactor PyVista embebido
# ── Barra de herramientas 3D ───────────────────────────────
toolbar = QWidget()
toolbar.setObjectName("viewer3dToolbar")
tb_lo = QHBoxLayout(toolbar)
tb_lo.setContentsMargins(4, 2, 4, 2)
tb_lo.setSpacing(4)
self._edge_btn = QPushButton("⬡ Mallas")
self._edge_btn.setCheckable(True)
self._edge_btn.setChecked(self._show_edges)
self._edge_btn.setFixedHeight(22)
self._edge_btn.setToolTip(
"Mostrar / ocultar aristas de la malla (como Delftship)"
)
self._edge_btn.toggled.connect(self._on_edge_toggled)
tb_lo.addWidget(self._edge_btn)
tb_lo.addStretch()
lo.addWidget(toolbar)
# ── Interactor PyVista embebido ────────────────────────────
self._plotter = QtInteractor(
parent=self,
auto_update=False, # sin polling continuo de GPU
@@ -192,15 +214,22 @@ class Viewer3DWidget(QWidget):
return
self._plotter.clear()
# Casco principal — color acero naval
self._plotter.add_mesh(
# Casco principal — color sólido estilo DelftShip
# smooth_shading=False → facetas planas, aspecto sólido sin blur
# ambient alto → menos sombras duras, color uniforme
# specular bajo → sin brillos que difuminen el color
self._hull_actor = self._plotter.add_mesh(
mesh,
color="#3a6080",
smooth_shading=True,
show_edges=True,
edge_color="#4da8ff",
line_width=0.3,
opacity=0.92,
color="#4a8ab0", # azul acero más vivo
smooth_shading=False, # facetado / sólido (no blur)
show_edges=self._show_edges,
edge_color="#90c8f0",
line_width=0.6,
opacity=1.0, # totalmente opaco
ambient=0.40, # luz ambiente alta: sombras suaves
diffuse=0.60, # difuso moderado
specular=0.05, # casi sin especular (anti-blur)
specular_power=5,
name="hull",
)
@@ -226,6 +255,17 @@ class Viewer3DWidget(QWidget):
self._plotter.view_isometric()
self._plotter.reset_camera()
def _on_edge_toggled(self, checked: bool) -> None:
"""Activa / desactiva la malla de aristas sin re-renderizar el casco."""
self._show_edges = checked
if self._hull_actor is not None and self._plotter is not None:
prop = self._hull_actor.GetProperty()
if checked:
prop.EdgeVisibilityOn()
else:
prop.EdgeVisibilityOff()
self._plotter.render()
def closeEvent(self, event) -> None: # type: ignore[override]
"""Libera el contexto PyVista al cerrar."""
if self._plotter is not None: