Skip to content

Commit 1185867

Browse files
committed
Fix path escaping and label collision in batch naming
Two defects that both fail quietly rather than loudly. freecad_prepare built the FreeCAD script by hand-escaping paths into single quotes, but the apostrophe branch of that escaping was a no-op: in Python source "\'" is simply "'", so the replace swapped an apostrophe for itself. A STEP file under a path like C:\Users\Dan's Files\part.step closed the string literal early and the generated script raised a SyntaxError, which reached the user as an unexplained "FreeCAD conversion failed". Paths are now interpolated with %r, which escapes quotes and backslashes together. alpha_pair restarted at two letters after ZZ, so index 26 produced 'AA' again -- the same label as index 0. With Products per Letter set low enough to wrap, two products resolved to one output directory and the second overwrote the first's renders. The label width now grows with the wrap count, giving AA..ZZ then AAA..ZZZ. Labels AA..ZZ are unchanged, so existing output naming is unaffected.
1 parent c372a67 commit 1185867

1 file changed

Lines changed: 15 additions & 10 deletions

File tree

‎multiview_product_renderer/__init__.py‎

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -523,13 +523,16 @@ def find_layer_coll(layer_coll, name):
523523

524524

525525
def alpha_pair(idx):
526+
"""Repeated-letter group label: AA..ZZ, then AAA..ZZZ, then AAAA..
527+
528+
The letter cycles every 26 groups and the label grows a character on each
529+
wrap, so no two indices share a label. The width has to key off the wrap
530+
count -- an earlier version restarted at two letters after ZZ, which handed
531+
index 26 the same 'AA' as index 0 and pointed two products at one output
532+
folder, where the second silently overwrote the first.
533+
"""
526534
idx = max(0, idx)
527-
if idx <= 25:
528-
c = chr(ord('A') + idx)
529-
return c + c
530-
n = 2 + (idx - 26) // 26
531-
c = chr(ord('A') + ((idx - 26) % 26))
532-
return c * n
535+
return chr(ord('A') + idx % 26) * (2 + idx // 26)
533536

534537

535538
def alpha_pair_to_idx(prefix):
@@ -590,11 +593,13 @@ def freecad_prepare(step_path, freecad_exe, deflection):
590593
return None
591594
tmp_dir = tempfile.mkdtemp(prefix="mv_step_")
592595
obj_out = os.path.join(tmp_dir, os.path.splitext(os.path.basename(step_path))[0] + ".obj")
593-
quoted_step = step_path.replace("\\", "\\\\").replace("'", "\'")
594-
quoted_obj = obj_out.replace("\\", "\\\\").replace("'", "\'")
596+
# Paths go in as %r, not hand-escaped into '...'. A path holding an
597+
# apostrophe -- C:\Users\Dan's Files\part.step -- closed the string early
598+
# and the script died of a SyntaxError that surfaced as a bare "conversion
599+
# failed". repr() handles quotes, backslashes and newlines in one step.
595600
script = (
596601
"import Import, MeshPart, FreeCAD\n"
597-
"Import.open('%s')\n" % quoted_step +
602+
"Import.open(%r)\n" % step_path +
598603
"doc = FreeCAD.ActiveDocument\n"
599604
"meshes = []\n"
600605
"for obj in doc.Objects:\n"
@@ -608,7 +613,7 @@ def freecad_prepare(step_path, freecad_exe, deflection):
608613
" m = meshes[0]\n"
609614
" for extra in meshes[1:]:\n"
610615
" m.addMesh(extra)\n"
611-
" m.write('%s')\n" % quoted_obj
616+
" m.write(%r)\n" % obj_out
612617
)
613618
script_path = os.path.join(tmp_dir, "convert.py")
614619
with open(script_path, "w", encoding="utf-8") as f:

0 commit comments

Comments
 (0)