88 lines
4.0 KiB
Python
88 lines
4.0 KiB
Python
|
|
# Seam-flag sweep for the top (topTest1 / pari). Diagnostic, exports nothing.
|
||
|
|
#
|
||
|
|
# python tools/md_bridge.py --file tools/tailor/md_pari_seamsweep.py --timeout 880
|
||
|
|
#
|
||
|
|
# WHY: the untextured back render shows the back panel rucked up with its REVERSE
|
||
|
|
# FACE exposed. Reverse faces mean the seam is twisting the panel, not that there is
|
||
|
|
# surplus cloth — so the fix is the seam pairing, not the pattern.
|
||
|
|
#
|
||
|
|
# md_pari.py sews same-index with (False, False). The skill's rule is "pair the same
|
||
|
|
# line index on MIRRORED front/back panels with (False, False)" — but these panels
|
||
|
|
# are NOT mirrored: both are the identical point list, only offset by dx. Sewing
|
||
|
|
# front-right to back-right on non-mirrored panels needs one edge traversed in
|
||
|
|
# REVERSE, which is what the two booleans do. md_piupiu_v3.py sidesteps this by
|
||
|
|
# pairing right<->left, which is equivalent to a reversal — and it drapes clean.
|
||
|
|
#
|
||
|
|
# Sweeps the two flags on the SIDE seams only, keeping shoulders at (False, False)
|
||
|
|
# since the front and shoulder line look correct. Also tested separately and
|
||
|
|
# DISPROVED: crossing every pair (7<->9 AND 0<->5) makes the garment slide to the
|
||
|
|
# hips, because cross-wired straps cancel and it falls off the shoulders.
|
||
|
|
#
|
||
|
|
# 4 combos x Simulate(200) ~= 3 min. Reads back the turntable rear frame per combo.
|
||
|
|
import os
|
||
|
|
import shutil
|
||
|
|
import tempfile
|
||
|
|
|
||
|
|
AVATAR_FBX = r"C:\Users\Jeremy\tinqs\animation\tools\tailor\avatar\Lena_QuatSkin_Avatar.fbx"
|
||
|
|
ZFAB = r"C:\Users\Public\Documents\MarvelousDesigner\New Assets\Fabric\(Default for Simulation).zfab"
|
||
|
|
|
||
|
|
W_FRONT, W_BACK = 570.0, 510.0
|
||
|
|
TOP, TOP_BACK = 350.0, 350.0 # both full height — isolate the seam flags
|
||
|
|
SCOOP_FRONT, SCOOP_BACK = 105.0, 45.0
|
||
|
|
SIDE_Y = 185.0
|
||
|
|
COMBOS = [(False, False), (False, True), (True, False), (True, True)]
|
||
|
|
|
||
|
|
report = {"combos": {}}
|
||
|
|
|
||
|
|
def panel(width, scoop, dx, top):
|
||
|
|
c = width / 2.0
|
||
|
|
pts = [(c - 210.0, top - 25.0), (c - 120.0, top),
|
||
|
|
(c - 70.0, top - scoop * 0.75), (c, top - scoop),
|
||
|
|
(c + 70.0, top - scoop * 0.75), (c + 120.0, top), (c + 210.0, top - 25.0),
|
||
|
|
(width, SIDE_Y), (width, 0.0), (0.0, 0.0), (0.0, SIDE_Y)]
|
||
|
|
return pattern_api.CreatePatternWithPoints([(x + dx, y, 0) for (x, y) in pts])
|
||
|
|
|
||
|
|
for fa, fb in COMBOS:
|
||
|
|
key = "%s_%s" % (int(fa), int(fb))
|
||
|
|
utility_api.NewProject() # also deletes the avatar
|
||
|
|
op = ApiTypes.ImportExportOption()
|
||
|
|
op.scale = 10.0
|
||
|
|
op.bAddArrangementPoints = True
|
||
|
|
op.bAutoTranslate = True
|
||
|
|
import_api.ImportFBX(AVATAR_FBX, op)
|
||
|
|
|
||
|
|
pf = panel(W_FRONT, SCOOP_FRONT, 0.0, TOP)
|
||
|
|
pb = panel(W_BACK, SCOOP_BACK, 900.0, TOP_BACK)
|
||
|
|
|
||
|
|
for line in (0, 5): # shoulders: leave alone
|
||
|
|
pattern_api.AddSeamlinePairGroup(pf, line, pb, line, False, False)
|
||
|
|
for line in (7, 9): # sides: the variable under test
|
||
|
|
pattern_api.AddSeamlinePairGroup(pf, line, pb, line, fa, fb)
|
||
|
|
|
||
|
|
fab = fabric_api.AddFabric(ZFAB) # PLAIN — judge shape, not motif
|
||
|
|
for p in (pf, pb):
|
||
|
|
pattern_api.SetPatternPieceFabricIndex(p, fab)
|
||
|
|
|
||
|
|
arr = {a["ArrangementName"]: int(a["ArrangementIndex"])
|
||
|
|
for a in pattern_api.GetArrangementList()}
|
||
|
|
pattern_api.SetArrangement(pf, arr["Body_Front_Center_1"])
|
||
|
|
pattern_api.SetArrangement(pb, arr["Body_Back_Center_1"])
|
||
|
|
pattern_api.SetArrangementPosition(pf, 50, 55, 50)
|
||
|
|
pattern_api.SetArrangementPosition(pb, 0, 55, 50)
|
||
|
|
utility_api.ResetClothArrangement()
|
||
|
|
|
||
|
|
ok = utility_api.Simulate(200)
|
||
|
|
utility_api.Refresh3DWindow()
|
||
|
|
|
||
|
|
shots = export_api.ExportTurntableImages(4) # 0 front, 1 side, 2 BACK, 3 side
|
||
|
|
saved = {}
|
||
|
|
for idx, label in ((0, "front"), (2, "back")):
|
||
|
|
if idx < len(shots) and os.path.exists(shots[idx]):
|
||
|
|
dst = os.path.join(tempfile.gettempdir(),
|
||
|
|
"tinqs_seamsweep_%s_%s.png" % (key, label))
|
||
|
|
shutil.copyfile(shots[idx], dst) # turntable reuses output*.png names
|
||
|
|
saved[label] = dst
|
||
|
|
report["combos"][key] = {"sim": ok, "flags": [fa, fb], "shots": saved}
|
||
|
|
|
||
|
|
result = report
|