update exe GUI build

This commit is contained in:
ykcheungab
2026-06-21 12:01:34 +08:00
parent 258948bcb7
commit 7feae9550e
18 changed files with 862 additions and 173 deletions
+102 -4
View File
@@ -3,7 +3,7 @@
from __future__ import annotations
from dataclasses import dataclass
from typing import Literal
from typing import Callable, Literal
import cv2
import numpy as np
@@ -396,21 +396,32 @@ class FlowArrowOverlay:
self.mesh = mesh
self.style = style or DEFAULT_FLOW_ARROW_STYLE
self._enabled = bool(self.style.enabled)
self._mesh_span = _mesh_span(mesh.rest_vertices)
_cylinder_template(o3d)
_cone_template(o3d)
self.arrow_mesh = create_flow_mesh_geometry(o3d) if self.style.enabled else None
self.arrow_mesh = create_flow_mesh_geometry(o3d) if self._enabled else None
@property
def enabled(self) -> bool:
return self.style.enabled
return self._enabled
def set_enabled(self, enabled: bool) -> None:
enabled = bool(enabled)
if enabled == self._enabled:
return
self._enabled = enabled
if enabled and self.arrow_mesh is None:
import open3d as o3d
self.arrow_mesh = create_flow_mesh_geometry(o3d)
def compute(
self,
flow,
valid_mask: np.ndarray | None = None,
) -> tuple[np.ndarray, np.ndarray, np.ndarray] | None:
if not self.style.enabled or self.arrow_mesh is None:
if not self._enabled or self.arrow_mesh is None:
return None
return build_flow_arrow_mesh(
@@ -429,3 +440,90 @@ class FlowArrowOverlay:
self.arrow_mesh.triangles = o3d.utility.Vector3iVector(arrow_triangles.astype(np.int32))
self.arrow_mesh.vertex_colors = o3d.utility.Vector3dVector(arrow_colors.astype(np.float64))
self.arrow_mesh.compute_vertex_normals()
FLOW_ARROWS_GEOMETRY_NAME = "flow_arrows"
@dataclass
class FlowArrowFilamentSlot:
added: bool = False
@dataclass
class FlowArrowHiddenSlot:
in_vis: bool = False
def ensure_flow_arrow_in_hidden_vis(
overlay: FlowArrowOverlay,
vis,
slot: FlowArrowHiddenSlot,
) -> None:
"""Add flow-arrow geometry to a HiddenVisualizer window when enabled at init."""
if overlay.enabled and overlay.arrow_mesh is not None and not slot.in_vis:
vis.add_geometry(overlay.arrow_mesh)
slot.in_vis = True
def update_flow_arrows_filament(
overlay: FlowArrowOverlay,
flow,
valid_mask,
*,
scene,
material,
slot: FlowArrowFilamentSlot,
mesh_to_o3d: Callable,
) -> None:
"""Sync flow-arrow TriangleMesh geometry to a Filament offscreen scene."""
flow_result = overlay.compute(flow, valid_mask=valid_mask)
if not overlay.enabled:
if slot.added:
scene.remove_geometry(FLOW_ARROWS_GEOMETRY_NAME)
slot.added = False
return
if flow_result is None or overlay.arrow_mesh is None:
return
flow_vertices, flow_triangles, flow_colors = flow_result
if len(flow_vertices) > 0:
flow_mesh = mesh_to_o3d(flow_vertices, flow_triangles, flow_colors)
if not slot.added:
scene.add_geometry(FLOW_ARROWS_GEOMETRY_NAME, flow_mesh, material)
slot.added = True
else:
scene.remove_geometry(FLOW_ARROWS_GEOMETRY_NAME)
scene.add_geometry(FLOW_ARROWS_GEOMETRY_NAME, flow_mesh, material)
elif slot.added:
scene.remove_geometry(FLOW_ARROWS_GEOMETRY_NAME)
slot.added = False
def update_flow_arrows_hidden(
overlay: FlowArrowOverlay,
flow,
valid_mask,
*,
vis,
slot: FlowArrowHiddenSlot,
) -> None:
"""Sync flow-arrow TriangleMesh geometry to a HiddenVisualizer window."""
flow_result = overlay.compute(flow, valid_mask=valid_mask)
if not overlay.enabled:
if slot.in_vis and overlay.arrow_mesh is not None:
empty = np.empty((0, 3), dtype=np.float64)
empty_i = np.empty((0, 3), dtype=np.int32)
overlay.apply(empty, empty_i, empty)
vis.update_geometry(overlay.arrow_mesh)
return
if overlay.arrow_mesh is None:
return
if not slot.in_vis:
vis.add_geometry(overlay.arrow_mesh)
slot.in_vis = True
if flow_result is not None:
flow_vertices, flow_triangles, flow_colors = flow_result
overlay.apply(flow_vertices, flow_triangles, flow_colors)
vis.update_geometry(overlay.arrow_mesh)