Files

166 lines
4.5 KiB
Python

import os
import sys
from pathlib import Path
# Add parent directory to path to allow running from examples folder
# without installing
sys.path.append(str(Path(__file__).parent.parent))
from navaltoolbox import ( # noqa: E402
Vessel,
Hull,
Tank,
Silhouette,
DownfloodingOpening,
OpeningType,
)
from navaltoolbox.visualization import ( # noqa: E402
plot_hydrostatic_condition,
plot_vessel_3d,
)
def main():
# 1. Resolve path to DTMB STL
# Assuming standard repo structure:
# python/examples/viz_demo.py -> rust/tests/data/dtmb5415.stl
current_dir = Path(__file__).parent
repo_root = current_dir.parent.parent
stl_path = repo_root / "rust" / "tests" / "data" / "dtmb5415.stl"
if not stl_path.exists():
print(f"Error: STL file not found at {stl_path}")
# Fallback for different CWD
stl_path = Path("rust/tests/data/dtmb5415.stl")
if not stl_path.exists():
print(
"Could not locate dtmb5415.stl. Check working directory."
)
return
print(f"Loading hull from {stl_path}...")
hull = Hull(str(stl_path))
# Scale to valid size if it's the model scale version?
# Usually DTMB5415 LBP is ~142m full scale or ~5.72m model scale.
# Let's check bounds.
bounds = hull.get_bounds()
length = bounds[1] - bounds[0]
print(f"Hull Length: {length:.2f} m")
if length < 10.0:
print("Scaling up to ship scale (approx 1:24.8)...")
hull.scale(24.8) # Approx scale for 5.72m model to 142m ship
# 2. Setup Vessel
vessel = Vessel(hull)
vessel.ap = 0
vessel.fp = 142
print("Adding components...")
# 3. Add Tanks
# Fwd Fuel Tank
tank1 = Tank.from_box(
"Fwd Fuel",
x_min=110.0,
x_max=120.0,
y_min=-4.0,
y_max=4.0,
z_min=4.0,
z_max=8.0,
fluid_density=850.0,
)
tank1.fill_percent = 85.0
vessel.add_tank(tank1)
# Aft Ballast
tank2 = Tank.from_box_hull_intersection(
hull=hull,
x_min=10.0,
x_max=20.0,
y_min=-8.0,
y_max=8.0,
z_min=0.0,
z_max=10.0,
fluid_density=1025.0,
name="Aft Ballast",
)
tank2.fill_percent = 50.0
vessel.add_tank(tank2)
# 4. Add Silhouette (Fake superstructure)
# Assuming deck at Z=10m roughly
deck_z = bounds[5]
if length < 10.0:
deck_z *= 24.8
points = [
(10.0, deck_z),
(80.0, deck_z),
(80.0, deck_z + 8.0), # Bridge
(60.0, deck_z + 8.0),
(60.0, deck_z + 15.0), # Mast
(55.0, deck_z + 15.0),
(55.0, deck_z + 8.0),
(10.0, deck_z + 4.0), # Poop deck
(10.0, deck_z), # Close silhouette
]
sil = Silhouette.from_points(points, "Profile")
vessel.add_silhouette(sil)
# 5. Add Openings
vent = DownfloodingOpening.from_point(
"Vent Stbd", (40.0, 6.0, deck_z + 1.0), OpeningType.vent()
)
vessel.add_opening(vent)
# 6. Visualize Upright
print("Generating 3D plot (Upright)...")
fig = plot_vessel_3d(
vessel, title="DTMB 5415 - Visualization Demo", opacity_hull=0.5
)
output_file = "dtmb_demo.html"
fig.write_html(output_file)
print(f"Success! Visualization saved to: {os.path.abspath(output_file)}")
# 7. Visualize Inclined (Hydrostatic Condition)
print("Generating 3D plot (Inclined)...")
# Simulate a condition: Draft 6.15m, Heel 15 deg, Trim 1 deg
fig_hydro = plot_hydrostatic_condition(
vessel,
draft=6.15,
heel=15.0,
trim=1.0,
title="DTMB 5415 - Hydrostatic (T=6.15m, Heel=15°, Trim=1°, COG)",
opacity_hull=0.5,
cog=(70.0, 0.0, 7.5), # Example COG
show_axes=False,
)
output_hydro = "dtmb_hydro.html"
fig_hydro.write_html(output_hydro)
print(
f"Success! Hydrostatic saved to: {os.path.abspath(output_hydro)}"
)
# Open files automatically based on platform
try:
if sys.platform == "darwin": # macOS
os.system(f"open {output_file}")
os.system(f"open {output_hydro}")
elif sys.platform == "win32": # Windows
os.startfile(output_file)
os.startfile(output_hydro)
elif sys.platform.startswith("linux"): # Linux
os.system(f"xdg-open {output_file}")
os.system(f"xdg-open {output_hydro}")
except Exception as e:
print(f"Could not open files automatically: {e}")
if __name__ == "__main__":
main()