Files
Alex38Lyon 135bd8e49c Modify PLY to STL conversion workflow
Updated GitHub Actions workflow for PLY to STL conversion.
2026-08-28 09:59:16 +02:00

247 lines
7.9 KiB
YAML

name: Convert PLY to STL
on:
push:
paths:
- '**/*.ply'
workflow_dispatch:
permissions:
contents: write
jobs:
convert:
runs-on: ubuntu-latest
steps:
# ------------------------------------------------------------
# Récupération du dépôt
# ------------------------------------------------------------
- name: Checkout repository
uses: actions/checkout@v6
# ------------------------------------------------------------
# Installation de Python
# ------------------------------------------------------------
- name: Setup Python
uses: actions/setup-python@v7
with:
python-version: '3.13'
# ------------------------------------------------------------
# Installation des bibliothèques
# ------------------------------------------------------------
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install trimesh numpy fast-simplification
# ------------------------------------------------------------
# Conversion PLY -> STL
# Recherche automatique du meilleur compromis qualité/taille
# ------------------------------------------------------------
- name: Convert PLY files to STL
run: |
python <<'PY'
import trimesh
import glob
import os
import tempfile
# Taille maximale autorisée.
# 50 MiB = 50 * 1024 * 1024 octets
MAX_SIZE = 50 * 1024 * 1024
# Marge de sécurité :
# on vise légèrement sous 50 MiB afin d'éviter
# tout dépassement lié aux métadonnées ou différences
# de calcul.
TARGET_SIZE = 49 * 1024 * 1024
# Ratios testés, du meilleur au moins bon.
# Le script s'arrête dès qu'il trouve un fichier
# suffisamment petit.
RATIOS = [
1.00,
0.90,
0.80,
0.70,
0.60,
0.50,
0.40,
0.30,
0.20,
0.10
]
ply_files = glob.glob('**/*.ply', recursive=True)
if not ply_files:
print("Aucun fichier PLY trouvé.")
exit(0)
for ply in ply_files:
print()
print("=" * 70)
print(f"Fichier : {ply}")
print("=" * 70)
# ----------------------------------------------------
# Chargement du maillage
# ----------------------------------------------------
mesh = trimesh.load(ply, force='mesh')
if mesh.is_empty:
print("ERREUR : maillage vide")
continue
if not isinstance(mesh, trimesh.Trimesh):
print("ERREUR : le fichier ne contient pas un maillage triangulaire.")
continue
original_faces = len(mesh.faces)
print(f"Triangles initiaux : {original_faces:,}")
# ----------------------------------------------------
# Fichier STL temporaire
# ----------------------------------------------------
base = os.path.splitext(ply)[0]
stl = base + '.stl'
best_mesh = None
best_size = None
best_ratio = None
# ----------------------------------------------------
# Essai des différents niveaux de simplification
# ----------------------------------------------------
for ratio in RATIOS:
target_faces = max(
1000,
int(original_faces * ratio)
)
print()
print(
f"Test : {ratio * 100:.0f}% "
f"({target_faces:,} triangles)"
)
# ------------------------------------------------
# Pas de simplification pour 100 %
# ------------------------------------------------
if ratio >= 1.0:
test_mesh = mesh.copy()
else:
try:
test_mesh = mesh.simplify_quadric_decimation(
face_count=target_faces
)
except Exception as e:
print(
"Erreur lors de la simplification : "
f"{e}"
)
continue
# ------------------------------------------------
# Export STL temporaire
# ------------------------------------------------
with tempfile.NamedTemporaryFile(
suffix='.stl',
delete=False
) as tmp:
temp_stl = tmp.name
try:
test_mesh.export(temp_stl)
size = os.path.getsize(temp_stl)
finally:
if os.path.exists(temp_stl):
os.remove(temp_stl)
size_mb = size / (1024 * 1024)
print(
f" -> {len(test_mesh.faces):,} triangles"
)
print(
f" -> {size_mb:.2f} MiB"
)
# ------------------------------------------------
# On conserve le premier résultat sous 49 MiB.
#
# Comme les ratios sont testés du plus grand
# au plus petit, c'est le meilleur résultat
# possible parmi les valeurs testées.
# ------------------------------------------------
if size < TARGET_SIZE:
best_mesh = test_mesh
best_size = size
best_ratio = ratio
print(" -> Taille acceptable")
break
# ----------------------------------------------------
# Aucun résultat suffisamment petit
# ----------------------------------------------------
if best_mesh is None:
print()
print(
"ERREUR : impossible d'obtenir un STL "
f"inférieur à {TARGET_SIZE / (1024 * 1024):.0f} MiB."
)
continue
# ----------------------------------------------------
# Export définitif
# ----------------------------------------------------
best_mesh.export(stl)
final_size = os.path.getsize(stl)
final_size_mb = final_size / (1024 * 1024)
print()
print("-" * 70)
print("RESULTAT")
print("-" * 70)
print(f"Fichier STL : {stl}")
print(f"Triangles : {len(best_mesh.faces):,}")
print(f"Ratio : {best_ratio * 100:.0f}%")
print(f"Taille : {final_size_mb:.2f} MiB")
print(f"Taille limite : 50.00 MiB")
if final_size >= MAX_SIZE:
print("ATTENTION : fichier supérieur à 50 MiB !")
else:
print("OK : fichier inférieur à 50 MiB.")
print("-" * 70)
PY
# ------------------------------------------------------------
# Commit des STL générés
# ------------------------------------------------------------
- name: Commit converted STL files
uses: stefanzweifel/git-auto-commit-action@v7
with:
commit_message: "Auto-convert PLY to reduced STL"