Files
design2garmentcode-impl/assets/garment_programs/skirt_levels.py
2025-07-03 17:03:00 +08:00

151 lines
5.6 KiB
Python

from assets.garment_programs.circle_skirt import *
from assets.garment_programs.skirt_paneled import *
from copy import deepcopy
class SkirtLevels(BaseBottoms):
"""Skirt constiting of multuple stitched skirts"""
def __init__(self, body, design, rise=None) -> None:
super().__init__(body, design, rise=rise)
ldesign = design['levels-skirt']
lbody = deepcopy(body) # We will modify the values, so need a copy
n_levels = ldesign['num_levels']['v']
ruffle = ldesign['level_ruffle']['v']
# Adjust length to the common denominators
self.eval_length(ldesign, body)
# Definitions
self.rise = ldesign['rise']['v'] if rise is None else rise
base_skirt_class = globals()[ldesign['base']['v']]
self.subs.append(base_skirt_class(
body,
design,
length=self.base_len,
rise=self.rise,
slit=False))
if (hasattr(base := self.subs[0], 'design')
and 'low_angle' in base.design):
self.angle = base.design['low_angle']['v']
else:
self.angle = 0
# Place the levels
level_skirt_class = globals()[ldesign['level']['v']]
for i in range(n_levels):
# Adjust the mesurement to trick skirts into producing correct width
# TODOLOW More elegant overwrite
lbody['waist'] = ruffle * self.subs[-1].interfaces['bottom'].edges.length()
lbody['waist_back_width'] = ruffle * self.subs[-1].interfaces['bottom_b'].edges.length()
self.subs.append(level_skirt_class(
lbody,
design,
tag=str(i),
length=self.level_len,
slit=False,
top_ruffles=False))
# Placement
# Rotation if base is assymetric
self.subs[-1].rotate_by(R.from_euler(
'XYZ', [0, 0, -self.angle], degrees=True))
self.subs[-1].place_by_interface(
self.subs[-1].interfaces['top'],
self.subs[-2].interfaces['bottom'],
gap=5
)
# Stitch
self.stitching_rules.append((
self.subs[-2].interfaces['bottom'],
self.subs[-1].interfaces['top']
))
self.interfaces = {
'top': self.subs[0].interfaces['top']
}
def eval_length(self, ldesign, body):
# With convertion to absolute values
total_length = ldesign['length']['v'] * body['_leg_length']
self.base_len = total_length * ldesign['base_length_frac']['v']
self.level_len = (total_length - self.base_len) / ldesign['num_levels']['v']
# Add hip_line (== zero length)
self.base_len = body['hips_line'] * ldesign['rise']['v'] + self.base_len
class SkirtLayers(BaseBottoms):
"""Skirt consisting of multiple layered skirts stitched at the waistline"""
def __init__(self, body, design, rise=None):
super().__init__(body, design, rise=rise)
ldesign = design['layers-skirt']
lbody = deepcopy(body) # We will modify the values, so need a copy
n_layers = ldesign['num_layers']['v']
ruffle = ldesign['layer_ruffle']['v']
# Definitions
self.rise = ldesign['rise']['v'] if rise is None else rise
base_skirt_class = globals()[ldesign['base']['v']]
total_length = ldesign['length']['v'] * body['_leg_length']
layer_lengths = self.eval_layer_lengths(ldesign, total_length, n_layers)
# Place the levels
self.layers = []
for i in range(n_layers):
# Adjust the measurements to produce correct width with ruffle
waist_multiplier = 1 + ruffle * i
lbody['waist'] = self.body['waist'] * waist_multiplier
lbody['waist_back_width'] = self.body['waist_back_width'] * waist_multiplier
layer_length = layer_lengths[i]
skirt_layer = base_skirt_class(
lbody,
design,
tag=str(i),
length=layer_length,
rise=self.rise,
slit=False,
top_ruffles=False)
# Place the layer at the waistline
skirt_layer.translate_by([0, self.body['_waist_level'], 0])
self.layers.append(skirt_layer)
# Interfaces
self.interfaces = {
'top': self.layers[0].interfaces['top'],
'bottom': self.layers[-1].interfaces['bottom']
}
# Stitching rules: stitch each outer layer's top interface
# to the 'top' interface of the component (waistline)
for layer in self.layers[1:]:
self.stitching_rules.append(
(self.interfaces['top'], layer.interfaces['top'])
)
# Add layers to subcomponents
self.subs.extend(self.layers)
for id,layer in enumerate(self.layers):
layer.front.translate_by([0,0, 5*id])
layer.back.translate_by([0, 0, -5*id])
def eval_layer_lengths(self, ldesign, total_length, n_layers):
"""Calculate lengths for each layer"""
if 'layer_lengths' in ldesign:
# If specific lengths are provided for each layer
layer_lengths = [ldesign['layer_lengths'][i]['v'] * total_length for i in range(n_layers)]
else:
# Distribute the total length among layers, possibly making outer layers longer
base_length = total_length / n_layers
layer_lengths = [base_length * (1 + 0.1 * i) for i in range(n_layers)]
return layer_lengths