122 lines
4.0 KiB
Python
122 lines
4.0 KiB
Python
|
|
import pygarment as pyg
|
||
|
|
|
||
|
|
class BaseBodicePanel(pyg.Panel):
|
||
|
|
"""Base class for bodice panels that defines expected interfaces and common functions"""
|
||
|
|
def __init__(self, name, body, design) -> None:
|
||
|
|
super().__init__(name)
|
||
|
|
self.body = body
|
||
|
|
self.design = design
|
||
|
|
|
||
|
|
self.interfaces = {
|
||
|
|
'outside': object(),
|
||
|
|
'inside': object(),
|
||
|
|
'shoulder': object(),
|
||
|
|
'bottom': object(),
|
||
|
|
|
||
|
|
'shoulder_corner': object(),
|
||
|
|
'collar_corner': object(),
|
||
|
|
}
|
||
|
|
|
||
|
|
def get_width(self, level):
|
||
|
|
"""Return the panel width at a given level (excluding darts)
|
||
|
|
* Level is counted from the top of the panel
|
||
|
|
|
||
|
|
NOTE: for fitted bodice, the request is only valid for values between 0 and bust_level
|
||
|
|
"""
|
||
|
|
# NOTE: this evaluation assumes that the top edge width is the same as bodice shoulder width
|
||
|
|
side_edge = self.interfaces['outside'].edges[-1]
|
||
|
|
|
||
|
|
x = side_edge.end[0] - side_edge.start[0]
|
||
|
|
y = side_edge.end[1] - side_edge.start[1]
|
||
|
|
|
||
|
|
# If the orientation of the edge is "looking down"
|
||
|
|
# instead of "looking up" as calculations above expect, flip the values
|
||
|
|
if y < 0:
|
||
|
|
x, y = -x, -y
|
||
|
|
|
||
|
|
return (level * x / y) + self.body['shoulder_w'] / 2
|
||
|
|
|
||
|
|
|
||
|
|
class BaseBottoms(pyg.Component):
|
||
|
|
"""A base class for all the bottom components.
|
||
|
|
Defines common elements:
|
||
|
|
* List of interfaces
|
||
|
|
* Presence of the rise value
|
||
|
|
"""
|
||
|
|
def __init__(self, body, design, tag='', rise=None) -> None:
|
||
|
|
"""Base bottoms initialization
|
||
|
|
"""
|
||
|
|
super().__init__(
|
||
|
|
self.__class__.__name__ if not tag else f'{self.__class__.__name__}_{tag}')
|
||
|
|
|
||
|
|
self.body = body
|
||
|
|
self.design = design
|
||
|
|
self.rise = rise
|
||
|
|
|
||
|
|
# Set of interfaces that need to be implemented
|
||
|
|
self.interfaces = {
|
||
|
|
'top': object()
|
||
|
|
}
|
||
|
|
|
||
|
|
def get_rise(self):
|
||
|
|
"""Return a rise value for a given component"""
|
||
|
|
return self.rise
|
||
|
|
|
||
|
|
def eval_rise(self, rise):
|
||
|
|
"""Evaluate updated hip and waist-related measurements,
|
||
|
|
corresponding to the provided rise value
|
||
|
|
"""
|
||
|
|
waist, hips = self.body['waist'], self.body['hips']
|
||
|
|
hips_level = self.body['hips_line']
|
||
|
|
self.adj_hips_depth = rise * hips_level
|
||
|
|
self.adj_waist = pyg.utils.lin_interpolation(hips, waist, rise)
|
||
|
|
|
||
|
|
self_adj_back_waist = pyg.utils.lin_interpolation(
|
||
|
|
self.body['hip_back_width'], self.body['waist_back_width'], rise)
|
||
|
|
|
||
|
|
return self.adj_waist, self.adj_hips_depth, self_adj_back_waist
|
||
|
|
|
||
|
|
class StackableSkirtComponent(BaseBottoms):
|
||
|
|
"""
|
||
|
|
Abstract definition of a skirt that can be stacked with other stackable skirts
|
||
|
|
(connecting bottom to another StackableSkirtComponent())
|
||
|
|
"""
|
||
|
|
|
||
|
|
def __init__(self, body, design, tag='', length=None, rise=None, slit=True, top_ruffles=True) -> None:
|
||
|
|
"""Skirt initialization
|
||
|
|
|
||
|
|
Extra parameters (length, sleets, top_ruffles)
|
||
|
|
can be used to overwrite parameters in design dictionary
|
||
|
|
"""
|
||
|
|
super().__init__(body, design, tag, rise=rise)
|
||
|
|
|
||
|
|
pass
|
||
|
|
|
||
|
|
# Set of interfaces that need to be implemented
|
||
|
|
self.interfaces = {
|
||
|
|
'top': object(),
|
||
|
|
'bottom_f': object(),
|
||
|
|
'bottom_b': object(),
|
||
|
|
'bottom': object()
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
class BaseBand(pyg.Component):
|
||
|
|
def __init__(self, body, design, tag='', rise=None) -> None:
|
||
|
|
"""Base band initialization
|
||
|
|
"""
|
||
|
|
super().__init__(
|
||
|
|
self.__class__.__name__ if not tag else f'{self.__class__.__name__}_{tag}')
|
||
|
|
self.body = body
|
||
|
|
self.design = design
|
||
|
|
self.rise = rise
|
||
|
|
|
||
|
|
# Set of interfaces that need to be implemented
|
||
|
|
self.interfaces = {
|
||
|
|
'top': object(),
|
||
|
|
'bottom': object()
|
||
|
|
}
|
||
|
|
|
||
|
|
def length(self):
|
||
|
|
"""Base length == Length of a first panel"""
|
||
|
|
return self._get_subcomponents()[0].length()
|