fusion: purge meshes/ folder prima di ogni export

Aggiunto _purge_meshes_dir() chiamato all inizio di export_meshes_and_hierarchy. Cancella .obj/.stl/.mtl residui di export precedenti (component rinominati o rimossi dal modello Fusion) che altrimenti rimanevano come orfani nella cartella di output e venivano potenzialmente caricati dal viewer come nodi vuoti. Conteggio in stats.purged_stale, mostrato nel messageBox finale di entrambi gli script (plotter + ATL).
This commit is contained in:
marco
2026-06-23 15:47:45 +02:00
parent bbdeb39ab0
commit 27def99a99
2 changed files with 52 additions and 13 deletions
+45 -7
View File
@@ -1558,10 +1558,40 @@ def _export_component_mesh(export_mgr, component, filepath_noext):
return (None, None)
def _purge_meshes_dir(meshes_dir):
"""Rimuove tutti i file di mesh residui in `meshes_dir`.
Tiene la cartella ma cancella .obj / .stl / .mtl. Cosi' i residui di
export precedenti (component rinominati o rimossi dal modello Fusion)
non rimangono come "orfani" nella cartella di output.
Ritorna il numero di file cancellati. Cartella inesistente -> 0.
"""
if not os.path.isdir(meshes_dir):
return 0
removed = 0
try:
for fname in os.listdir(meshes_dir):
low = fname.lower()
if not (low.endswith('.obj') or low.endswith('.stl') or low.endswith('.mtl')):
continue
try:
os.remove(os.path.join(meshes_dir, fname))
removed += 1
except Exception:
continue
except Exception:
pass
return removed
def export_meshes_and_hierarchy(design, root_comp, out_dir):
"""Esporta le mesh dei component (deduplicato) + costruisce la gerarchia.
Workflow:
* Pulisce eventuali file mesh residui in `out_dir/meshes/` (orfani
di export precedenti, es. component rinominati o rimossi dal
modello Fusion).
* Scorre tutte le occurrences visibili (lightBulbOn + non suppressed).
* Per ogni occurrence, se il suo Component contiene bodies e non e'
ancora stato esportato, esporta `meshes/<safe>.obj` (o .stl in
@@ -1574,13 +1604,19 @@ def export_meshes_and_hierarchy(design, root_comp, out_dir):
"""
meshes_dir = os.path.join(out_dir, 'meshes')
os.makedirs(meshes_dir, exist_ok=True)
purged = _purge_meshes_dir(meshes_dir)
em = design.exportManager
nodes = []
# comp.id -> path relativo del meshFile gia' esportato (per dedup).
component_to_meshfile = {}
used_filenames = set()
stats = {'exported_meshes': 0, 'failed_meshes': 0, 'skipped_invisible': 0}
stats = {
'exported_meshes': 0,
'failed_meshes': 0,
'skipped_invisible': 0,
'purged_stale': purged,
}
def _maybe_export_component_mesh(comp):
"""Esporta la mesh del component se non gia' fatto. Ritorna path o None."""
@@ -1862,16 +1898,18 @@ def run(context):
'Nodi gerarchia: {1}\n'
'Mesh esportate: {2}\n'
'Mesh fallite: {3}\n'
'Occurrences invisibili/suppresse: {4}\n'
'Occurrences escluse da filtro nome: {5}\n\n'
'Joints: {6}\n'
'As-Built Joints: {7}\n'
'Motion Links: {8}\n'
'Rigid Groups: {9}'.format(
'Mesh stale rimosse: {4}\n'
'Occurrences invisibili/suppresse: {5}\n'
'Occurrences escluse da filtro nome: {6}\n\n'
'Joints: {7}\n'
'As-Built Joints: {8}\n'
'Motion Links: {9}\n'
'Rigid Groups: {10}'.format(
out_dir,
len(nodes),
mesh_stats['exported_meshes'],
mesh_stats['failed_meshes'],
mesh_stats.get('purged_stale', 0),
mesh_stats['skipped_invisible'],
mesh_stats.get('skipped_excluded', 0),
len(joints_payload['joints']),