qbhf2 commited on
Commit
66c9c8a
·
1 Parent(s): 2b40ca6

added NvidiaWarp and GarmentCode repos

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. GarmentCode/.gitignore +33 -0
  2. GarmentCode/CHANGELOG.md +36 -0
  3. GarmentCode/LICENSE +21 -0
  4. GarmentCode/ReadMe.md +100 -0
  5. GarmentCode/assets/Patterns/dress_pencil_specification.json +1161 -0
  6. GarmentCode/assets/Patterns/hoody_mean_specification.json +732 -0
  7. GarmentCode/assets/Patterns/js_mean_all_specification.json +2505 -0
  8. GarmentCode/assets/Patterns/shirt_mean_specification.json +1058 -0
  9. GarmentCode/assets/Sim_props/default_sim_props.yaml +92 -0
  10. GarmentCode/assets/Sim_props/gui_sim_props.yaml +93 -0
  11. GarmentCode/assets/Sim_props/mid_bending.yaml +92 -0
  12. GarmentCode/assets/Sim_props/minimal_bending.yaml +92 -0
  13. GarmentCode/assets/Sim_props/soft_flexy_ochra 30s.json +75 -0
  14. GarmentCode/assets/Sim_props/soft_ochra.json +75 -0
  15. GarmentCode/assets/Sim_props/stiff_ochra.json +75 -0
  16. GarmentCode/assets/bodies/Readme.md +7 -0
  17. GarmentCode/assets/bodies/body_params.py +39 -0
  18. GarmentCode/assets/bodies/f_smpl_average_A40.obj +3 -0
  19. GarmentCode/assets/bodies/f_smpl_average_A40.yaml +35 -0
  20. GarmentCode/assets/bodies/ggg_body_segmentation.json +0 -0
  21. GarmentCode/assets/bodies/m_smpl_average_A40.obj +3 -0
  22. GarmentCode/assets/bodies/m_smpl_average_A40.yaml +26 -0
  23. GarmentCode/assets/bodies/mean_all.obj +3 -0
  24. GarmentCode/assets/bodies/mean_all.stl +3 -0
  25. GarmentCode/assets/bodies/mean_all.yaml +27 -0
  26. GarmentCode/assets/bodies/mean_all_apart.obj +3 -0
  27. GarmentCode/assets/bodies/mean_all_tpose.obj +3 -0
  28. GarmentCode/assets/bodies/mean_all_tpose.yaml +27 -0
  29. GarmentCode/assets/bodies/mean_female.obj +3 -0
  30. GarmentCode/assets/bodies/mean_female.yaml +27 -0
  31. GarmentCode/assets/bodies/mean_male.obj +3 -0
  32. GarmentCode/assets/bodies/mean_male.yaml +27 -0
  33. GarmentCode/assets/bodies/smpl_vert_segmentation.json +0 -0
  34. GarmentCode/assets/design_params/default.yaml +885 -0
  35. GarmentCode/assets/design_params/t-shirt.yaml +885 -0
  36. GarmentCode/assets/garment_programs/bands.py +262 -0
  37. GarmentCode/assets/garment_programs/base_classes.py +122 -0
  38. GarmentCode/assets/garment_programs/bodice.py +491 -0
  39. GarmentCode/assets/garment_programs/circle_skirt.py +234 -0
  40. GarmentCode/assets/garment_programs/collars.py +370 -0
  41. GarmentCode/assets/garment_programs/godet.py +121 -0
  42. GarmentCode/assets/garment_programs/meta_garment.py +123 -0
  43. GarmentCode/assets/garment_programs/pants.py +312 -0
  44. GarmentCode/assets/garment_programs/shapes.py +64 -0
  45. GarmentCode/assets/garment_programs/skirt_levels.py +80 -0
  46. GarmentCode/assets/garment_programs/skirt_paneled.py +512 -0
  47. GarmentCode/assets/garment_programs/sleeves.py +364 -0
  48. GarmentCode/assets/garment_programs/stats_utils.py +150 -0
  49. GarmentCode/assets/garment_programs/tee.py +116 -0
  50. GarmentCode/assets/img/err_dress_20s.png +3 -0
GarmentCode/.gitignore ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Jupyter tmp files
2
+ .ipynb_checkpoints
3
+
4
+ # VSCode settings
5
+ *.code-workspace
6
+ .vscode
7
+ __pycache__
8
+
9
+ # PyCharm
10
+ .idea
11
+
12
+ # Compiled files
13
+ *.pyc
14
+ dist
15
+ *egg-info*
16
+
17
+ # Maya
18
+ .mayaSwatches
19
+
20
+ # custom settings -- to have customized local copy
21
+ system.json
22
+
23
+ # place to store render scenes
24
+ **/data_generation/Scenes
25
+
26
+ # file for small script tries
27
+ tmp*
28
+ *tmp*.mb
29
+ Logs*
30
+ output*
31
+
32
+ # Nicegui
33
+ .nicegui
GarmentCode/CHANGELOG.md ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ # Change Log
3
+
4
+ ## [2.0.1] - 2024-09-12
5
+
6
+ ### Fixed
7
+ - Allow disabling frame timeout in simulation through setting `None` (`null` in `.yaml`) as `max_frame_time` config value. This fixes #15.
8
+ - Fix erroneous duplication of frame timeout value for all frames. Timeout is only prolonged for the first frame -- initialization requires more time compared to the following frames. Sim property files are updated to reproduce earlier behavior with erroneous timeout duplication
9
+
10
+ ## [2.0.0] - 2024-08-30
11
+
12
+ Major update with release of [GarmentCodeData](https://igl.ethz.ch/projects/GarmentCodeData/), new GUI, and a number of other improvements and library changes. For technical details, see our papers.
13
+
14
+
15
+ ### Added
16
+ - **[Mesh generation]** GarmentCode library can now generate box meshes for the sewing patterns.
17
+ - **[Simulation]** We integrated our version of [NVIDIA warp](https://github.com/maria-korosteleva/NvidiaWarp-GarmentCode) to support simulation of GarmentCode sewing patterns. It can be run from command line and from GUI.
18
+ - **[Desing Sampling]** We support random sampling of sewing pattern designs from the designs spaces. Sampling can be controlled though setting probabilities of sampling default values.
19
+ - **[Generating synthetic 3D data]** Combining the new capabilities allows for creating diverse synthetic datasets of 3D garments. We provide high-level scripts to create such datasets from the GarmentCode-provided garment programs.
20
+ - **[Labeling]** We added support for assigning labels to pattern elements (edges and panels) in both GarmentCode objects and JSON serialized pattern representation. These are currently utilized to guide the cloth simulation process, but can be assigned to enrich the data labeling.
21
+ - **[Stitch orientation]** GarmentCode now allows explicit specification of whether a stitch should be connecting the right side of the fabric on one side to the right side of the fabric on the other or right side to wrong side. It gives explicit control to developer on resolving the stitching direction. Most stitches require the default (right-to-right) setting, hence only a few need explicit update of this parameter. Internally, the right-to-right direction is found following the manifold property of connecting two panels with specified normal direction indicating the right side of the fabric.
22
+
23
+ ### Changed
24
+ - **[Architecture]** We updated the structure of `pygarment` library. It now includes new mesh generation and cloth simulation routines, as well as the pattern serialization modules (`pattern` library) and the Maya + Qualoth routines for backward compatibility. This greatly simplifies the installation process and reduces module import issues.
25
+ - **[GUI]** We re-wrote our GUI from PySimpleGUI to NiceGUI following the change in PySimpleGUI licensing scheme and desire for better UI look. GarmentCode GUI now runs in browser. Dependency on PySimpleGUI is removed.
26
+ - **[Interface matching]** In addition to stitch orientation labels above, we removed extra heuristics involved in the matching of the edges in two interfaces connected by a stitch. We found that these heuristics behaved unintuitively in some cases, and it was difficult to determine the correct way to fix erroneous matched. The process is now fully controlled by the developer, making it more intuitive. As before, the default matching process should work in most cases, and only a few complex stitches require intervention.
27
+
28
+ ### Fixed
29
+ - **[Sewing patterns quality]** We have made numerous improvements to the quality of sewing patterns produced by our garment programs. They now showcase better fit, balance and 3D alignment
30
+ - **[Design space]** We have updated the quality of the parameter interaction in our garment programs introducing better parameter ranges, parameter dependencies, interaction between design and body shape parameters, etc. Design space now has fewer invalid parameter combinations making the exploration of parameter space more reliable.
31
+ - **[Other]** numerous small bugs where discovered and fixed.
32
+
33
+
34
+ ## [1.0.0] - 2023-10-18
35
+
36
+ Initial release -- implementation of [GarmentCode](https://igl.ethz.ch/projects/garmentcode/)
GarmentCode/LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Maria Korosteleva
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
GarmentCode/ReadMe.md ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # GarmentCode: Programming Parametric Sewing Patterns
2
+
3
+ ![Examples of garments sampled from GarmentCode configurator](https://github.com/maria-korosteleva/GarmentCode/raw/main/assets/img/header.png)
4
+
5
+ Official Implementation of [GarmentCode: Programming Parametric Sewing Patterns](https://igl.ethz.ch/projects/garmentcode/) and [GarmentCodeData: A Dataset of 3D Made-to-Measure Garments With Sewing Patterns](https://igl.ethz.ch/projects/GarmentCodeData/).
6
+
7
+ > You can find the body measurements part of the project here: https://github.com/mbotsch/GarmentMeasurements
8
+
9
+ ## News
10
+
11
+ **[Nov 20, 2024]** GarmentCode configurator demo is now ONLINE 🥳 Check it out: https://garmentcode.ethz.ch/ (not for mobile)
12
+
13
+ **[Sept 4, 2024]** We release a new version of the dataset with a few fixes and updates: [GarmentCodeData (v2)](https://doi.org/10.3929/ethz-b-000690432). See documentation for new data version for more details.
14
+
15
+ **[Aug 30, 2024]** Major release -- implementation of [GarmentCodeData](https://igl.ethz.ch/projects/GarmentCodeData/) in `pygarment v2.0.0`, new GUI, and other updates and improvements. Basic JSON representation classes are now part of PyGarment library! See CHANGELOG for more details
16
+
17
+ **[July 1, 2024]** [GarmentCodeData](https://igl.ethz.ch/projects/GarmentCodeData/) is accepted to ECCV!
18
+
19
+ **[May 29, 2024]** First release of [GarmentCodeData](https://doi.org/10.3929/ethz-b-000673889) dataset!
20
+
21
+ **[Oct 18, 2023]** First release of GarmentCode!
22
+
23
+ ## Documents
24
+
25
+ 1. [Installation](https://github.com/maria-korosteleva/GarmentCode/blob/main/docs/Installation.md)
26
+ 2. [Running Configurator](https://github.com/maria-korosteleva/GarmentCode/blob/main/docs/Running_garmentcode.md)
27
+ 3. [Running Data Generation (warp)](https://github.com/maria-korosteleva/GarmentCode/blob/main/docs/Running_data_generation.md)
28
+ 3. [Body measurements](https://github.com/maria-korosteleva/GarmentCode/blob/main/docs/Body%20Measurements%20GarmentCode.pdf)
29
+ 4. [Dataset documentation](https://www.research-collection.ethz.ch/handle/20.500.11850/673889)
30
+ 3. [Running Old Maya+Qualoth tools](https://github.com/maria-korosteleva/GarmentCode/blob/main/docs/Running_Maya_Qualoth.md)
31
+
32
+ ## Navigation
33
+
34
+ ### Library
35
+
36
+ [PyGarment](https://github.com/maria-korosteleva/GarmentCode/tree/main/pygarment) is the core library described in the GarmentCode paper. It contains the base types (Edge, Panel, Component, Interface, etc.), as well as edge factory and various helpers and operators that help you design sewing patterns.
37
+
38
+ See [Installation instructions](https://github.com/maria-korosteleva/GarmentCode/tree/main/docs/Installation.md) before use.
39
+
40
+ ### Examples
41
+
42
+ * [assets/garment_programs/](https://github.com/maria-korosteleva/GarmentCode/tree/main/assets/garment_programs/) contains the code of garment components designed using PyGarment.
43
+ * [assets/design_params/](https://github.com/maria-korosteleva/GarmentCode/tree/main/assets/design_params/), [assets/bodies/](https://github.com/maria-korosteleva/GarmentCode/tree/main/assets/bodies/) contain examples of design and body measurements presets. They can be used in both GarmentCode GUI and `test_garmentcode.py` script.
44
+
45
+ > NOTE: [assets/design_params/default.yaml](https://github.com/maria-korosteleva/GarmentCode/blob/main/assets/design_params/default.yaml) is the setup used by GUI on load. Changing this file results in changes in the GUI initial state =)
46
+
47
+
48
+ ## Citation
49
+
50
+ If you are using our system in your research, please cite our papers:
51
+
52
+ ```bibtex
53
+ @inproceedings{GarmentCodeData:2024,
54
+ author = {Korosteleva, Maria and Kesdogan, Timur Levent and Kemper, Fabian and Wenninger, Stephan and Koller, Jasmin and Zhang, Yuhan and Botsch, Mario and Sorkine-Hornung, Olga},
55
+ title = {{GarmentCodeData}: A Dataset of 3{D} Made-to-Measure Garments With Sewing Patterns},
56
+ booktitle={Computer Vision -- ECCV 2024},
57
+ year = {2024},
58
+ keywords = {sewing patterns, garment reconstruction, dataset},
59
+ }
60
+ ```
61
+
62
+ ```bibtex
63
+ @article{GarmentCode2023,
64
+ author = {Korosteleva, Maria and Sorkine-Hornung, Olga},
65
+ title = {{GarmentCode}: Programming Parametric Sewing Patterns},
66
+ year = {2023},
67
+ issue_date = {December 2023},
68
+ publisher = {Association for Computing Machinery},
69
+ address = {New York, NY, USA},
70
+ volume = {42},
71
+ number = {6},
72
+ doi = {10.1145/3618351},
73
+ journal = {ACM Transaction on Graphics},
74
+ note = {SIGGRAPH ASIA 2023 issue},
75
+ numpages = {16},
76
+ keywords = {sewing patterns, garment modeling}
77
+ }
78
+ ```
79
+
80
+ ## Issues, questions, suggestions
81
+
82
+ Please post your issues and questions to [GitHub Issues](https://github.com/maria-korosteleva/GarmentCode/issues).
83
+
84
+ For other requests you can find my info on https://korosteleva.com/.
85
+
86
+ ## Contributors
87
+
88
+ This project is brought to life by these people:
89
+
90
+ * [Maria Korosteleva](https://github.com/maria-korosteleva)
91
+ * [Jasmin Koller](https://github.com/JasminKoller)
92
+ * [Yuhan Zhang](https://github.com/yuhan-zh)
93
+ * [Yuhan Liu](https://github.com/yuhanliu-tech)
94
+ * [Ami Beuret](https://github.com/amibeuret)
95
+ * [Olga Sorkine-Hornung](https://igl.ethz.ch/people/sorkine/index.php)
96
+
97
+ The body measurements team developed [GarmentMeasurements](https://github.com/mbotsch/GarmentMeasurements):
98
+ * [Fabian Kemper](https://github.com/fabiankemper)
99
+ * [Stephan Wenninger](https://github.com/stephan-wenninger)
100
+ * [Mario Botsch](https://github.com/mbotsch)
GarmentCode/assets/Patterns/dress_pencil_specification.json ADDED
@@ -0,0 +1,1161 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "pattern": {
3
+ "panels": {
4
+ "skirt_back": {
5
+ "translation": [
6
+ -24.824900000000003,
7
+ 11.333059991041225,
8
+ -20.0
9
+ ],
10
+ "rotation": [
11
+ 0.0,
12
+ 0.0,
13
+ 0.0
14
+ ],
15
+ "vertices": [
16
+ [
17
+ -0.4130500000000019,
18
+ 0.0
19
+ ],
20
+ [
21
+ -1.7334539024861542,
22
+ 17.04131618994797
23
+ ],
24
+ [
25
+ -3,
26
+ 42.644400000000005
27
+ ],
28
+ [
29
+ -0.8720071770690723,
30
+ 67.30228500000001
31
+ ],
32
+ [
33
+ 7.299518077285981,
34
+ 67.30228500000001
35
+ ],
36
+ [
37
+ 8.728507371553249,
38
+ 48.33423948376196
39
+ ],
40
+ [
41
+ 10.157496665820517,
42
+ 67.30228500000001
43
+ ],
44
+ [
45
+ 14.716046605358555,
46
+ 67.30228500000001
47
+ ],
48
+ [
49
+ 16.145035899625825,
50
+ 46.21531831899609
51
+ ],
52
+ [
53
+ 17.574025193893092,
54
+ 67.30228500000001
55
+ ],
56
+ [
57
+ 24.979559436732718,
58
+ 67.30228500000001
59
+ ],
60
+ [
61
+ 31.249675173371372,
62
+ 67.30228500000001
63
+ ],
64
+ [
65
+ 32.67866446763864,
66
+ 46.21531831899609
67
+ ],
68
+ [
69
+ 34.10765376190591,
70
+ 67.30228500000001
71
+ ],
72
+ [
73
+ 38.66620363029078,
74
+ 67.30228500000001
75
+ ],
76
+ [
77
+ 40.09519292455805,
78
+ 48.33423948376196
79
+ ],
80
+ [
81
+ 41.52418221882532,
82
+ 67.30228500000001
83
+ ],
84
+ [
85
+ 49.695707177069075,
86
+ 67.30228500000001
87
+ ],
88
+ [
89
+ 51.8237,
90
+ 42.644400000000005
91
+ ],
92
+ [
93
+ 50.55715389441775,
94
+ 17.041316190455504
95
+ ],
96
+ [
97
+ 49.23675,
98
+ 0.0
99
+ ]
100
+ ],
101
+ "edges": [
102
+ {
103
+ "endpoints": [
104
+ 0,
105
+ 1
106
+ ],
107
+ "curvature": {
108
+ "type": "quadratic",
109
+ "params": [
110
+ [
111
+ 0.553542823166636,
112
+ 0.0026959050473747332
113
+ ]
114
+ ]
115
+ }
116
+ },
117
+ {
118
+ "endpoints": [
119
+ 1,
120
+ 2
121
+ ],
122
+ "curvature": {
123
+ "type": "quadratic",
124
+ "params": [
125
+ [
126
+ 0.6934856449693695,
127
+ 0.015163006851581376
128
+ ]
129
+ ]
130
+ }
131
+ },
132
+ {
133
+ "endpoints": [
134
+ 2,
135
+ 3
136
+ ],
137
+ "curvature": {
138
+ "type": "quadratic",
139
+ "params": [
140
+ [
141
+ 0.49804539625739797,
142
+ 0.04298166013440281
143
+ ]
144
+ ]
145
+ }
146
+ },
147
+ {
148
+ "endpoints": [
149
+ 3,
150
+ 4
151
+ ],
152
+ "label": "lower_interface"
153
+ },
154
+ {
155
+ "endpoints": [
156
+ 4,
157
+ 5
158
+ ]
159
+ },
160
+ {
161
+ "endpoints": [
162
+ 5,
163
+ 6
164
+ ]
165
+ },
166
+ {
167
+ "endpoints": [
168
+ 6,
169
+ 7
170
+ ],
171
+ "label": "lower_interface"
172
+ },
173
+ {
174
+ "endpoints": [
175
+ 7,
176
+ 8
177
+ ]
178
+ },
179
+ {
180
+ "endpoints": [
181
+ 8,
182
+ 9
183
+ ]
184
+ },
185
+ {
186
+ "endpoints": [
187
+ 9,
188
+ 10
189
+ ],
190
+ "label": "lower_interface"
191
+ },
192
+ {
193
+ "endpoints": [
194
+ 10,
195
+ 11
196
+ ],
197
+ "label": "lower_interface"
198
+ },
199
+ {
200
+ "endpoints": [
201
+ 11,
202
+ 12
203
+ ]
204
+ },
205
+ {
206
+ "endpoints": [
207
+ 12,
208
+ 13
209
+ ]
210
+ },
211
+ {
212
+ "endpoints": [
213
+ 13,
214
+ 14
215
+ ],
216
+ "label": "lower_interface"
217
+ },
218
+ {
219
+ "endpoints": [
220
+ 14,
221
+ 15
222
+ ]
223
+ },
224
+ {
225
+ "endpoints": [
226
+ 15,
227
+ 16
228
+ ]
229
+ },
230
+ {
231
+ "endpoints": [
232
+ 16,
233
+ 17
234
+ ],
235
+ "label": "lower_interface"
236
+ },
237
+ {
238
+ "endpoints": [
239
+ 17,
240
+ 18
241
+ ],
242
+ "curvature": {
243
+ "type": "quadratic",
244
+ "params": [
245
+ [
246
+ 0.5019546014244243,
247
+ 0.04298166025796645
248
+ ]
249
+ ]
250
+ }
251
+ },
252
+ {
253
+ "endpoints": [
254
+ 18,
255
+ 19
256
+ ],
257
+ "curvature": {
258
+ "type": "quadratic",
259
+ "params": [
260
+ [
261
+ 0.30651434782492415,
262
+ 0.015163006659112958
263
+ ]
264
+ ]
265
+ }
266
+ },
267
+ {
268
+ "endpoints": [
269
+ 19,
270
+ 20
271
+ ],
272
+ "curvature": {
273
+ "type": "quadratic",
274
+ "params": [
275
+ [
276
+ 0.44645717612825436,
277
+ 0.002695904916413496
278
+ ]
279
+ ]
280
+ }
281
+ },
282
+ {
283
+ "endpoints": [
284
+ 20,
285
+ 0
286
+ ]
287
+ }
288
+ ],
289
+ "label": "leg"
290
+ },
291
+ "skirt_front": {
292
+ "translation": [
293
+ -21.824900000000003,
294
+ 12.333059991041225,
295
+ 25.0
296
+ ],
297
+ "rotation": [
298
+ 0.0,
299
+ 0.0,
300
+ 0.0
301
+ ],
302
+ "vertices": [
303
+ [
304
+ -0.4130500000000019,
305
+ 0.0
306
+ ],
307
+ [
308
+ 43.06734999999999,
309
+ 0.0
310
+ ],
311
+ [
312
+ 44.38775389441775,
313
+ 17.041316190455504
314
+ ],
315
+ [
316
+ 45.65429999999999,
317
+ 42.644400000000005
318
+ ],
319
+ [
320
+ 43.92614999999999,
321
+ 66.1281
322
+ ],
323
+ [
324
+ 42.79073112653457,
325
+ 66.1281
326
+ ],
327
+ [
328
+ 20.759440563267283,
329
+ 66.1281
330
+ ],
331
+ [
332
+ -1.2718500000000006,
333
+ 66.1281
334
+ ],
335
+ [
336
+ -3,
337
+ 42.644400000000005
338
+ ],
339
+ [
340
+ -1.7334539024861542,
341
+ 17.04131618994797
342
+ ]
343
+ ],
344
+ "edges": [
345
+ {
346
+ "endpoints": [
347
+ 0,
348
+ 1
349
+ ]
350
+ },
351
+ {
352
+ "endpoints": [
353
+ 1,
354
+ 2
355
+ ],
356
+ "curvature": {
357
+ "type": "quadratic",
358
+ "params": [
359
+ [
360
+ 0.5535428238717457,
361
+ -0.002695904916413684
362
+ ]
363
+ ]
364
+ }
365
+ },
366
+ {
367
+ "endpoints": [
368
+ 2,
369
+ 3
370
+ ],
371
+ "curvature": {
372
+ "type": "quadratic",
373
+ "params": [
374
+ [
375
+ 0.6934856521750759,
376
+ -0.015163006659112872
377
+ ]
378
+ ]
379
+ }
380
+ },
381
+ {
382
+ "endpoints": [
383
+ 3,
384
+ 4
385
+ ],
386
+ "curvature": {
387
+ "type": "quadratic",
388
+ "params": [
389
+ [
390
+ 0.4985545386253931,
391
+ -0.03668751570703501
392
+ ]
393
+ ]
394
+ }
395
+ },
396
+ {
397
+ "endpoints": [
398
+ 4,
399
+ 5
400
+ ],
401
+ "label": "lower_interface"
402
+ },
403
+ {
404
+ "endpoints": [
405
+ 5,
406
+ 6
407
+ ],
408
+ "label": "lower_interface"
409
+ },
410
+ {
411
+ "endpoints": [
412
+ 6,
413
+ 7
414
+ ],
415
+ "label": "lower_interface"
416
+ },
417
+ {
418
+ "endpoints": [
419
+ 7,
420
+ 8
421
+ ],
422
+ "curvature": {
423
+ "type": "quadratic",
424
+ "params": [
425
+ [
426
+ 0.50144546248277,
427
+ -0.036687515673545716
428
+ ]
429
+ ]
430
+ }
431
+ },
432
+ {
433
+ "endpoints": [
434
+ 8,
435
+ 9
436
+ ],
437
+ "curvature": {
438
+ "type": "quadratic",
439
+ "params": [
440
+ [
441
+ 0.3065143550306305,
442
+ -0.015163006851581376
443
+ ]
444
+ ]
445
+ }
446
+ },
447
+ {
448
+ "endpoints": [
449
+ 9,
450
+ 0
451
+ ],
452
+ "curvature": {
453
+ "type": "quadratic",
454
+ "params": [
455
+ [
456
+ 0.44645717683336394,
457
+ -0.0026959050473747332
458
+ ]
459
+ ]
460
+ }
461
+ }
462
+ ],
463
+ "label": "leg"
464
+ },
465
+ "left_ftorso": {
466
+ "translation": [
467
+ 0.0,
468
+ 83.50364829637593,
469
+ 30.0
470
+ ],
471
+ "rotation": [
472
+ 0.0,
473
+ 0.0,
474
+ 0.0
475
+ ],
476
+ "vertices": [
477
+ [
478
+ 0.0,
479
+ 0.0
480
+ ],
481
+ [
482
+ 28.690530000000003,
483
+ 0.0
484
+ ],
485
+ [
486
+ 28.690530000000003,
487
+ 33.79684512687102
488
+ ],
489
+ [
490
+ 17.2284,
491
+ 55.311905126871025
492
+ ],
493
+ [
494
+ 12.8474,
495
+ 57.05334151891786
496
+ ],
497
+ [
498
+ 0.0,
499
+ 42.825634374897184
500
+ ]
501
+ ],
502
+ "edges": [
503
+ {
504
+ "endpoints": [
505
+ 0,
506
+ 1
507
+ ]
508
+ },
509
+ {
510
+ "endpoints": [
511
+ 1,
512
+ 2
513
+ ]
514
+ },
515
+ {
516
+ "endpoints": [
517
+ 2,
518
+ 3
519
+ ],
520
+ "curvature": {
521
+ "type": "cubic",
522
+ "params": [
523
+ [
524
+ 0.19999999999999996,
525
+ 0.35
526
+ ],
527
+ [
528
+ 0.5,
529
+ 0.2
530
+ ]
531
+ ]
532
+ }
533
+ },
534
+ {
535
+ "endpoints": [
536
+ 3,
537
+ 4
538
+ ]
539
+ },
540
+ {
541
+ "endpoints": [
542
+ 4,
543
+ 5
544
+ ],
545
+ "curvature": {
546
+ "type": "quadratic",
547
+ "params": [
548
+ [
549
+ 0.5,
550
+ 0.3
551
+ ]
552
+ ]
553
+ }
554
+ },
555
+ {
556
+ "endpoints": [
557
+ 5,
558
+ 0
559
+ ]
560
+ }
561
+ ],
562
+ "label": "body"
563
+ },
564
+ "left_btorso": {
565
+ "translation": [
566
+ 0.0,
567
+ 83.59285668570652,
568
+ -25.0
569
+ ],
570
+ "rotation": [
571
+ 0.0,
572
+ 0.0,
573
+ 0.0
574
+ ],
575
+ "vertices": [
576
+ [
577
+ 0.0,
578
+ 0.0
579
+ ],
580
+ [
581
+ 0.0,
582
+ 51.64782005173698
583
+ ],
584
+ [
585
+ 12.8474,
586
+ 56.96413324645448
587
+ ],
588
+ [
589
+ 17.228400000000004,
590
+ 55.22269603613863
591
+ ],
592
+ [
593
+ 26.221855,
594
+ 33.70763603613863
595
+ ],
596
+ [
597
+ 26.221855,
598
+ 0.0
599
+ ],
600
+ [
601
+ 24.743241245704578,
602
+ 0.0
603
+ ],
604
+ [
605
+ 14.101768323953378,
606
+ 0.0
607
+ ],
608
+ [
609
+ 8.16533843666146,
610
+ 0.0
611
+ ]
612
+ ],
613
+ "edges": [
614
+ {
615
+ "endpoints": [
616
+ 0,
617
+ 1
618
+ ]
619
+ },
620
+ {
621
+ "endpoints": [
622
+ 1,
623
+ 2
624
+ ],
625
+ "curvature": {
626
+ "type": "quadratic",
627
+ "params": [
628
+ [
629
+ 0.15000000000000002,
630
+ -0.1
631
+ ]
632
+ ]
633
+ }
634
+ },
635
+ {
636
+ "endpoints": [
637
+ 2,
638
+ 3
639
+ ]
640
+ },
641
+ {
642
+ "endpoints": [
643
+ 3,
644
+ 4
645
+ ],
646
+ "curvature": {
647
+ "type": "cubic",
648
+ "params": [
649
+ [
650
+ 0.5,
651
+ -0.2
652
+ ],
653
+ [
654
+ 0.8,
655
+ -0.35
656
+ ]
657
+ ]
658
+ }
659
+ },
660
+ {
661
+ "endpoints": [
662
+ 4,
663
+ 5
664
+ ]
665
+ },
666
+ {
667
+ "endpoints": [
668
+ 5,
669
+ 6
670
+ ]
671
+ },
672
+ {
673
+ "endpoints": [
674
+ 6,
675
+ 7
676
+ ]
677
+ },
678
+ {
679
+ "endpoints": [
680
+ 7,
681
+ 8
682
+ ]
683
+ },
684
+ {
685
+ "endpoints": [
686
+ 8,
687
+ 0
688
+ ]
689
+ }
690
+ ],
691
+ "label": "body"
692
+ },
693
+ "right_ftorso": {
694
+ "translation": [
695
+ 0.0,
696
+ 83.50364829637593,
697
+ 30.0
698
+ ],
699
+ "rotation": [
700
+ 0.0,
701
+ 0.0,
702
+ 0.0
703
+ ],
704
+ "vertices": [
705
+ [
706
+ 0,
707
+ 0
708
+ ],
709
+ [
710
+ 0.0,
711
+ 42.825634374897184
712
+ ],
713
+ [
714
+ -12.8474,
715
+ 57.05334151891786
716
+ ],
717
+ [
718
+ -17.2284,
719
+ 55.311905126871025
720
+ ],
721
+ [
722
+ -28.690530000000003,
723
+ 33.79684512687102
724
+ ],
725
+ [
726
+ -28.690530000000003,
727
+ 0
728
+ ]
729
+ ],
730
+ "edges": [
731
+ {
732
+ "endpoints": [
733
+ 0,
734
+ 1
735
+ ]
736
+ },
737
+ {
738
+ "endpoints": [
739
+ 1,
740
+ 2
741
+ ],
742
+ "curvature": {
743
+ "type": "quadratic",
744
+ "params": [
745
+ [
746
+ 0.5,
747
+ 0.3
748
+ ]
749
+ ]
750
+ }
751
+ },
752
+ {
753
+ "endpoints": [
754
+ 2,
755
+ 3
756
+ ]
757
+ },
758
+ {
759
+ "endpoints": [
760
+ 3,
761
+ 4
762
+ ],
763
+ "curvature": {
764
+ "type": "cubic",
765
+ "params": [
766
+ [
767
+ 0.5,
768
+ 0.2
769
+ ],
770
+ [
771
+ 0.8,
772
+ 0.35
773
+ ]
774
+ ]
775
+ }
776
+ },
777
+ {
778
+ "endpoints": [
779
+ 4,
780
+ 5
781
+ ]
782
+ },
783
+ {
784
+ "endpoints": [
785
+ 5,
786
+ 0
787
+ ]
788
+ }
789
+ ],
790
+ "label": "body"
791
+ },
792
+ "right_btorso": {
793
+ "translation": [
794
+ 0.0,
795
+ 83.59285668570652,
796
+ -25.0
797
+ ],
798
+ "rotation": [
799
+ 0.0,
800
+ 0.0,
801
+ 0.0
802
+ ],
803
+ "vertices": [
804
+ [
805
+ 0,
806
+ 0
807
+ ],
808
+ [
809
+ -9.64395171268208,
810
+ 0.0
811
+ ],
812
+ [
813
+ -15.58038169263411,
814
+ 0.0
815
+ ],
816
+ [
817
+ -26.221855,
818
+ 0
819
+ ],
820
+ [
821
+ -26.221855,
822
+ 33.70763603613863
823
+ ],
824
+ [
825
+ -17.228400000000004,
826
+ 55.22269603613863
827
+ ],
828
+ [
829
+ -12.8474,
830
+ 56.96413324645448
831
+ ],
832
+ [
833
+ 0.0,
834
+ 51.64782005173698
835
+ ]
836
+ ],
837
+ "edges": [
838
+ {
839
+ "endpoints": [
840
+ 0,
841
+ 1
842
+ ]
843
+ },
844
+ {
845
+ "endpoints": [
846
+ 1,
847
+ 2
848
+ ]
849
+ },
850
+ {
851
+ "endpoints": [
852
+ 2,
853
+ 3
854
+ ]
855
+ },
856
+ {
857
+ "endpoints": [
858
+ 3,
859
+ 4
860
+ ]
861
+ },
862
+ {
863
+ "endpoints": [
864
+ 4,
865
+ 5
866
+ ],
867
+ "curvature": {
868
+ "type": "cubic",
869
+ "params": [
870
+ [
871
+ 0.19999999999999996,
872
+ -0.35
873
+ ],
874
+ [
875
+ 0.5,
876
+ -0.2
877
+ ]
878
+ ]
879
+ }
880
+ },
881
+ {
882
+ "endpoints": [
883
+ 5,
884
+ 6
885
+ ]
886
+ },
887
+ {
888
+ "endpoints": [
889
+ 6,
890
+ 7
891
+ ],
892
+ "curvature": {
893
+ "type": "quadratic",
894
+ "params": [
895
+ [
896
+ 0.85,
897
+ -0.1
898
+ ]
899
+ ]
900
+ }
901
+ },
902
+ {
903
+ "endpoints": [
904
+ 7,
905
+ 0
906
+ ]
907
+ }
908
+ ],
909
+ "label": "body"
910
+ }
911
+ },
912
+ "stitches": [
913
+ [
914
+ {
915
+ "panel": "skirt_back",
916
+ "edge": 4
917
+ },
918
+ {
919
+ "panel": "skirt_back",
920
+ "edge": 5
921
+ }
922
+ ],
923
+ [
924
+ {
925
+ "panel": "skirt_back",
926
+ "edge": 7
927
+ },
928
+ {
929
+ "panel": "skirt_back",
930
+ "edge": 8
931
+ }
932
+ ],
933
+ [
934
+ {
935
+ "panel": "skirt_back",
936
+ "edge": 11
937
+ },
938
+ {
939
+ "panel": "skirt_back",
940
+ "edge": 12
941
+ }
942
+ ],
943
+ [
944
+ {
945
+ "panel": "skirt_back",
946
+ "edge": 14
947
+ },
948
+ {
949
+ "panel": "skirt_back",
950
+ "edge": 15
951
+ }
952
+ ],
953
+ [
954
+ {
955
+ "panel": "skirt_front",
956
+ "edge": 8
957
+ },
958
+ {
959
+ "panel": "skirt_back",
960
+ "edge": 1
961
+ }
962
+ ],
963
+ [
964
+ {
965
+ "panel": "skirt_front",
966
+ "edge": 7
967
+ },
968
+ {
969
+ "panel": "skirt_back",
970
+ "edge": 2
971
+ }
972
+ ],
973
+ [
974
+ {
975
+ "panel": "skirt_front",
976
+ "edge": 3
977
+ },
978
+ {
979
+ "panel": "skirt_back",
980
+ "edge": 17
981
+ }
982
+ ],
983
+ [
984
+ {
985
+ "panel": "skirt_front",
986
+ "edge": 2
987
+ },
988
+ {
989
+ "panel": "skirt_back",
990
+ "edge": 18
991
+ }
992
+ ],
993
+ [
994
+ {
995
+ "panel": "left_ftorso",
996
+ "edge": 3
997
+ },
998
+ {
999
+ "panel": "left_btorso",
1000
+ "edge": 2
1001
+ }
1002
+ ],
1003
+ [
1004
+ {
1005
+ "panel": "left_ftorso",
1006
+ "edge": 1
1007
+ },
1008
+ {
1009
+ "panel": "left_btorso",
1010
+ "edge": 4
1011
+ }
1012
+ ],
1013
+ [
1014
+ {
1015
+ "panel": "right_ftorso",
1016
+ "edge": 2
1017
+ },
1018
+ {
1019
+ "panel": "right_btorso",
1020
+ "edge": 5
1021
+ }
1022
+ ],
1023
+ [
1024
+ {
1025
+ "panel": "right_ftorso",
1026
+ "edge": 4
1027
+ },
1028
+ {
1029
+ "panel": "right_btorso",
1030
+ "edge": 3
1031
+ }
1032
+ ],
1033
+ [
1034
+ {
1035
+ "panel": "right_ftorso",
1036
+ "edge": 0
1037
+ },
1038
+ {
1039
+ "panel": "left_ftorso",
1040
+ "edge": 5
1041
+ }
1042
+ ],
1043
+ [
1044
+ {
1045
+ "panel": "right_btorso",
1046
+ "edge": 7
1047
+ },
1048
+ {
1049
+ "panel": "left_btorso",
1050
+ "edge": 0
1051
+ }
1052
+ ],
1053
+ [
1054
+ {
1055
+ "panel": "right_ftorso",
1056
+ "edge": 5
1057
+ },
1058
+ {
1059
+ "panel": "skirt_front",
1060
+ "edge": 6
1061
+ }
1062
+ ],
1063
+ [
1064
+ {
1065
+ "panel": "left_ftorso",
1066
+ "edge": 0
1067
+ },
1068
+ {
1069
+ "panel": "skirt_front",
1070
+ "edge": 5
1071
+ }
1072
+ ],
1073
+ [
1074
+ {
1075
+ "panel": "left_btorso",
1076
+ "edge": 5
1077
+ },
1078
+ {
1079
+ "panel": "skirt_front",
1080
+ "edge": 4
1081
+ }
1082
+ ],
1083
+ [
1084
+ {
1085
+ "panel": "left_btorso",
1086
+ "edge": 6
1087
+ },
1088
+ {
1089
+ "panel": "skirt_back",
1090
+ "edge": 16
1091
+ }
1092
+ ],
1093
+ [
1094
+ {
1095
+ "panel": "left_btorso",
1096
+ "edge": 7
1097
+ },
1098
+ {
1099
+ "panel": "skirt_back",
1100
+ "edge": 13
1101
+ }
1102
+ ],
1103
+ [
1104
+ {
1105
+ "panel": "left_btorso",
1106
+ "edge": 8
1107
+ },
1108
+ {
1109
+ "panel": "skirt_back",
1110
+ "edge": 10
1111
+ }
1112
+ ],
1113
+ [
1114
+ {
1115
+ "panel": "right_btorso",
1116
+ "edge": 0
1117
+ },
1118
+ {
1119
+ "panel": "skirt_back",
1120
+ "edge": 9
1121
+ }
1122
+ ],
1123
+ [
1124
+ {
1125
+ "panel": "right_btorso",
1126
+ "edge": 1
1127
+ },
1128
+ {
1129
+ "panel": "skirt_back",
1130
+ "edge": 6
1131
+ }
1132
+ ],
1133
+ [
1134
+ {
1135
+ "panel": "right_btorso",
1136
+ "edge": 2
1137
+ },
1138
+ {
1139
+ "panel": "skirt_back",
1140
+ "edge": 3
1141
+ }
1142
+ ]
1143
+ ],
1144
+ "panel_order": [
1145
+ "right_btorso",
1146
+ "right_ftorso",
1147
+ "skirt_back",
1148
+ "skirt_front",
1149
+ "left_btorso",
1150
+ "left_ftorso"
1151
+ ]
1152
+ },
1153
+ "parameters": {},
1154
+ "parameter_order": [],
1155
+ "properties": {
1156
+ "curvature_coords": "relative",
1157
+ "normalize_panel_translation": false,
1158
+ "normalized_edge_loops": true,
1159
+ "units_in_meter": 100
1160
+ }
1161
+ }
GarmentCode/assets/Patterns/hoody_mean_specification.json ADDED
@@ -0,0 +1,732 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "pattern": {
3
+ "panels": {
4
+ "left_btorso": {
5
+ "translation": [
6
+ 0.0,
7
+ 91.4448950181744,
8
+ -20.0
9
+ ],
10
+ "rotation": [
11
+ 0.0,
12
+ 0.0,
13
+ 0.0
14
+ ],
15
+ "vertices": [
16
+ [
17
+ 0.0,
18
+ 0.0
19
+ ],
20
+ [
21
+ 0.0,
22
+ 44.26956007084882
23
+ ],
24
+ [
25
+ 10.8188,
26
+ 49.91845847814037
27
+ ],
28
+ [
29
+ 17.2284,
30
+ 47.37065774294582
31
+ ],
32
+ [
33
+ 25.0299525,
34
+ 28.92917774294582
35
+ ],
36
+ [
37
+ 25.0299525,
38
+ 0.0
39
+ ]
40
+ ],
41
+ "edges": [
42
+ {
43
+ "endpoints": [
44
+ 0,
45
+ 1
46
+ ]
47
+ },
48
+ {
49
+ "endpoints": [
50
+ 1,
51
+ 2
52
+ ],
53
+ "curvature": {
54
+ "type": "circle",
55
+ "params": [
56
+ 13.184560591816423,
57
+ 0,
58
+ 1
59
+ ]
60
+ }
61
+ },
62
+ {
63
+ "endpoints": [
64
+ 2,
65
+ 3
66
+ ]
67
+ },
68
+ {
69
+ "endpoints": [
70
+ 3,
71
+ 4
72
+ ],
73
+ "curvature": {
74
+ "type": "cubic",
75
+ "params": [
76
+ [
77
+ 0.5,
78
+ -0.2
79
+ ],
80
+ [
81
+ 0.8,
82
+ -0.35
83
+ ]
84
+ ]
85
+ }
86
+ },
87
+ {
88
+ "endpoints": [
89
+ 4,
90
+ 5
91
+ ]
92
+ },
93
+ {
94
+ "endpoints": [
95
+ 5,
96
+ 0
97
+ ]
98
+ }
99
+ ],
100
+ "label": "body"
101
+ },
102
+ "left_ftorso": {
103
+ "translation": [
104
+ 0.0,
105
+ 91.40029082350912,
106
+ 25.0
107
+ ],
108
+ "rotation": [
109
+ 0.0,
110
+ 0.0,
111
+ 0.0
112
+ ],
113
+ "vertices": [
114
+ [
115
+ 0.0,
116
+ 0.0
117
+ ],
118
+ [
119
+ 27.386415000000003,
120
+ 0.0
121
+ ],
122
+ [
123
+ 27.386415000000003,
124
+ 28.973782566623598
125
+ ],
126
+ [
127
+ 17.228399999999997,
128
+ 47.415262566623596
129
+ ],
130
+ [
131
+ 10.818799999999998,
132
+ 49.963062523006585
133
+ ],
134
+ [
135
+ 0.0,
136
+ 34.31450269441045
137
+ ]
138
+ ],
139
+ "edges": [
140
+ {
141
+ "endpoints": [
142
+ 0,
143
+ 1
144
+ ]
145
+ },
146
+ {
147
+ "endpoints": [
148
+ 1,
149
+ 2
150
+ ]
151
+ },
152
+ {
153
+ "endpoints": [
154
+ 2,
155
+ 3
156
+ ],
157
+ "curvature": {
158
+ "type": "cubic",
159
+ "params": [
160
+ [
161
+ 0.19999999999999996,
162
+ 0.35
163
+ ],
164
+ [
165
+ 0.5,
166
+ 0.2
167
+ ]
168
+ ]
169
+ }
170
+ },
171
+ {
172
+ "endpoints": [
173
+ 3,
174
+ 4
175
+ ]
176
+ },
177
+ {
178
+ "endpoints": [
179
+ 4,
180
+ 5
181
+ ],
182
+ "curvature": {
183
+ "type": "circle",
184
+ "params": [
185
+ 11.564126734773824,
186
+ 0,
187
+ 0
188
+ ]
189
+ }
190
+ },
191
+ {
192
+ "endpoints": [
193
+ 5,
194
+ 0
195
+ ]
196
+ }
197
+ ],
198
+ "label": "body"
199
+ },
200
+ "left_hood": {
201
+ "translation": [
202
+ 10.818800000000001,
203
+ 149.36600318541687,
204
+ -11.637599999999999
205
+ ],
206
+ "rotation": [
207
+ 0.0,
208
+ 90.0,
209
+ 0.0
210
+ ],
211
+ "vertices": [
212
+ [
213
+ 0.8187999999999995,
214
+ -0.6488984072915587
215
+ ],
216
+ [
217
+ -12.16376,
218
+ 36.7356
219
+ ],
220
+ [
221
+ -22.98256,
222
+ 36.7356
223
+ ],
224
+ [
225
+ -21.37098745180261,
226
+ -11.459953817131435
227
+ ],
228
+ [
229
+ -10.124915390760208,
230
+ 5.065222977771245
231
+ ]
232
+ ],
233
+ "edges": [
234
+ {
235
+ "endpoints": [
236
+ 0,
237
+ 1
238
+ ],
239
+ "curvature": {
240
+ "type": "quadratic",
241
+ "params": [
242
+ [
243
+ 0.8,
244
+ -0.5
245
+ ]
246
+ ]
247
+ }
248
+ },
249
+ {
250
+ "endpoints": [
251
+ 1,
252
+ 2
253
+ ]
254
+ },
255
+ {
256
+ "endpoints": [
257
+ 2,
258
+ 3
259
+ ]
260
+ },
261
+ {
262
+ "endpoints": [
263
+ 3,
264
+ 4
265
+ ],
266
+ "curvature": {
267
+ "type": "cubic",
268
+ "params": [
269
+ [
270
+ 0.2809593298782206,
271
+ -0.37546453034800403
272
+ ],
273
+ [
274
+ 0.7190492879150145,
275
+ 0.3755072247003444
276
+ ]
277
+ ]
278
+ }
279
+ },
280
+ {
281
+ "endpoints": [
282
+ 4,
283
+ 0
284
+ ],
285
+ "curvature": {
286
+ "type": "cubic",
287
+ "params": [
288
+ [
289
+ 0.377233550352168,
290
+ 0.18074617772869186
291
+ ],
292
+ [
293
+ 0.6225672655140111,
294
+ -0.18160966127735645
295
+ ]
296
+ ]
297
+ }
298
+ }
299
+ ],
300
+ "label": "body"
301
+ },
302
+ "right_hood": {
303
+ "translation": [
304
+ -10.818800000000001,
305
+ 149.36600318541687,
306
+ -11.637599999999999
307
+ ],
308
+ "rotation": [
309
+ 0.0,
310
+ -90.0,
311
+ 0.0
312
+ ],
313
+ "vertices": [
314
+ [
315
+ -0.8187999999999995,
316
+ -0.6488984072915587
317
+ ],
318
+ [
319
+ 10.124915390760208,
320
+ 5.065222977771245
321
+ ],
322
+ [
323
+ 21.37098745180261,
324
+ -11.459953817131435
325
+ ],
326
+ [
327
+ 22.98256,
328
+ 36.7356
329
+ ],
330
+ [
331
+ 12.16376,
332
+ 36.7356
333
+ ]
334
+ ],
335
+ "edges": [
336
+ {
337
+ "endpoints": [
338
+ 0,
339
+ 1
340
+ ],
341
+ "curvature": {
342
+ "type": "cubic",
343
+ "params": [
344
+ [
345
+ 0.37743273448598885,
346
+ -0.18160966127735645
347
+ ],
348
+ [
349
+ 0.622766449647832,
350
+ 0.18074617772869186
351
+ ]
352
+ ]
353
+ }
354
+ },
355
+ {
356
+ "endpoints": [
357
+ 1,
358
+ 2
359
+ ],
360
+ "curvature": {
361
+ "type": "cubic",
362
+ "params": [
363
+ [
364
+ 0.28095071208498545,
365
+ 0.3755072247003444
366
+ ],
367
+ [
368
+ 0.7190406701217794,
369
+ -0.37546453034800403
370
+ ]
371
+ ]
372
+ }
373
+ },
374
+ {
375
+ "endpoints": [
376
+ 2,
377
+ 3
378
+ ]
379
+ },
380
+ {
381
+ "endpoints": [
382
+ 3,
383
+ 4
384
+ ]
385
+ },
386
+ {
387
+ "endpoints": [
388
+ 4,
389
+ 0
390
+ ],
391
+ "curvature": {
392
+ "type": "quadratic",
393
+ "params": [
394
+ [
395
+ 0.2,
396
+ -0.5
397
+ ]
398
+ ]
399
+ }
400
+ }
401
+ ],
402
+ "label": "body"
403
+ },
404
+ "right_ftorso": {
405
+ "translation": [
406
+ 0.0,
407
+ 91.40029082350912,
408
+ 25.0
409
+ ],
410
+ "rotation": [
411
+ 0.0,
412
+ 0.0,
413
+ 0.0
414
+ ],
415
+ "vertices": [
416
+ [
417
+ 0,
418
+ 0
419
+ ],
420
+ [
421
+ 0.0,
422
+ 34.31450269441045
423
+ ],
424
+ [
425
+ -10.818799999999998,
426
+ 49.963062523006585
427
+ ],
428
+ [
429
+ -17.228399999999997,
430
+ 47.415262566623596
431
+ ],
432
+ [
433
+ -27.386415000000003,
434
+ 28.973782566623598
435
+ ],
436
+ [
437
+ -27.386415000000003,
438
+ 0
439
+ ]
440
+ ],
441
+ "edges": [
442
+ {
443
+ "endpoints": [
444
+ 0,
445
+ 1
446
+ ]
447
+ },
448
+ {
449
+ "endpoints": [
450
+ 1,
451
+ 2
452
+ ],
453
+ "curvature": {
454
+ "type": "circle",
455
+ "params": [
456
+ 11.564126734773824,
457
+ 0,
458
+ 0
459
+ ]
460
+ }
461
+ },
462
+ {
463
+ "endpoints": [
464
+ 2,
465
+ 3
466
+ ]
467
+ },
468
+ {
469
+ "endpoints": [
470
+ 3,
471
+ 4
472
+ ],
473
+ "curvature": {
474
+ "type": "cubic",
475
+ "params": [
476
+ [
477
+ 0.5,
478
+ 0.2
479
+ ],
480
+ [
481
+ 0.8,
482
+ 0.35
483
+ ]
484
+ ]
485
+ }
486
+ },
487
+ {
488
+ "endpoints": [
489
+ 4,
490
+ 5
491
+ ]
492
+ },
493
+ {
494
+ "endpoints": [
495
+ 5,
496
+ 0
497
+ ]
498
+ }
499
+ ],
500
+ "label": "body"
501
+ },
502
+ "right_btorso": {
503
+ "translation": [
504
+ 0.0,
505
+ 91.4448950181744,
506
+ -20.0
507
+ ],
508
+ "rotation": [
509
+ 0.0,
510
+ 0.0,
511
+ 0.0
512
+ ],
513
+ "vertices": [
514
+ [
515
+ 0,
516
+ 0
517
+ ],
518
+ [
519
+ -25.0299525,
520
+ 0
521
+ ],
522
+ [
523
+ -25.0299525,
524
+ 28.92917774294582
525
+ ],
526
+ [
527
+ -17.2284,
528
+ 47.37065774294582
529
+ ],
530
+ [
531
+ -10.8188,
532
+ 49.91845847814037
533
+ ],
534
+ [
535
+ 0.0,
536
+ 44.26956007084882
537
+ ]
538
+ ],
539
+ "edges": [
540
+ {
541
+ "endpoints": [
542
+ 0,
543
+ 1
544
+ ]
545
+ },
546
+ {
547
+ "endpoints": [
548
+ 1,
549
+ 2
550
+ ]
551
+ },
552
+ {
553
+ "endpoints": [
554
+ 2,
555
+ 3
556
+ ],
557
+ "curvature": {
558
+ "type": "cubic",
559
+ "params": [
560
+ [
561
+ 0.19999999999999996,
562
+ -0.35
563
+ ],
564
+ [
565
+ 0.5,
566
+ -0.2
567
+ ]
568
+ ]
569
+ }
570
+ },
571
+ {
572
+ "endpoints": [
573
+ 3,
574
+ 4
575
+ ]
576
+ },
577
+ {
578
+ "endpoints": [
579
+ 4,
580
+ 5
581
+ ],
582
+ "curvature": {
583
+ "type": "circle",
584
+ "params": [
585
+ 13.184560591816423,
586
+ 0,
587
+ 1
588
+ ]
589
+ }
590
+ },
591
+ {
592
+ "endpoints": [
593
+ 5,
594
+ 0
595
+ ]
596
+ }
597
+ ],
598
+ "label": "body"
599
+ }
600
+ },
601
+ "stitches": [
602
+ [
603
+ {
604
+ "panel": "left_ftorso",
605
+ "edge": 4
606
+ },
607
+ {
608
+ "panel": "left_hood",
609
+ "edge": 3
610
+ }
611
+ ],
612
+ [
613
+ {
614
+ "panel": "left_btorso",
615
+ "edge": 1
616
+ },
617
+ {
618
+ "panel": "left_hood",
619
+ "edge": 4
620
+ }
621
+ ],
622
+ [
623
+ {
624
+ "panel": "left_ftorso",
625
+ "edge": 3
626
+ },
627
+ {
628
+ "panel": "left_btorso",
629
+ "edge": 2
630
+ }
631
+ ],
632
+ [
633
+ {
634
+ "panel": "left_ftorso",
635
+ "edge": 1
636
+ },
637
+ {
638
+ "panel": "left_btorso",
639
+ "edge": 4
640
+ }
641
+ ],
642
+ [
643
+ {
644
+ "panel": "right_ftorso",
645
+ "edge": 1
646
+ },
647
+ {
648
+ "panel": "right_hood",
649
+ "edge": 1
650
+ }
651
+ ],
652
+ [
653
+ {
654
+ "panel": "right_btorso",
655
+ "edge": 4
656
+ },
657
+ {
658
+ "panel": "right_hood",
659
+ "edge": 0
660
+ }
661
+ ],
662
+ [
663
+ {
664
+ "panel": "right_ftorso",
665
+ "edge": 2
666
+ },
667
+ {
668
+ "panel": "right_btorso",
669
+ "edge": 3
670
+ }
671
+ ],
672
+ [
673
+ {
674
+ "panel": "right_ftorso",
675
+ "edge": 4
676
+ },
677
+ {
678
+ "panel": "right_btorso",
679
+ "edge": 1
680
+ }
681
+ ],
682
+ [
683
+ {
684
+ "panel": "right_ftorso",
685
+ "edge": 0
686
+ },
687
+ {
688
+ "panel": "left_ftorso",
689
+ "edge": 5
690
+ }
691
+ ],
692
+ [
693
+ {
694
+ "panel": "right_btorso",
695
+ "edge": 5
696
+ },
697
+ {
698
+ "panel": "left_btorso",
699
+ "edge": 0
700
+ }
701
+ ],
702
+ [
703
+ {
704
+ "panel": "right_hood",
705
+ "edge": 3
706
+ },
707
+ {
708
+ "panel": "left_hood",
709
+ "edge": 1
710
+ }
711
+ ],
712
+ [
713
+ {
714
+ "panel": "right_hood",
715
+ "edge": 4
716
+ },
717
+ {
718
+ "panel": "left_hood",
719
+ "edge": 0
720
+ }
721
+ ]
722
+ ]
723
+ },
724
+ "parameters": {},
725
+ "parameter_order": [],
726
+ "properties": {
727
+ "curvature_coords": "relative",
728
+ "normalize_panel_translation": false,
729
+ "normalized_edge_loops": true,
730
+ "units_in_meter": 100
731
+ }
732
+ }
GarmentCode/assets/Patterns/js_mean_all_specification.json ADDED
@@ -0,0 +1,2505 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "pattern": {
3
+ "panels": {
4
+ "pant_f_r": {
5
+ "translation": [
6
+ -30.5,
7
+ -4.3669186450417214,
8
+ 25.0
9
+ ],
10
+ "rotation": [
11
+ 0.0,
12
+ 0.0,
13
+ 0.0
14
+ ],
15
+ "vertices": [
16
+ [
17
+ 0.0,
18
+ 0
19
+ ],
20
+ [
21
+ 28.408937499999993,
22
+ 0
23
+ ],
24
+ [
25
+ 30.408937499999993,
26
+ 67.94629
27
+ ],
28
+ [
29
+ 24.327149999999996,
30
+ 87.32758500000001
31
+ ],
32
+ [
33
+ 24.327149999999996,
34
+ 100.24362
35
+ ],
36
+ [
37
+ 24.238441243468394,
38
+ 100.24362
39
+ ],
40
+ [
41
+ 15.798551106433417,
42
+ 100.24362
43
+ ],
44
+ [
45
+ 1.7281499999999994,
46
+ 100.24362
47
+ ],
48
+ [
49
+ 0,
50
+ 76.75992000000001
51
+ ]
52
+ ],
53
+ "edges": [
54
+ {
55
+ "endpoints": [
56
+ 0,
57
+ 1
58
+ ]
59
+ },
60
+ {
61
+ "endpoints": [
62
+ 1,
63
+ 2
64
+ ],
65
+ "curvature": {
66
+ "type": "quadratic",
67
+ "params": [
68
+ [
69
+ 0.6999900866807987,
70
+ 0.02060441156153251
71
+ ]
72
+ ]
73
+ }
74
+ },
75
+ {
76
+ "endpoints": [
77
+ 2,
78
+ 3
79
+ ],
80
+ "curvature": {
81
+ "type": "quadratic",
82
+ "params": [
83
+ [
84
+ 0.08964087499583218,
85
+ 0.28566587353404743
86
+ ]
87
+ ]
88
+ }
89
+ },
90
+ {
91
+ "endpoints": [
92
+ 3,
93
+ 4
94
+ ]
95
+ },
96
+ {
97
+ "endpoints": [
98
+ 4,
99
+ 5
100
+ ],
101
+ "label": "lower_interface"
102
+ },
103
+ {
104
+ "endpoints": [
105
+ 5,
106
+ 6
107
+ ],
108
+ "label": "lower_interface"
109
+ },
110
+ {
111
+ "endpoints": [
112
+ 6,
113
+ 7
114
+ ],
115
+ "label": "lower_interface"
116
+ },
117
+ {
118
+ "endpoints": [
119
+ 7,
120
+ 8
121
+ ],
122
+ "curvature": {
123
+ "type": "quadratic",
124
+ "params": [
125
+ [
126
+ 0.50144546248277,
127
+ -0.036687515673545716
128
+ ]
129
+ ]
130
+ }
131
+ },
132
+ {
133
+ "endpoints": [
134
+ 8,
135
+ 0
136
+ ]
137
+ }
138
+ ]
139
+ },
140
+ "pant_b_r": {
141
+ "translation": [
142
+ -34.5,
143
+ -6.715288645041724,
144
+ -20.0
145
+ ],
146
+ "rotation": [
147
+ 0.0,
148
+ 0.0,
149
+ 0.0
150
+ ],
151
+ "vertices": [
152
+ [
153
+ 0.0,
154
+ 0
155
+ ],
156
+ [
157
+ 0,
158
+ 76.75992000000001
159
+ ],
160
+ [
161
+ 2.2293258144990666,
162
+ 102.59199000000001
163
+ ],
164
+ [
165
+ 10.40085079989197,
166
+ 102.59199000000001
167
+ ],
168
+ [
169
+ 11.804506846267202,
170
+ 84.0459415418824
171
+ ],
172
+ [
173
+ 13.208162892642434,
174
+ 102.59199000000001
175
+ ],
176
+ [
177
+ 13.341630160745268,
178
+ 102.59199000000001
179
+ ],
180
+ [
181
+ 17.76671297304689,
182
+ 102.59199000000001
183
+ ],
184
+ [
185
+ 19.17036901942212,
186
+ 81.97405878433702
187
+ ],
188
+ [
189
+ 20.574025065797358,
190
+ 102.59199000000001
191
+ ],
192
+ [
193
+ 20.689582502203926,
194
+ 102.59199000000001
195
+ ],
196
+ [
197
+ 27.41185,
198
+ 102.59199000000001
199
+ ],
200
+ [
201
+ 27.41185,
202
+ 88.38435150000001
203
+ ],
204
+ [
205
+ 34.794962500000004,
206
+ 67.94629
207
+ ],
208
+ [
209
+ 32.794962500000004,
210
+ 0
211
+ ]
212
+ ],
213
+ "edges": [
214
+ {
215
+ "endpoints": [
216
+ 0,
217
+ 1
218
+ ]
219
+ },
220
+ {
221
+ "endpoints": [
222
+ 1,
223
+ 2
224
+ ],
225
+ "curvature": {
226
+ "type": "quadratic",
227
+ "params": [
228
+ [
229
+ 0.4980453962635151,
230
+ 0.04298166013493028
231
+ ]
232
+ ]
233
+ }
234
+ },
235
+ {
236
+ "endpoints": [
237
+ 2,
238
+ 3
239
+ ],
240
+ "label": "lower_interface"
241
+ },
242
+ {
243
+ "endpoints": [
244
+ 3,
245
+ 4
246
+ ]
247
+ },
248
+ {
249
+ "endpoints": [
250
+ 4,
251
+ 5
252
+ ]
253
+ },
254
+ {
255
+ "endpoints": [
256
+ 5,
257
+ 6
258
+ ],
259
+ "label": "lower_interface"
260
+ },
261
+ {
262
+ "endpoints": [
263
+ 6,
264
+ 7
265
+ ],
266
+ "label": "lower_interface"
267
+ },
268
+ {
269
+ "endpoints": [
270
+ 7,
271
+ 8
272
+ ]
273
+ },
274
+ {
275
+ "endpoints": [
276
+ 8,
277
+ 9
278
+ ]
279
+ },
280
+ {
281
+ "endpoints": [
282
+ 9,
283
+ 10
284
+ ],
285
+ "label": "lower_interface"
286
+ },
287
+ {
288
+ "endpoints": [
289
+ 10,
290
+ 11
291
+ ],
292
+ "label": "lower_interface"
293
+ },
294
+ {
295
+ "endpoints": [
296
+ 11,
297
+ 12
298
+ ]
299
+ },
300
+ {
301
+ "endpoints": [
302
+ 12,
303
+ 13
304
+ ],
305
+ "curvature": {
306
+ "type": "quadratic",
307
+ "params": [
308
+ [
309
+ 0.8845668946561731,
310
+ -0.3195439140202038
311
+ ]
312
+ ]
313
+ }
314
+ },
315
+ {
316
+ "endpoints": [
317
+ 13,
318
+ 14
319
+ ],
320
+ "curvature": {
321
+ "type": "quadratic",
322
+ "params": [
323
+ [
324
+ 0.3000099133192014,
325
+ -0.02060441156153251
326
+ ]
327
+ ]
328
+ }
329
+ },
330
+ {
331
+ "endpoints": [
332
+ 14,
333
+ 0
334
+ ]
335
+ }
336
+ ]
337
+ },
338
+ "pant_b_l": {
339
+ "translation": [
340
+ 34.5,
341
+ -6.715288645041724,
342
+ -20.0
343
+ ],
344
+ "rotation": [
345
+ 0.0,
346
+ 0.0,
347
+ 0.0
348
+ ],
349
+ "vertices": [
350
+ [
351
+ 0.0,
352
+ 0.0
353
+ ],
354
+ [
355
+ -32.794962500000004,
356
+ 0.0
357
+ ],
358
+ [
359
+ -34.794962500000004,
360
+ 67.94629
361
+ ],
362
+ [
363
+ -27.41185,
364
+ 88.38435150000001
365
+ ],
366
+ [
367
+ -27.41185,
368
+ 102.59199000000001
369
+ ],
370
+ [
371
+ -27.323141243468424,
372
+ 102.59199000000001
373
+ ],
374
+ [
375
+ -20.574025065797358,
376
+ 102.59199000000001
377
+ ],
378
+ [
379
+ -19.17036901942212,
380
+ 81.97405878433702
381
+ ],
382
+ [
383
+ -17.76671297304689,
384
+ 102.59199000000001
385
+ ],
386
+ [
387
+ -13.208162892642434,
388
+ 102.59199000000001
389
+ ],
390
+ [
391
+ -11.804506846267202,
392
+ 84.0459415418824
393
+ ],
394
+ [
395
+ -10.40085079989197,
396
+ 102.59199000000001
397
+ ],
398
+ [
399
+ -2.2293258144990666,
400
+ 102.59199000000001
401
+ ],
402
+ [
403
+ 0.0,
404
+ 76.75992000000001
405
+ ]
406
+ ],
407
+ "edges": [
408
+ {
409
+ "endpoints": [
410
+ 0,
411
+ 1
412
+ ]
413
+ },
414
+ {
415
+ "endpoints": [
416
+ 1,
417
+ 2
418
+ ],
419
+ "curvature": {
420
+ "type": "quadratic",
421
+ "params": [
422
+ [
423
+ 0.6999900866807987,
424
+ -0.02060441156153251
425
+ ]
426
+ ]
427
+ }
428
+ },
429
+ {
430
+ "endpoints": [
431
+ 2,
432
+ 3
433
+ ],
434
+ "curvature": {
435
+ "type": "quadratic",
436
+ "params": [
437
+ [
438
+ 0.11543310534382689,
439
+ -0.3195439140202038
440
+ ]
441
+ ]
442
+ }
443
+ },
444
+ {
445
+ "endpoints": [
446
+ 3,
447
+ 4
448
+ ]
449
+ },
450
+ {
451
+ "endpoints": [
452
+ 4,
453
+ 5
454
+ ],
455
+ "label": "lower_interface"
456
+ },
457
+ {
458
+ "endpoints": [
459
+ 5,
460
+ 6
461
+ ],
462
+ "label": "lower_interface"
463
+ },
464
+ {
465
+ "endpoints": [
466
+ 6,
467
+ 7
468
+ ]
469
+ },
470
+ {
471
+ "endpoints": [
472
+ 7,
473
+ 8
474
+ ]
475
+ },
476
+ {
477
+ "endpoints": [
478
+ 8,
479
+ 9
480
+ ],
481
+ "label": "lower_interface"
482
+ },
483
+ {
484
+ "endpoints": [
485
+ 9,
486
+ 10
487
+ ]
488
+ },
489
+ {
490
+ "endpoints": [
491
+ 10,
492
+ 11
493
+ ]
494
+ },
495
+ {
496
+ "endpoints": [
497
+ 11,
498
+ 12
499
+ ],
500
+ "label": "lower_interface"
501
+ },
502
+ {
503
+ "endpoints": [
504
+ 12,
505
+ 13
506
+ ],
507
+ "curvature": {
508
+ "type": "quadratic",
509
+ "params": [
510
+ [
511
+ 0.5019546037364848,
512
+ 0.04298166013493028
513
+ ]
514
+ ]
515
+ }
516
+ },
517
+ {
518
+ "endpoints": [
519
+ 13,
520
+ 0
521
+ ]
522
+ }
523
+ ]
524
+ },
525
+ "pant_f_l": {
526
+ "translation": [
527
+ 30.5,
528
+ -4.3669186450417214,
529
+ 25.0
530
+ ],
531
+ "rotation": [
532
+ 0.0,
533
+ 0.0,
534
+ 0.0
535
+ ],
536
+ "vertices": [
537
+ [
538
+ 0.0,
539
+ 0.0
540
+ ],
541
+ [
542
+ 0.0,
543
+ 76.75992000000001
544
+ ],
545
+ [
546
+ -1.7281499999999994,
547
+ 100.24362
548
+ ],
549
+ [
550
+ -1.905567513063204,
551
+ 100.24362
552
+ ],
553
+ [
554
+ -15.975968619496626,
555
+ 100.24362
556
+ ],
557
+ [
558
+ -24.327149999999996,
559
+ 100.24362
560
+ ],
561
+ [
562
+ -24.327149999999996,
563
+ 87.32758500000001
564
+ ],
565
+ [
566
+ -30.408937499999993,
567
+ 67.94629
568
+ ],
569
+ [
570
+ -28.408937499999993,
571
+ 0.0
572
+ ]
573
+ ],
574
+ "edges": [
575
+ {
576
+ "endpoints": [
577
+ 0,
578
+ 1
579
+ ]
580
+ },
581
+ {
582
+ "endpoints": [
583
+ 1,
584
+ 2
585
+ ],
586
+ "curvature": {
587
+ "type": "quadratic",
588
+ "params": [
589
+ [
590
+ 0.49855453751723,
591
+ -0.036687515673545716
592
+ ]
593
+ ]
594
+ }
595
+ },
596
+ {
597
+ "endpoints": [
598
+ 2,
599
+ 3
600
+ ],
601
+ "label": "lower_interface"
602
+ },
603
+ {
604
+ "endpoints": [
605
+ 3,
606
+ 4
607
+ ],
608
+ "label": "lower_interface"
609
+ },
610
+ {
611
+ "endpoints": [
612
+ 4,
613
+ 5
614
+ ],
615
+ "label": "lower_interface"
616
+ },
617
+ {
618
+ "endpoints": [
619
+ 5,
620
+ 6
621
+ ]
622
+ },
623
+ {
624
+ "endpoints": [
625
+ 6,
626
+ 7
627
+ ],
628
+ "curvature": {
629
+ "type": "quadratic",
630
+ "params": [
631
+ [
632
+ 0.9103591250041678,
633
+ 0.28566587353404743
634
+ ]
635
+ ]
636
+ }
637
+ },
638
+ {
639
+ "endpoints": [
640
+ 7,
641
+ 8
642
+ ],
643
+ "curvature": {
644
+ "type": "quadratic",
645
+ "params": [
646
+ [
647
+ 0.30000991331920135,
648
+ 0.02060441156153251
649
+ ]
650
+ ]
651
+ }
652
+ },
653
+ {
654
+ "endpoints": [
655
+ 8,
656
+ 0
657
+ ]
658
+ }
659
+ ]
660
+ },
661
+ "right_sleeve_b": {
662
+ "translation": [
663
+ -63.1462686655216,
664
+ 93.89395203562641,
665
+ -12.5
666
+ ],
667
+ "rotation": [
668
+ 0.0,
669
+ 0.0,
670
+ 50.48299999999997
671
+ ],
672
+ "vertices": [
673
+ [
674
+ 0,
675
+ 0
676
+ ],
677
+ [
678
+ 53.9697,
679
+ 0.0
680
+ ],
681
+ [
682
+ 53.973272929069736,
683
+ -0.5315642505301881
684
+ ],
685
+ [
686
+ 38.59156179316456,
687
+ -18.26821330891046
688
+ ],
689
+ [
690
+ 38.283061457383745,
691
+ -18.70773098482538
692
+ ],
693
+ [
694
+ 0,
695
+ -18.70773098482538
696
+ ]
697
+ ],
698
+ "edges": [
699
+ {
700
+ "endpoints": [
701
+ 0,
702
+ 1
703
+ ]
704
+ },
705
+ {
706
+ "endpoints": [
707
+ 1,
708
+ 2
709
+ ],
710
+ "curvature": {
711
+ "type": "cubic",
712
+ "params": [
713
+ [
714
+ 0.32863847640779986,
715
+ 0.005982609693050386
716
+ ],
717
+ [
718
+ 0.6619300386670336,
719
+ 0.0060373677151341325
720
+ ]
721
+ ]
722
+ }
723
+ },
724
+ {
725
+ "endpoints": [
726
+ 2,
727
+ 3
728
+ ],
729
+ "curvature": {
730
+ "type": "cubic",
731
+ "params": [
732
+ [
733
+ 0.37868547557453663,
734
+ 0.3104039319894889
735
+ ],
736
+ [
737
+ 0.6642671905527117,
738
+ -0.02627863415950396
739
+ ]
740
+ ]
741
+ }
742
+ },
743
+ {
744
+ "endpoints": [
745
+ 3,
746
+ 4
747
+ ],
748
+ "curvature": {
749
+ "type": "cubic",
750
+ "params": [
751
+ [
752
+ 0.3313648410129161,
753
+ -0.008051543005962211
754
+ ],
755
+ [
756
+ 0.6646573093704425,
757
+ -0.00821617932857873
758
+ ]
759
+ ]
760
+ }
761
+ },
762
+ {
763
+ "endpoints": [
764
+ 4,
765
+ 5
766
+ ]
767
+ },
768
+ {
769
+ "endpoints": [
770
+ 5,
771
+ 0
772
+ ]
773
+ }
774
+ ]
775
+ },
776
+ "right_sleeve_f": {
777
+ "translation": [
778
+ -63.1462686655216,
779
+ 93.89395203562641,
780
+ 17.5
781
+ ],
782
+ "rotation": [
783
+ 0.0,
784
+ 0.0,
785
+ 50.48299999999997
786
+ ],
787
+ "vertices": [
788
+ [
789
+ 0,
790
+ 0
791
+ ],
792
+ [
793
+ 0,
794
+ -18.70773098482539
795
+ ],
796
+ [
797
+ 38.283061457383745,
798
+ -18.70773098482539
799
+ ],
800
+ [
801
+ 53.9697,
802
+ 0.0
803
+ ]
804
+ ],
805
+ "edges": [
806
+ {
807
+ "endpoints": [
808
+ 0,
809
+ 1
810
+ ]
811
+ },
812
+ {
813
+ "endpoints": [
814
+ 1,
815
+ 2
816
+ ]
817
+ },
818
+ {
819
+ "endpoints": [
820
+ 2,
821
+ 3
822
+ ],
823
+ "curvature": {
824
+ "type": "cubic",
825
+ "params": [
826
+ [
827
+ 0.32358252781938784,
828
+ 0.04591413598690493
829
+ ],
830
+ [
831
+ 0.669121242607226,
832
+ -0.26368523271924277
833
+ ]
834
+ ]
835
+ }
836
+ },
837
+ {
838
+ "endpoints": [
839
+ 3,
840
+ 0
841
+ ]
842
+ }
843
+ ]
844
+ },
845
+ "right_ftorso": {
846
+ "translation": [
847
+ 0.0,
848
+ 97.85775552378857,
849
+ 25.0
850
+ ],
851
+ "rotation": [
852
+ 0.0,
853
+ 0.0,
854
+ 0.0
855
+ ],
856
+ "vertices": [
857
+ [
858
+ 0,
859
+ 0
860
+ ],
861
+ [
862
+ 0.0,
863
+ 34.89594151313412
864
+ ],
865
+ [
866
+ -9.466400000000007,
867
+ 44.043173444839624
868
+ ],
869
+ [
870
+ -17.068593301490633,
871
+ 41.021320591251275
872
+ ],
873
+ [
874
+ -24.996302137010776,
875
+ 19.59242892249056
876
+ ],
877
+ [
878
+ -25.526504666141484,
879
+ 19.506260591251273
880
+ ],
881
+ [
882
+ -26.082300000000004,
883
+ 17.90286664205999
884
+ ],
885
+ [
886
+ -13.003468750843743,
887
+ 16.06836664205999
888
+ ],
889
+ [
890
+ -26.082300000000004,
891
+ 14.233866642059992
892
+ ],
893
+ [
894
+ -24.921200000000002,
895
+ 0
896
+ ],
897
+ [
898
+ -10.795350131373658,
899
+ 2.8438747969799893e-16
900
+ ],
901
+ [
902
+ -9.634250131373655,
903
+ 12.757752334184888
904
+ ],
905
+ [
906
+ -8.473150131373654,
907
+ 0.0
908
+ ]
909
+ ],
910
+ "edges": [
911
+ {
912
+ "endpoints": [
913
+ 0,
914
+ 1
915
+ ]
916
+ },
917
+ {
918
+ "endpoints": [
919
+ 1,
920
+ 2
921
+ ],
922
+ "curvature": {
923
+ "type": "circle",
924
+ "params": [
925
+ 9.471968255871255,
926
+ 0,
927
+ 0
928
+ ]
929
+ }
930
+ },
931
+ {
932
+ "endpoints": [
933
+ 2,
934
+ 3
935
+ ]
936
+ },
937
+ {
938
+ "endpoints": [
939
+ 3,
940
+ 4
941
+ ],
942
+ "curvature": {
943
+ "type": "cubic",
944
+ "params": [
945
+ [
946
+ 0.4999050169681545,
947
+ 0.1883302341344098
948
+ ],
949
+ [
950
+ 0.8043518804116235,
951
+ 0.3319741548667245
952
+ ]
953
+ ]
954
+ }
955
+ },
956
+ {
957
+ "endpoints": [
958
+ 4,
959
+ 5
960
+ ],
961
+ "curvature": {
962
+ "type": "cubic",
963
+ "params": [
964
+ [
965
+ 0.3271796227218547,
966
+ 0.005595060073123807
967
+ ],
968
+ [
969
+ 0.660465834300256,
970
+ 0.005610518980133189
971
+ ]
972
+ ]
973
+ }
974
+ },
975
+ {
976
+ "endpoints": [
977
+ 5,
978
+ 6
979
+ ]
980
+ },
981
+ {
982
+ "endpoints": [
983
+ 6,
984
+ 7
985
+ ]
986
+ },
987
+ {
988
+ "endpoints": [
989
+ 7,
990
+ 8
991
+ ]
992
+ },
993
+ {
994
+ "endpoints": [
995
+ 8,
996
+ 9
997
+ ]
998
+ },
999
+ {
1000
+ "endpoints": [
1001
+ 9,
1002
+ 10
1003
+ ]
1004
+ },
1005
+ {
1006
+ "endpoints": [
1007
+ 10,
1008
+ 11
1009
+ ]
1010
+ },
1011
+ {
1012
+ "endpoints": [
1013
+ 11,
1014
+ 12
1015
+ ]
1016
+ },
1017
+ {
1018
+ "endpoints": [
1019
+ 12,
1020
+ 0
1021
+ ]
1022
+ }
1023
+ ]
1024
+ },
1025
+ "right_btorso": {
1026
+ "translation": [
1027
+ 0.0,
1028
+ 103.895647186128,
1029
+ -20.0
1030
+ ],
1031
+ "rotation": [
1032
+ 0.0,
1033
+ 0.0,
1034
+ 0.0
1035
+ ],
1036
+ "vertices": [
1037
+ [
1038
+ 0,
1039
+ 0.36889166233942916
1040
+ ],
1041
+ [
1042
+ -0.08905833277792433,
1043
+ 0.3688589462235563
1044
+ ],
1045
+ [
1046
+ -6.834173497862042,
1047
+ 0.17565525646278113
1048
+ ],
1049
+ [
1050
+ -8.48693346149262,
1051
+ 12.065376393017543
1052
+ ],
1053
+ [
1054
+ -8.609766328346904,
1055
+ 0.06196036718399833
1056
+ ],
1057
+ [
1058
+ -8.725480294727715,
1059
+ 0.053638541168747444
1060
+ ],
1061
+ [
1062
+ -13.149513068978942,
1063
+ -0.34849401033276073
1064
+ ],
1065
+ [
1066
+ -15.282781625426587,
1067
+ 10.242436235402488
1068
+ ],
1069
+ [
1070
+ -14.916717524779742,
1071
+ -0.5550002787973305
1072
+ ],
1073
+ [
1074
+ -15.049438757247827,
1075
+ -0.5734192881844533
1076
+ ],
1077
+ [
1078
+ -23.126358333333332,
1079
+ -2
1080
+ ],
1081
+ [
1082
+ -23.83805,
1083
+ 12.233866666666664
1084
+ ],
1085
+ [
1086
+ -23.83805,
1087
+ 13.773738041611095
1088
+ ],
1089
+ [
1090
+ -17.184234849367538,
1091
+ 34.758881544252446
1092
+ ],
1093
+ [
1094
+ -17.2284,
1095
+ 35.288798041611095
1096
+ ],
1097
+ [
1098
+ -9.4664,
1099
+ 38.374174026708005
1100
+ ],
1101
+ [
1102
+ 0.0,
1103
+ 32.66147825518972
1104
+ ]
1105
+ ],
1106
+ "edges": [
1107
+ {
1108
+ "endpoints": [
1109
+ 0,
1110
+ 1
1111
+ ],
1112
+ "curvature": {
1113
+ "type": "quadratic",
1114
+ "params": [
1115
+ [
1116
+ 0.5000097415162759,
1117
+ -0.00018368624360182154
1118
+ ]
1119
+ ]
1120
+ }
1121
+ },
1122
+ {
1123
+ "endpoints": [
1124
+ 1,
1125
+ 2
1126
+ ],
1127
+ "curvature": {
1128
+ "type": "quadratic",
1129
+ "params": [
1130
+ [
1131
+ 0.5003451907438896,
1132
+ -0.013963720864474685
1133
+ ]
1134
+ ]
1135
+ }
1136
+ },
1137
+ {
1138
+ "endpoints": [
1139
+ 2,
1140
+ 3
1141
+ ]
1142
+ },
1143
+ {
1144
+ "endpoints": [
1145
+ 3,
1146
+ 4
1147
+ ]
1148
+ },
1149
+ {
1150
+ "endpoints": [
1151
+ 4,
1152
+ 5
1153
+ ],
1154
+ "curvature": {
1155
+ "type": "quadratic",
1156
+ "params": [
1157
+ [
1158
+ 0.49999557020576196,
1159
+ -0.00024016853064609864
1160
+ ]
1161
+ ]
1162
+ }
1163
+ },
1164
+ {
1165
+ "endpoints": [
1166
+ 5,
1167
+ 6
1168
+ ],
1169
+ "curvature": {
1170
+ "type": "quadratic",
1171
+ "params": [
1172
+ [
1173
+ 0.4996573855254641,
1174
+ -0.009181854128981672
1175
+ ]
1176
+ ]
1177
+ }
1178
+ },
1179
+ {
1180
+ "endpoints": [
1181
+ 6,
1182
+ 7
1183
+ ]
1184
+ },
1185
+ {
1186
+ "endpoints": [
1187
+ 7,
1188
+ 8
1189
+ ]
1190
+ },
1191
+ {
1192
+ "endpoints": [
1193
+ 8,
1194
+ 9
1195
+ ],
1196
+ "curvature": {
1197
+ "type": "quadratic",
1198
+ "params": [
1199
+ [
1200
+ 0.49997879225709474,
1201
+ -0.00029863531116029263
1202
+ ]
1203
+ ]
1204
+ }
1205
+ },
1206
+ {
1207
+ "endpoints": [
1208
+ 9,
1209
+ 10
1210
+ ],
1211
+ "curvature": {
1212
+ "type": "quadratic",
1213
+ "params": [
1214
+ [
1215
+ 0.4980409448407881,
1216
+ -0.01809939780149614
1217
+ ]
1218
+ ]
1219
+ }
1220
+ },
1221
+ {
1222
+ "endpoints": [
1223
+ 10,
1224
+ 11
1225
+ ]
1226
+ },
1227
+ {
1228
+ "endpoints": [
1229
+ 11,
1230
+ 12
1231
+ ]
1232
+ },
1233
+ {
1234
+ "endpoints": [
1235
+ 12,
1236
+ 13
1237
+ ],
1238
+ "curvature": {
1239
+ "type": "cubic",
1240
+ "params": [
1241
+ [
1242
+ 0.2046292227373173,
1243
+ -0.35074597383647943
1244
+ ],
1245
+ [
1246
+ 0.5040478228681711,
1247
+ -0.2043546603132496
1248
+ ]
1249
+ ]
1250
+ }
1251
+ },
1252
+ {
1253
+ "endpoints": [
1254
+ 13,
1255
+ 14
1256
+ ],
1257
+ "curvature": {
1258
+ "type": "cubic",
1259
+ "params": [
1260
+ [
1261
+ 0.3314569774677236,
1262
+ 0.00021546824748456243
1263
+ ],
1264
+ [
1265
+ 0.6647936582659214,
1266
+ 0.00023588113266078883
1267
+ ]
1268
+ ]
1269
+ }
1270
+ },
1271
+ {
1272
+ "endpoints": [
1273
+ 14,
1274
+ 15
1275
+ ]
1276
+ },
1277
+ {
1278
+ "endpoints": [
1279
+ 15,
1280
+ 16
1281
+ ],
1282
+ "curvature": {
1283
+ "type": "circle",
1284
+ "params": [
1285
+ 10.699643988343615,
1286
+ 0,
1287
+ 1
1288
+ ]
1289
+ }
1290
+ },
1291
+ {
1292
+ "endpoints": [
1293
+ 16,
1294
+ 0
1295
+ ]
1296
+ }
1297
+ ]
1298
+ },
1299
+ "left_sleeve_f": {
1300
+ "translation": [
1301
+ 63.1462686655216,
1302
+ 93.89395203562643,
1303
+ 17.5
1304
+ ],
1305
+ "rotation": [
1306
+ 0.0,
1307
+ 0.0,
1308
+ -50.48299999999997
1309
+ ],
1310
+ "vertices": [
1311
+ [
1312
+ 0.0,
1313
+ 0.0
1314
+ ],
1315
+ [
1316
+ -53.9697,
1317
+ 0.0
1318
+ ],
1319
+ [
1320
+ -38.283061457383745,
1321
+ -18.70773098482539
1322
+ ],
1323
+ [
1324
+ 0.0,
1325
+ -18.70773098482539
1326
+ ]
1327
+ ],
1328
+ "edges": [
1329
+ {
1330
+ "endpoints": [
1331
+ 0,
1332
+ 1
1333
+ ]
1334
+ },
1335
+ {
1336
+ "endpoints": [
1337
+ 1,
1338
+ 2
1339
+ ],
1340
+ "curvature": {
1341
+ "type": "cubic",
1342
+ "params": [
1343
+ [
1344
+ 0.33087875739277395,
1345
+ -0.26368523271924277
1346
+ ],
1347
+ [
1348
+ 0.6764174721806122,
1349
+ 0.04591413598690493
1350
+ ]
1351
+ ]
1352
+ }
1353
+ },
1354
+ {
1355
+ "endpoints": [
1356
+ 2,
1357
+ 3
1358
+ ]
1359
+ },
1360
+ {
1361
+ "endpoints": [
1362
+ 3,
1363
+ 0
1364
+ ]
1365
+ }
1366
+ ]
1367
+ },
1368
+ "left_sleeve_b": {
1369
+ "translation": [
1370
+ 63.1462686655216,
1371
+ 93.89395203562643,
1372
+ -12.5
1373
+ ],
1374
+ "rotation": [
1375
+ 0.0,
1376
+ 0.0,
1377
+ -50.48299999999997
1378
+ ],
1379
+ "vertices": [
1380
+ [
1381
+ 0.0,
1382
+ 0.0
1383
+ ],
1384
+ [
1385
+ 0.0,
1386
+ -18.70773098482538
1387
+ ],
1388
+ [
1389
+ -38.283061457383745,
1390
+ -18.70773098482538
1391
+ ],
1392
+ [
1393
+ -38.59156179316456,
1394
+ -18.26821330891046
1395
+ ],
1396
+ [
1397
+ -53.973272929069736,
1398
+ -0.5315642505301881
1399
+ ],
1400
+ [
1401
+ -53.9697,
1402
+ 0.0
1403
+ ]
1404
+ ],
1405
+ "edges": [
1406
+ {
1407
+ "endpoints": [
1408
+ 0,
1409
+ 1
1410
+ ]
1411
+ },
1412
+ {
1413
+ "endpoints": [
1414
+ 1,
1415
+ 2
1416
+ ]
1417
+ },
1418
+ {
1419
+ "endpoints": [
1420
+ 2,
1421
+ 3
1422
+ ],
1423
+ "curvature": {
1424
+ "type": "cubic",
1425
+ "params": [
1426
+ [
1427
+ 0.33534269062955746,
1428
+ -0.00821617932857873
1429
+ ],
1430
+ [
1431
+ 0.6686351589870839,
1432
+ -0.008051543005962211
1433
+ ]
1434
+ ]
1435
+ }
1436
+ },
1437
+ {
1438
+ "endpoints": [
1439
+ 3,
1440
+ 4
1441
+ ],
1442
+ "curvature": {
1443
+ "type": "cubic",
1444
+ "params": [
1445
+ [
1446
+ 0.33573280944728834,
1447
+ -0.02627863415950396
1448
+ ],
1449
+ [
1450
+ 0.6213145244254634,
1451
+ 0.3104039319894889
1452
+ ]
1453
+ ]
1454
+ }
1455
+ },
1456
+ {
1457
+ "endpoints": [
1458
+ 4,
1459
+ 5
1460
+ ],
1461
+ "curvature": {
1462
+ "type": "cubic",
1463
+ "params": [
1464
+ [
1465
+ 0.3380699613329664,
1466
+ 0.0060373677151341325
1467
+ ],
1468
+ [
1469
+ 0.6713615235922001,
1470
+ 0.005982609693050386
1471
+ ]
1472
+ ]
1473
+ }
1474
+ },
1475
+ {
1476
+ "endpoints": [
1477
+ 5,
1478
+ 0
1479
+ ]
1480
+ }
1481
+ ]
1482
+ },
1483
+ "left_btorso": {
1484
+ "translation": [
1485
+ 0.0,
1486
+ 103.895647186128,
1487
+ -20.0
1488
+ ],
1489
+ "rotation": [
1490
+ 0.0,
1491
+ 0.0,
1492
+ 0.0
1493
+ ],
1494
+ "vertices": [
1495
+ [
1496
+ 0.0,
1497
+ 0.36889166233942916
1498
+ ],
1499
+ [
1500
+ 0.0,
1501
+ 32.66147825518972
1502
+ ],
1503
+ [
1504
+ 9.4664,
1505
+ 38.374174026708005
1506
+ ],
1507
+ [
1508
+ 17.2284,
1509
+ 35.288798041611095
1510
+ ],
1511
+ [
1512
+ 17.184234849367538,
1513
+ 34.758881544252446
1514
+ ],
1515
+ [
1516
+ 23.83805,
1517
+ 13.773738041611095
1518
+ ],
1519
+ [
1520
+ 23.83805,
1521
+ 12.233866666666664
1522
+ ],
1523
+ [
1524
+ 23.126358333333332,
1525
+ -2.0
1526
+ ],
1527
+ [
1528
+ 22.952157983833775,
1529
+ -1.9628545543963698
1530
+ ],
1531
+ [
1532
+ 14.916717524779742,
1533
+ -0.5550002787973305
1534
+ ],
1535
+ [
1536
+ 15.282781625426587,
1537
+ 10.242436235402488
1538
+ ],
1539
+ [
1540
+ 13.149513068978942,
1541
+ -0.34849401033276073
1542
+ ],
1543
+ [
1544
+ 8.609766328346904,
1545
+ 0.06196036718399833
1546
+ ],
1547
+ [
1548
+ 8.48693346149262,
1549
+ 12.065376393017543
1550
+ ],
1551
+ [
1552
+ 6.834173497862042,
1553
+ 0.17565525646278113
1554
+ ]
1555
+ ],
1556
+ "edges": [
1557
+ {
1558
+ "endpoints": [
1559
+ 0,
1560
+ 1
1561
+ ]
1562
+ },
1563
+ {
1564
+ "endpoints": [
1565
+ 1,
1566
+ 2
1567
+ ],
1568
+ "curvature": {
1569
+ "type": "circle",
1570
+ "params": [
1571
+ 10.699643988343615,
1572
+ 0,
1573
+ 1
1574
+ ]
1575
+ }
1576
+ },
1577
+ {
1578
+ "endpoints": [
1579
+ 2,
1580
+ 3
1581
+ ]
1582
+ },
1583
+ {
1584
+ "endpoints": [
1585
+ 3,
1586
+ 4
1587
+ ],
1588
+ "curvature": {
1589
+ "type": "cubic",
1590
+ "params": [
1591
+ [
1592
+ 0.3352063417340786,
1593
+ 0.00023588113266078883
1594
+ ],
1595
+ [
1596
+ 0.6685430225322764,
1597
+ 0.00021546824748456243
1598
+ ]
1599
+ ]
1600
+ }
1601
+ },
1602
+ {
1603
+ "endpoints": [
1604
+ 4,
1605
+ 5
1606
+ ],
1607
+ "curvature": {
1608
+ "type": "cubic",
1609
+ "params": [
1610
+ [
1611
+ 0.49595217713182893,
1612
+ -0.2043546603132496
1613
+ ],
1614
+ [
1615
+ 0.7953707772626827,
1616
+ -0.35074597383647943
1617
+ ]
1618
+ ]
1619
+ }
1620
+ },
1621
+ {
1622
+ "endpoints": [
1623
+ 5,
1624
+ 6
1625
+ ]
1626
+ },
1627
+ {
1628
+ "endpoints": [
1629
+ 6,
1630
+ 7
1631
+ ]
1632
+ },
1633
+ {
1634
+ "endpoints": [
1635
+ 7,
1636
+ 8
1637
+ ],
1638
+ "curvature": {
1639
+ "type": "quadratic",
1640
+ "params": [
1641
+ [
1642
+ 0.5000558765910527,
1643
+ -0.00038784390855770744
1644
+ ]
1645
+ ]
1646
+ }
1647
+ },
1648
+ {
1649
+ "endpoints": [
1650
+ 8,
1651
+ 9
1652
+ ],
1653
+ "curvature": {
1654
+ "type": "quadratic",
1655
+ "params": [
1656
+ [
1657
+ 0.5019243166361619,
1658
+ -0.018010083991666603
1659
+ ]
1660
+ ]
1661
+ }
1662
+ },
1663
+ {
1664
+ "endpoints": [
1665
+ 9,
1666
+ 10
1667
+ ]
1668
+ },
1669
+ {
1670
+ "endpoints": [
1671
+ 10,
1672
+ 11
1673
+ ]
1674
+ },
1675
+ {
1676
+ "endpoints": [
1677
+ 11,
1678
+ 12
1679
+ ],
1680
+ "curvature": {
1681
+ "type": "quadratic",
1682
+ "params": [
1683
+ [
1684
+ 0.5003470519620661,
1685
+ -0.009422105541958865
1686
+ ]
1687
+ ]
1688
+ }
1689
+ },
1690
+ {
1691
+ "endpoints": [
1692
+ 12,
1693
+ 13
1694
+ ]
1695
+ },
1696
+ {
1697
+ "endpoints": [
1698
+ 13,
1699
+ 14
1700
+ ]
1701
+ },
1702
+ {
1703
+ "endpoints": [
1704
+ 14,
1705
+ 0
1706
+ ],
1707
+ "curvature": {
1708
+ "type": "quadratic",
1709
+ "params": [
1710
+ [
1711
+ 0.4996450528168853,
1712
+ -0.014147551785309244
1713
+ ]
1714
+ ]
1715
+ }
1716
+ }
1717
+ ]
1718
+ },
1719
+ "left_ftorso": {
1720
+ "translation": [
1721
+ 0.0,
1722
+ 97.85775552378857,
1723
+ 25.0
1724
+ ],
1725
+ "rotation": [
1726
+ 0.0,
1727
+ 0.0,
1728
+ 0.0
1729
+ ],
1730
+ "vertices": [
1731
+ [
1732
+ 0.0,
1733
+ 0.0
1734
+ ],
1735
+ [
1736
+ 0.08905834079065551,
1737
+ 0.0
1738
+ ],
1739
+ [
1740
+ 8.473150131373654,
1741
+ 0.0
1742
+ ],
1743
+ [
1744
+ 9.634250131373655,
1745
+ 12.757752334184888
1746
+ ],
1747
+ [
1748
+ 10.795350131373658,
1749
+ 2.8438747969799893e-16
1750
+ ],
1751
+ [
1752
+ 24.921200000000002,
1753
+ 0.0
1754
+ ],
1755
+ [
1756
+ 26.082300000000004,
1757
+ 14.233866642059992
1758
+ ],
1759
+ [
1760
+ 13.003468750843743,
1761
+ 16.06836664205999
1762
+ ],
1763
+ [
1764
+ 26.082300000000004,
1765
+ 17.90286664205999
1766
+ ],
1767
+ [
1768
+ 25.526504666141484,
1769
+ 19.506260591251273
1770
+ ],
1771
+ [
1772
+ 24.996302137010776,
1773
+ 19.59242892249056
1774
+ ],
1775
+ [
1776
+ 17.068593301490633,
1777
+ 41.021320591251275
1778
+ ],
1779
+ [
1780
+ 9.466400000000007,
1781
+ 44.043173444839624
1782
+ ],
1783
+ [
1784
+ 0.0,
1785
+ 34.89594151313412
1786
+ ]
1787
+ ],
1788
+ "edges": [
1789
+ {
1790
+ "endpoints": [
1791
+ 0,
1792
+ 1
1793
+ ]
1794
+ },
1795
+ {
1796
+ "endpoints": [
1797
+ 1,
1798
+ 2
1799
+ ]
1800
+ },
1801
+ {
1802
+ "endpoints": [
1803
+ 2,
1804
+ 3
1805
+ ]
1806
+ },
1807
+ {
1808
+ "endpoints": [
1809
+ 3,
1810
+ 4
1811
+ ]
1812
+ },
1813
+ {
1814
+ "endpoints": [
1815
+ 4,
1816
+ 5
1817
+ ]
1818
+ },
1819
+ {
1820
+ "endpoints": [
1821
+ 5,
1822
+ 6
1823
+ ]
1824
+ },
1825
+ {
1826
+ "endpoints": [
1827
+ 6,
1828
+ 7
1829
+ ]
1830
+ },
1831
+ {
1832
+ "endpoints": [
1833
+ 7,
1834
+ 8
1835
+ ]
1836
+ },
1837
+ {
1838
+ "endpoints": [
1839
+ 8,
1840
+ 9
1841
+ ]
1842
+ },
1843
+ {
1844
+ "endpoints": [
1845
+ 9,
1846
+ 10
1847
+ ],
1848
+ "curvature": {
1849
+ "type": "cubic",
1850
+ "params": [
1851
+ [
1852
+ 0.33953416569974404,
1853
+ 0.005610518980133189
1854
+ ],
1855
+ [
1856
+ 0.6728203772781454,
1857
+ 0.005595060073123807
1858
+ ]
1859
+ ]
1860
+ }
1861
+ },
1862
+ {
1863
+ "endpoints": [
1864
+ 10,
1865
+ 11
1866
+ ],
1867
+ "curvature": {
1868
+ "type": "cubic",
1869
+ "params": [
1870
+ [
1871
+ 0.19564811958837647,
1872
+ 0.3319741548667245
1873
+ ],
1874
+ [
1875
+ 0.5000949830318455,
1876
+ 0.1883302341344098
1877
+ ]
1878
+ ]
1879
+ }
1880
+ },
1881
+ {
1882
+ "endpoints": [
1883
+ 11,
1884
+ 12
1885
+ ]
1886
+ },
1887
+ {
1888
+ "endpoints": [
1889
+ 12,
1890
+ 13
1891
+ ],
1892
+ "curvature": {
1893
+ "type": "circle",
1894
+ "params": [
1895
+ 9.471968255871255,
1896
+ 0,
1897
+ 0
1898
+ ]
1899
+ }
1900
+ },
1901
+ {
1902
+ "endpoints": [
1903
+ 13,
1904
+ 0
1905
+ ]
1906
+ }
1907
+ ]
1908
+ }
1909
+ },
1910
+ "stitches": [
1911
+ [
1912
+ {
1913
+ "panel": "pant_b_r",
1914
+ "edge": 3
1915
+ },
1916
+ {
1917
+ "panel": "pant_b_r",
1918
+ "edge": 4
1919
+ }
1920
+ ],
1921
+ [
1922
+ {
1923
+ "panel": "pant_b_r",
1924
+ "edge": 7
1925
+ },
1926
+ {
1927
+ "panel": "pant_b_r",
1928
+ "edge": 8
1929
+ }
1930
+ ],
1931
+ [
1932
+ {
1933
+ "panel": "pant_f_r",
1934
+ "edge": 8
1935
+ },
1936
+ {
1937
+ "panel": "pant_b_r",
1938
+ "edge": 0
1939
+ }
1940
+ ],
1941
+ [
1942
+ {
1943
+ "panel": "pant_f_r",
1944
+ "edge": 7
1945
+ },
1946
+ {
1947
+ "panel": "pant_b_r",
1948
+ "edge": 1
1949
+ }
1950
+ ],
1951
+ [
1952
+ {
1953
+ "panel": "pant_f_r",
1954
+ "edge": 1
1955
+ },
1956
+ {
1957
+ "panel": "pant_b_r",
1958
+ "edge": 13
1959
+ }
1960
+ ],
1961
+ [
1962
+ {
1963
+ "panel": "pant_b_l",
1964
+ "edge": 10
1965
+ },
1966
+ {
1967
+ "panel": "pant_b_l",
1968
+ "edge": 9
1969
+ }
1970
+ ],
1971
+ [
1972
+ {
1973
+ "panel": "pant_b_l",
1974
+ "edge": 7
1975
+ },
1976
+ {
1977
+ "panel": "pant_b_l",
1978
+ "edge": 6
1979
+ }
1980
+ ],
1981
+ [
1982
+ {
1983
+ "panel": "pant_f_l",
1984
+ "edge": 0
1985
+ },
1986
+ {
1987
+ "panel": "pant_b_l",
1988
+ "edge": 13
1989
+ }
1990
+ ],
1991
+ [
1992
+ {
1993
+ "panel": "pant_f_l",
1994
+ "edge": 1
1995
+ },
1996
+ {
1997
+ "panel": "pant_b_l",
1998
+ "edge": 12
1999
+ }
2000
+ ],
2001
+ [
2002
+ {
2003
+ "panel": "pant_f_l",
2004
+ "edge": 7
2005
+ },
2006
+ {
2007
+ "panel": "pant_b_l",
2008
+ "edge": 1
2009
+ }
2010
+ ],
2011
+ [
2012
+ {
2013
+ "panel": "pant_f_r",
2014
+ "edge": 3
2015
+ },
2016
+ {
2017
+ "panel": "pant_f_l",
2018
+ "edge": 5
2019
+ }
2020
+ ],
2021
+ [
2022
+ {
2023
+ "panel": "pant_f_r",
2024
+ "edge": 2
2025
+ },
2026
+ {
2027
+ "panel": "pant_f_l",
2028
+ "edge": 6
2029
+ }
2030
+ ],
2031
+ [
2032
+ {
2033
+ "panel": "pant_b_r",
2034
+ "edge": 11
2035
+ },
2036
+ {
2037
+ "panel": "pant_b_l",
2038
+ "edge": 3
2039
+ }
2040
+ ],
2041
+ [
2042
+ {
2043
+ "panel": "pant_b_r",
2044
+ "edge": 12
2045
+ },
2046
+ {
2047
+ "panel": "pant_b_l",
2048
+ "edge": 2
2049
+ }
2050
+ ],
2051
+ [
2052
+ {
2053
+ "panel": "right_sleeve_f",
2054
+ "edge": 3
2055
+ },
2056
+ {
2057
+ "panel": "right_sleeve_b",
2058
+ "edge": 0
2059
+ }
2060
+ ],
2061
+ [
2062
+ {
2063
+ "panel": "right_sleeve_f",
2064
+ "edge": 1
2065
+ },
2066
+ {
2067
+ "panel": "right_sleeve_b",
2068
+ "edge": 4
2069
+ }
2070
+ ],
2071
+ [
2072
+ {
2073
+ "panel": "right_ftorso",
2074
+ "edge": 7
2075
+ },
2076
+ {
2077
+ "panel": "right_ftorso",
2078
+ "edge": 6
2079
+ }
2080
+ ],
2081
+ [
2082
+ {
2083
+ "panel": "right_ftorso",
2084
+ "edge": 11
2085
+ },
2086
+ {
2087
+ "panel": "right_ftorso",
2088
+ "edge": 10
2089
+ }
2090
+ ],
2091
+ [
2092
+ {
2093
+ "panel": "right_btorso",
2094
+ "edge": 6
2095
+ },
2096
+ {
2097
+ "panel": "right_btorso",
2098
+ "edge": 7
2099
+ }
2100
+ ],
2101
+ [
2102
+ {
2103
+ "panel": "right_btorso",
2104
+ "edge": 2
2105
+ },
2106
+ {
2107
+ "panel": "right_btorso",
2108
+ "edge": 3
2109
+ }
2110
+ ],
2111
+ [
2112
+ {
2113
+ "panel": "right_sleeve_f",
2114
+ "edge": 2
2115
+ },
2116
+ {
2117
+ "panel": "right_ftorso",
2118
+ "edge": 3
2119
+ }
2120
+ ],
2121
+ [
2122
+ {
2123
+ "panel": "right_sleeve_b",
2124
+ "edge": 3
2125
+ },
2126
+ {
2127
+ "panel": "right_ftorso",
2128
+ "edge": 4
2129
+ }
2130
+ ],
2131
+ [
2132
+ {
2133
+ "panel": "right_sleeve_b",
2134
+ "edge": 2
2135
+ },
2136
+ {
2137
+ "panel": "right_btorso",
2138
+ "edge": 12
2139
+ }
2140
+ ],
2141
+ [
2142
+ {
2143
+ "panel": "right_sleeve_b",
2144
+ "edge": 1
2145
+ },
2146
+ {
2147
+ "panel": "right_btorso",
2148
+ "edge": 13
2149
+ }
2150
+ ],
2151
+ [
2152
+ {
2153
+ "panel": "right_ftorso",
2154
+ "edge": 2
2155
+ },
2156
+ {
2157
+ "panel": "right_btorso",
2158
+ "edge": 14
2159
+ }
2160
+ ],
2161
+ [
2162
+ {
2163
+ "panel": "right_ftorso",
2164
+ "edge": 8
2165
+ },
2166
+ {
2167
+ "panel": "right_btorso",
2168
+ "edge": 10
2169
+ }
2170
+ ],
2171
+ [
2172
+ {
2173
+ "panel": "right_ftorso",
2174
+ "edge": 5
2175
+ },
2176
+ {
2177
+ "panel": "right_btorso",
2178
+ "edge": 11
2179
+ }
2180
+ ],
2181
+ [
2182
+ {
2183
+ "panel": "left_sleeve_f",
2184
+ "edge": 0
2185
+ },
2186
+ {
2187
+ "panel": "left_sleeve_b",
2188
+ "edge": 5
2189
+ }
2190
+ ],
2191
+ [
2192
+ {
2193
+ "panel": "left_sleeve_f",
2194
+ "edge": 2
2195
+ },
2196
+ {
2197
+ "panel": "left_sleeve_b",
2198
+ "edge": 1
2199
+ }
2200
+ ],
2201
+ [
2202
+ {
2203
+ "panel": "left_btorso",
2204
+ "edge": 10
2205
+ },
2206
+ {
2207
+ "panel": "left_btorso",
2208
+ "edge": 9
2209
+ }
2210
+ ],
2211
+ [
2212
+ {
2213
+ "panel": "left_btorso",
2214
+ "edge": 13
2215
+ },
2216
+ {
2217
+ "panel": "left_btorso",
2218
+ "edge": 12
2219
+ }
2220
+ ],
2221
+ [
2222
+ {
2223
+ "panel": "left_ftorso",
2224
+ "edge": 6
2225
+ },
2226
+ {
2227
+ "panel": "left_ftorso",
2228
+ "edge": 7
2229
+ }
2230
+ ],
2231
+ [
2232
+ {
2233
+ "panel": "left_ftorso",
2234
+ "edge": 2
2235
+ },
2236
+ {
2237
+ "panel": "left_ftorso",
2238
+ "edge": 3
2239
+ }
2240
+ ],
2241
+ [
2242
+ {
2243
+ "panel": "left_sleeve_f",
2244
+ "edge": 1
2245
+ },
2246
+ {
2247
+ "panel": "left_ftorso",
2248
+ "edge": 10
2249
+ }
2250
+ ],
2251
+ [
2252
+ {
2253
+ "panel": "left_sleeve_b",
2254
+ "edge": 2
2255
+ },
2256
+ {
2257
+ "panel": "left_ftorso",
2258
+ "edge": 9
2259
+ }
2260
+ ],
2261
+ [
2262
+ {
2263
+ "panel": "left_sleeve_b",
2264
+ "edge": 3
2265
+ },
2266
+ {
2267
+ "panel": "left_btorso",
2268
+ "edge": 4
2269
+ }
2270
+ ],
2271
+ [
2272
+ {
2273
+ "panel": "left_sleeve_b",
2274
+ "edge": 4
2275
+ },
2276
+ {
2277
+ "panel": "left_btorso",
2278
+ "edge": 3
2279
+ }
2280
+ ],
2281
+ [
2282
+ {
2283
+ "panel": "left_ftorso",
2284
+ "edge": 11
2285
+ },
2286
+ {
2287
+ "panel": "left_btorso",
2288
+ "edge": 2
2289
+ }
2290
+ ],
2291
+ [
2292
+ {
2293
+ "panel": "left_ftorso",
2294
+ "edge": 5
2295
+ },
2296
+ {
2297
+ "panel": "left_btorso",
2298
+ "edge": 6
2299
+ }
2300
+ ],
2301
+ [
2302
+ {
2303
+ "panel": "left_ftorso",
2304
+ "edge": 8
2305
+ },
2306
+ {
2307
+ "panel": "left_btorso",
2308
+ "edge": 5
2309
+ }
2310
+ ],
2311
+ [
2312
+ {
2313
+ "panel": "right_ftorso",
2314
+ "edge": 0
2315
+ },
2316
+ {
2317
+ "panel": "left_ftorso",
2318
+ "edge": 13
2319
+ }
2320
+ ],
2321
+ [
2322
+ {
2323
+ "panel": "right_btorso",
2324
+ "edge": 16
2325
+ },
2326
+ {
2327
+ "panel": "left_btorso",
2328
+ "edge": 0
2329
+ }
2330
+ ],
2331
+ [
2332
+ {
2333
+ "panel": "right_ftorso",
2334
+ "edge": 9
2335
+ },
2336
+ {
2337
+ "panel": "pant_f_r",
2338
+ "edge": 6
2339
+ }
2340
+ ],
2341
+ [
2342
+ {
2343
+ "panel": "right_ftorso",
2344
+ "edge": 12
2345
+ },
2346
+ {
2347
+ "panel": "pant_f_r",
2348
+ "edge": 5
2349
+ }
2350
+ ],
2351
+ [
2352
+ {
2353
+ "panel": "left_ftorso",
2354
+ "edge": 0
2355
+ },
2356
+ {
2357
+ "panel": "pant_f_r",
2358
+ "edge": 4
2359
+ }
2360
+ ],
2361
+ [
2362
+ {
2363
+ "panel": "left_ftorso",
2364
+ "edge": 1
2365
+ },
2366
+ {
2367
+ "panel": "pant_f_l",
2368
+ "edge": 4
2369
+ }
2370
+ ],
2371
+ [
2372
+ {
2373
+ "panel": "left_ftorso",
2374
+ "edge": 4
2375
+ },
2376
+ {
2377
+ "panel": "pant_f_l",
2378
+ "edge": 3
2379
+ }
2380
+ ],
2381
+ [
2382
+ {
2383
+ "panel": "left_btorso",
2384
+ "edge": 7
2385
+ },
2386
+ {
2387
+ "panel": "pant_f_l",
2388
+ "edge": 2
2389
+ }
2390
+ ],
2391
+ [
2392
+ {
2393
+ "panel": "left_btorso",
2394
+ "edge": 8
2395
+ },
2396
+ {
2397
+ "panel": "pant_b_l",
2398
+ "edge": 11
2399
+ }
2400
+ ],
2401
+ [
2402
+ {
2403
+ "panel": "left_btorso",
2404
+ "edge": 11
2405
+ },
2406
+ {
2407
+ "panel": "pant_b_l",
2408
+ "edge": 8
2409
+ }
2410
+ ],
2411
+ [
2412
+ {
2413
+ "panel": "left_btorso",
2414
+ "edge": 14
2415
+ },
2416
+ {
2417
+ "panel": "pant_b_l",
2418
+ "edge": 5
2419
+ }
2420
+ ],
2421
+ [
2422
+ {
2423
+ "panel": "right_btorso",
2424
+ "edge": 0
2425
+ },
2426
+ {
2427
+ "panel": "pant_b_l",
2428
+ "edge": 4
2429
+ }
2430
+ ],
2431
+ [
2432
+ {
2433
+ "panel": "right_btorso",
2434
+ "edge": 1
2435
+ },
2436
+ {
2437
+ "panel": "pant_b_r",
2438
+ "edge": 10
2439
+ }
2440
+ ],
2441
+ [
2442
+ {
2443
+ "panel": "right_btorso",
2444
+ "edge": 4
2445
+ },
2446
+ {
2447
+ "panel": "pant_b_r",
2448
+ "edge": 9
2449
+ }
2450
+ ],
2451
+ [
2452
+ {
2453
+ "panel": "right_btorso",
2454
+ "edge": 5
2455
+ },
2456
+ {
2457
+ "panel": "pant_b_r",
2458
+ "edge": 6
2459
+ }
2460
+ ],
2461
+ [
2462
+ {
2463
+ "panel": "right_btorso",
2464
+ "edge": 8
2465
+ },
2466
+ {
2467
+ "panel": "pant_b_r",
2468
+ "edge": 5
2469
+ }
2470
+ ],
2471
+ [
2472
+ {
2473
+ "panel": "right_btorso",
2474
+ "edge": 9
2475
+ },
2476
+ {
2477
+ "panel": "pant_b_r",
2478
+ "edge": 2
2479
+ }
2480
+ ]
2481
+ ],
2482
+ "panel_order": [
2483
+ "right_sleeve_b",
2484
+ "right_sleeve_f",
2485
+ "pant_b_r",
2486
+ "pant_f_r",
2487
+ "right_btorso",
2488
+ "right_ftorso",
2489
+ "pant_b_l",
2490
+ "pant_f_l",
2491
+ "left_btorso",
2492
+ "left_ftorso",
2493
+ "left_sleeve_b",
2494
+ "left_sleeve_f"
2495
+ ]
2496
+ },
2497
+ "parameters": {},
2498
+ "parameter_order": [],
2499
+ "properties": {
2500
+ "curvature_coords": "relative",
2501
+ "normalize_panel_translation": false,
2502
+ "normalized_edge_loops": true,
2503
+ "units_in_meter": 100
2504
+ }
2505
+ }
GarmentCode/assets/Patterns/shirt_mean_specification.json ADDED
@@ -0,0 +1,1058 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "pattern": {
3
+ "panels": {
4
+ "left_btorso": {
5
+ "translation": [
6
+ 0.0,
7
+ 94.66024668570651,
8
+ -20.0
9
+ ],
10
+ "rotation": [
11
+ 0.0,
12
+ 0.0,
13
+ 0.0
14
+ ],
15
+ "vertices": [
16
+ [
17
+ 0.0,
18
+ 0.0
19
+ ],
20
+ [
21
+ 0.0,
22
+ 40.58043003350011
23
+ ],
24
+ [
25
+ 12.8474,
26
+ 45.89674322821761
27
+ ],
28
+ [
29
+ 17.228400000000004,
30
+ 44.155306096702866
31
+ ],
32
+ [
33
+ 17.28924306871916,
34
+ 43.41003858511645
35
+ ],
36
+ [
37
+ 26.221855,
38
+ 26.140246096702864
39
+ ],
40
+ [
41
+ 26.221855,
42
+ 0.0
43
+ ]
44
+ ],
45
+ "edges": [
46
+ {
47
+ "endpoints": [
48
+ 0,
49
+ 1
50
+ ]
51
+ },
52
+ {
53
+ "endpoints": [
54
+ 1,
55
+ 2
56
+ ],
57
+ "curvature": {
58
+ "type": "quadratic",
59
+ "params": [
60
+ [
61
+ 0.15000000000000002,
62
+ -0.1
63
+ ]
64
+ ]
65
+ }
66
+ },
67
+ {
68
+ "endpoints": [
69
+ 2,
70
+ 3
71
+ ]
72
+ },
73
+ {
74
+ "endpoints": [
75
+ 3,
76
+ 4
77
+ ],
78
+ "curvature": {
79
+ "type": "cubic",
80
+ "params": [
81
+ [
82
+ 0.3362996181255371,
83
+ 0.00035561086727752493
84
+ ],
85
+ [
86
+ 0.6696413214557415,
87
+ 0.000304683330208262
88
+ ]
89
+ ]
90
+ }
91
+ },
92
+ {
93
+ "endpoints": [
94
+ 4,
95
+ 5
96
+ ],
97
+ "curvature": {
98
+ "type": "cubic",
99
+ "params": [
100
+ [
101
+ 0.49354586181258675,
102
+ -0.2068129166538814
103
+ ],
104
+ [
105
+ 0.7926359002814091,
106
+ -0.3511169364913611
107
+ ]
108
+ ]
109
+ }
110
+ },
111
+ {
112
+ "endpoints": [
113
+ 5,
114
+ 6
115
+ ]
116
+ },
117
+ {
118
+ "endpoints": [
119
+ 6,
120
+ 0
121
+ ]
122
+ }
123
+ ]
124
+ },
125
+ "left_ftorso": {
126
+ "translation": [
127
+ 0.0,
128
+ 94.57103829637592,
129
+ 25.0
130
+ ],
131
+ "rotation": [
132
+ 0.0,
133
+ 0.0,
134
+ 0.0
135
+ ],
136
+ "vertices": [
137
+ [
138
+ 0.0,
139
+ 0.0
140
+ ],
141
+ [
142
+ 28.690530000000003,
143
+ 0.0
144
+ ],
145
+ [
146
+ 28.690530000000003,
147
+ 26.22945508918822
148
+ ],
149
+ [
150
+ 27.9380061020118,
151
+ 26.212914946368773
152
+ ],
153
+ [
154
+ 17.2284,
155
+ 44.244515089188226
156
+ ],
157
+ [
158
+ 12.8474,
159
+ 45.985951591486455
160
+ ],
161
+ [
162
+ 0.0,
163
+ 31.758244447465778
164
+ ]
165
+ ],
166
+ "edges": [
167
+ {
168
+ "endpoints": [
169
+ 0,
170
+ 1
171
+ ]
172
+ },
173
+ {
174
+ "endpoints": [
175
+ 1,
176
+ 2
177
+ ]
178
+ },
179
+ {
180
+ "endpoints": [
181
+ 2,
182
+ 3
183
+ ],
184
+ "curvature": {
185
+ "type": "cubic",
186
+ "params": [
187
+ [
188
+ 0.3428096078203796,
189
+ 0.008753178295583862
190
+ ],
191
+ [
192
+ 0.676031583087778,
193
+ 0.008715531749032087
194
+ ]
195
+ ]
196
+ }
197
+ },
198
+ {
199
+ "endpoints": [
200
+ 3,
201
+ 4
202
+ ],
203
+ "curvature": {
204
+ "type": "cubic",
205
+ "params": [
206
+ [
207
+ 0.19372096202165834,
208
+ 0.322540122492371
209
+ ],
210
+ [
211
+ 0.5003726893654397,
212
+ 0.1822675025368038
213
+ ]
214
+ ]
215
+ }
216
+ },
217
+ {
218
+ "endpoints": [
219
+ 4,
220
+ 5
221
+ ]
222
+ },
223
+ {
224
+ "endpoints": [
225
+ 5,
226
+ 6
227
+ ],
228
+ "curvature": {
229
+ "type": "quadratic",
230
+ "params": [
231
+ [
232
+ 0.5,
233
+ 0.3
234
+ ]
235
+ ]
236
+ }
237
+ },
238
+ {
239
+ "endpoints": [
240
+ 6,
241
+ 0
242
+ ]
243
+ }
244
+ ]
245
+ },
246
+ "left_sleeve_f": {
247
+ "translation": [
248
+ 53.57347770869189,
249
+ 111.1086631392047,
250
+ 17.5
251
+ ],
252
+ "rotation": [
253
+ 0.0,
254
+ 0.0,
255
+ -50.48299999999997
256
+ ],
257
+ "vertices": [
258
+ [
259
+ 0.0,
260
+ 0.0
261
+ ],
262
+ [
263
+ -31.204774210476085,
264
+ 0.0
265
+ ],
266
+ [
267
+ -22.76492578952392,
268
+ -21.25900713751968
269
+ ],
270
+ [
271
+ 0.0,
272
+ -21.25900713751968
273
+ ]
274
+ ],
275
+ "edges": [
276
+ {
277
+ "endpoints": [
278
+ 0,
279
+ 1
280
+ ]
281
+ },
282
+ {
283
+ "endpoints": [
284
+ 1,
285
+ 2
286
+ ],
287
+ "curvature": {
288
+ "type": "cubic",
289
+ "params": [
290
+ [
291
+ 0.3973662914003405,
292
+ -0.1498416610988617
293
+ ],
294
+ [
295
+ 0.6591952002566281,
296
+ 0.025928691992446788
297
+ ]
298
+ ]
299
+ }
300
+ },
301
+ {
302
+ "endpoints": [
303
+ 2,
304
+ 3
305
+ ]
306
+ },
307
+ {
308
+ "endpoints": [
309
+ 3,
310
+ 0
311
+ ]
312
+ }
313
+ ]
314
+ },
315
+ "left_sleeve_b": {
316
+ "translation": [
317
+ 53.57347770869189,
318
+ 111.1086631392047,
319
+ -12.5
320
+ ],
321
+ "rotation": [
322
+ 0.0,
323
+ 0.0,
324
+ -50.48299999999997
325
+ ],
326
+ "vertices": [
327
+ [
328
+ 0.0,
329
+ 0.0
330
+ ],
331
+ [
332
+ 0.0,
333
+ -21.259007137519678
334
+ ],
335
+ [
336
+ -22.76492578952392,
337
+ -21.259007137519678
338
+ ],
339
+ [
340
+ -23.017812246669145,
341
+ -20.549928308877696
342
+ ],
343
+ [
344
+ -31.2062986511695,
345
+ -0.7477987993325925
346
+ ],
347
+ [
348
+ -31.20477421047608,
349
+ 0.0
350
+ ]
351
+ ],
352
+ "edges": [
353
+ {
354
+ "endpoints": [
355
+ 0,
356
+ 1
357
+ ]
358
+ },
359
+ {
360
+ "endpoints": [
361
+ 1,
362
+ 2
363
+ ]
364
+ },
365
+ {
366
+ "endpoints": [
367
+ 2,
368
+ 3
369
+ ],
370
+ "curvature": {
371
+ "type": "cubic",
372
+ "params": [
373
+ [
374
+ 0.3381422696745128,
375
+ -0.00675750744885745
376
+ ],
377
+ [
378
+ 0.6713298287607794,
379
+ -0.006552681033887989
380
+ ]
381
+ ]
382
+ }
383
+ },
384
+ {
385
+ "endpoints": [
386
+ 3,
387
+ 4
388
+ ],
389
+ "curvature": {
390
+ "type": "cubic",
391
+ "params": [
392
+ [
393
+ 0.33975451217196817,
394
+ -0.010056311234005784
395
+ ],
396
+ [
397
+ 0.5517725654386645,
398
+ 0.1796260847071758
399
+ ]
400
+ ]
401
+ }
402
+ },
403
+ {
404
+ "endpoints": [
405
+ 4,
406
+ 5
407
+ ],
408
+ "curvature": {
409
+ "type": "cubic",
410
+ "params": [
411
+ [
412
+ 0.3382675258169162,
413
+ 0.005087462690011052
414
+ ],
415
+ [
416
+ 0.6715360336122662,
417
+ 0.00501956287580371
418
+ ]
419
+ ]
420
+ }
421
+ },
422
+ {
423
+ "endpoints": [
424
+ 5,
425
+ 0
426
+ ]
427
+ }
428
+ ]
429
+ },
430
+ "right_ftorso": {
431
+ "translation": [
432
+ 0.0,
433
+ 94.57103829637592,
434
+ 25.0
435
+ ],
436
+ "rotation": [
437
+ 0.0,
438
+ 0.0,
439
+ 0.0
440
+ ],
441
+ "vertices": [
442
+ [
443
+ 0,
444
+ 0
445
+ ],
446
+ [
447
+ 0.0,
448
+ 31.758244447465778
449
+ ],
450
+ [
451
+ -12.8474,
452
+ 45.985951591486455
453
+ ],
454
+ [
455
+ -17.2284,
456
+ 44.244515089188226
457
+ ],
458
+ [
459
+ -27.9380061020118,
460
+ 26.212914946368773
461
+ ],
462
+ [
463
+ -28.690530000000003,
464
+ 26.22945508918822
465
+ ],
466
+ [
467
+ -28.690530000000003,
468
+ 0
469
+ ]
470
+ ],
471
+ "edges": [
472
+ {
473
+ "endpoints": [
474
+ 0,
475
+ 1
476
+ ]
477
+ },
478
+ {
479
+ "endpoints": [
480
+ 1,
481
+ 2
482
+ ],
483
+ "curvature": {
484
+ "type": "quadratic",
485
+ "params": [
486
+ [
487
+ 0.5,
488
+ 0.3
489
+ ]
490
+ ]
491
+ }
492
+ },
493
+ {
494
+ "endpoints": [
495
+ 2,
496
+ 3
497
+ ]
498
+ },
499
+ {
500
+ "endpoints": [
501
+ 3,
502
+ 4
503
+ ],
504
+ "curvature": {
505
+ "type": "cubic",
506
+ "params": [
507
+ [
508
+ 0.49962731063456034,
509
+ 0.1822675025368038
510
+ ],
511
+ [
512
+ 0.8062790379783417,
513
+ 0.322540122492371
514
+ ]
515
+ ]
516
+ }
517
+ },
518
+ {
519
+ "endpoints": [
520
+ 4,
521
+ 5
522
+ ],
523
+ "curvature": {
524
+ "type": "cubic",
525
+ "params": [
526
+ [
527
+ 0.323968416912222,
528
+ 0.008715531749032087
529
+ ],
530
+ [
531
+ 0.6571903921796204,
532
+ 0.008753178295583862
533
+ ]
534
+ ]
535
+ }
536
+ },
537
+ {
538
+ "endpoints": [
539
+ 5,
540
+ 6
541
+ ]
542
+ },
543
+ {
544
+ "endpoints": [
545
+ 6,
546
+ 0
547
+ ]
548
+ }
549
+ ]
550
+ },
551
+ "right_sleeve_b": {
552
+ "translation": [
553
+ -53.57347770869188,
554
+ 111.10866313920468,
555
+ -12.5
556
+ ],
557
+ "rotation": [
558
+ 0.0,
559
+ 0.0,
560
+ 50.48299999999997
561
+ ],
562
+ "vertices": [
563
+ [
564
+ 0,
565
+ 0
566
+ ],
567
+ [
568
+ 31.20477421047608,
569
+ 0.0
570
+ ],
571
+ [
572
+ 31.2062986511695,
573
+ -0.7477987993325925
574
+ ],
575
+ [
576
+ 23.017812246669145,
577
+ -20.549928308877696
578
+ ],
579
+ [
580
+ 22.76492578952392,
581
+ -21.259007137519678
582
+ ],
583
+ [
584
+ 0,
585
+ -21.259007137519678
586
+ ]
587
+ ],
588
+ "edges": [
589
+ {
590
+ "endpoints": [
591
+ 0,
592
+ 1
593
+ ]
594
+ },
595
+ {
596
+ "endpoints": [
597
+ 1,
598
+ 2
599
+ ],
600
+ "curvature": {
601
+ "type": "cubic",
602
+ "params": [
603
+ [
604
+ 0.3284639663877338,
605
+ 0.00501956287580371
606
+ ],
607
+ [
608
+ 0.6617324741830838,
609
+ 0.005087462690011052
610
+ ]
611
+ ]
612
+ }
613
+ },
614
+ {
615
+ "endpoints": [
616
+ 2,
617
+ 3
618
+ ],
619
+ "curvature": {
620
+ "type": "cubic",
621
+ "params": [
622
+ [
623
+ 0.44822743456133546,
624
+ 0.1796260847071758
625
+ ],
626
+ [
627
+ 0.6602454878280318,
628
+ -0.010056311234005784
629
+ ]
630
+ ]
631
+ }
632
+ },
633
+ {
634
+ "endpoints": [
635
+ 3,
636
+ 4
637
+ ],
638
+ "curvature": {
639
+ "type": "cubic",
640
+ "params": [
641
+ [
642
+ 0.32867017123922065,
643
+ -0.006552681033887989
644
+ ],
645
+ [
646
+ 0.6618577303254872,
647
+ -0.00675750744885745
648
+ ]
649
+ ]
650
+ }
651
+ },
652
+ {
653
+ "endpoints": [
654
+ 4,
655
+ 5
656
+ ]
657
+ },
658
+ {
659
+ "endpoints": [
660
+ 5,
661
+ 0
662
+ ]
663
+ }
664
+ ]
665
+ },
666
+ "right_sleeve_f": {
667
+ "translation": [
668
+ -53.57347770869188,
669
+ 111.10866313920468,
670
+ 17.5
671
+ ],
672
+ "rotation": [
673
+ 0.0,
674
+ 0.0,
675
+ 50.48299999999997
676
+ ],
677
+ "vertices": [
678
+ [
679
+ 0,
680
+ 0
681
+ ],
682
+ [
683
+ 0,
684
+ -21.25900713751968
685
+ ],
686
+ [
687
+ 22.76492578952392,
688
+ -21.25900713751968
689
+ ],
690
+ [
691
+ 31.204774210476085,
692
+ 0.0
693
+ ]
694
+ ],
695
+ "edges": [
696
+ {
697
+ "endpoints": [
698
+ 0,
699
+ 1
700
+ ]
701
+ },
702
+ {
703
+ "endpoints": [
704
+ 1,
705
+ 2
706
+ ]
707
+ },
708
+ {
709
+ "endpoints": [
710
+ 2,
711
+ 3
712
+ ],
713
+ "curvature": {
714
+ "type": "cubic",
715
+ "params": [
716
+ [
717
+ 0.3408047997433718,
718
+ 0.025928691992446788
719
+ ],
720
+ [
721
+ 0.6026337085996595,
722
+ -0.1498416610988617
723
+ ]
724
+ ]
725
+ }
726
+ },
727
+ {
728
+ "endpoints": [
729
+ 3,
730
+ 0
731
+ ]
732
+ }
733
+ ]
734
+ },
735
+ "right_btorso": {
736
+ "translation": [
737
+ 0.0,
738
+ 94.66024668570651,
739
+ -20.0
740
+ ],
741
+ "rotation": [
742
+ 0.0,
743
+ 0.0,
744
+ 0.0
745
+ ],
746
+ "vertices": [
747
+ [
748
+ 0,
749
+ 0
750
+ ],
751
+ [
752
+ -26.221855,
753
+ 0
754
+ ],
755
+ [
756
+ -26.221855,
757
+ 26.140246096702864
758
+ ],
759
+ [
760
+ -17.28924306871916,
761
+ 43.41003858511645
762
+ ],
763
+ [
764
+ -17.228400000000004,
765
+ 44.155306096702866
766
+ ],
767
+ [
768
+ -12.8474,
769
+ 45.89674322821761
770
+ ],
771
+ [
772
+ 0.0,
773
+ 40.58043003350011
774
+ ]
775
+ ],
776
+ "edges": [
777
+ {
778
+ "endpoints": [
779
+ 0,
780
+ 1
781
+ ]
782
+ },
783
+ {
784
+ "endpoints": [
785
+ 1,
786
+ 2
787
+ ]
788
+ },
789
+ {
790
+ "endpoints": [
791
+ 2,
792
+ 3
793
+ ],
794
+ "curvature": {
795
+ "type": "cubic",
796
+ "params": [
797
+ [
798
+ 0.2073640997185909,
799
+ -0.3511169364913611
800
+ ],
801
+ [
802
+ 0.5064541381874132,
803
+ -0.2068129166538814
804
+ ]
805
+ ]
806
+ }
807
+ },
808
+ {
809
+ "endpoints": [
810
+ 3,
811
+ 4
812
+ ],
813
+ "curvature": {
814
+ "type": "cubic",
815
+ "params": [
816
+ [
817
+ 0.3303586785442585,
818
+ 0.000304683330208262
819
+ ],
820
+ [
821
+ 0.6637003818744629,
822
+ 0.00035561086727752493
823
+ ]
824
+ ]
825
+ }
826
+ },
827
+ {
828
+ "endpoints": [
829
+ 4,
830
+ 5
831
+ ]
832
+ },
833
+ {
834
+ "endpoints": [
835
+ 5,
836
+ 6
837
+ ],
838
+ "curvature": {
839
+ "type": "quadratic",
840
+ "params": [
841
+ [
842
+ 0.85,
843
+ -0.1
844
+ ]
845
+ ]
846
+ }
847
+ },
848
+ {
849
+ "endpoints": [
850
+ 6,
851
+ 0
852
+ ]
853
+ }
854
+ ]
855
+ }
856
+ },
857
+ "stitches": [
858
+ [
859
+ {
860
+ "panel": "left_sleeve_f",
861
+ "edge": 0
862
+ },
863
+ {
864
+ "panel": "left_sleeve_b",
865
+ "edge": 5
866
+ }
867
+ ],
868
+ [
869
+ {
870
+ "panel": "left_sleeve_f",
871
+ "edge": 2
872
+ },
873
+ {
874
+ "panel": "left_sleeve_b",
875
+ "edge": 1
876
+ }
877
+ ],
878
+ [
879
+ {
880
+ "panel": "left_sleeve_f",
881
+ "edge": 1
882
+ },
883
+ {
884
+ "panel": "left_ftorso",
885
+ "edge": 3
886
+ }
887
+ ],
888
+ [
889
+ {
890
+ "panel": "left_sleeve_b",
891
+ "edge": 2
892
+ },
893
+ {
894
+ "panel": "left_ftorso",
895
+ "edge": 2
896
+ }
897
+ ],
898
+ [
899
+ {
900
+ "panel": "left_sleeve_b",
901
+ "edge": 3
902
+ },
903
+ {
904
+ "panel": "left_btorso",
905
+ "edge": 4
906
+ }
907
+ ],
908
+ [
909
+ {
910
+ "panel": "left_sleeve_b",
911
+ "edge": 4
912
+ },
913
+ {
914
+ "panel": "left_btorso",
915
+ "edge": 3
916
+ }
917
+ ],
918
+ [
919
+ {
920
+ "panel": "left_ftorso",
921
+ "edge": 4
922
+ },
923
+ {
924
+ "panel": "left_btorso",
925
+ "edge": 2
926
+ }
927
+ ],
928
+ [
929
+ {
930
+ "panel": "left_ftorso",
931
+ "edge": 1
932
+ },
933
+ {
934
+ "panel": "left_btorso",
935
+ "edge": 5
936
+ }
937
+ ],
938
+ [
939
+ {
940
+ "panel": "right_sleeve_f",
941
+ "edge": 3
942
+ },
943
+ {
944
+ "panel": "right_sleeve_b",
945
+ "edge": 0
946
+ }
947
+ ],
948
+ [
949
+ {
950
+ "panel": "right_sleeve_f",
951
+ "edge": 1
952
+ },
953
+ {
954
+ "panel": "right_sleeve_b",
955
+ "edge": 4
956
+ }
957
+ ],
958
+ [
959
+ {
960
+ "panel": "right_sleeve_f",
961
+ "edge": 2
962
+ },
963
+ {
964
+ "panel": "right_ftorso",
965
+ "edge": 3
966
+ }
967
+ ],
968
+ [
969
+ {
970
+ "panel": "right_sleeve_b",
971
+ "edge": 3
972
+ },
973
+ {
974
+ "panel": "right_ftorso",
975
+ "edge": 4
976
+ }
977
+ ],
978
+ [
979
+ {
980
+ "panel": "right_sleeve_b",
981
+ "edge": 2
982
+ },
983
+ {
984
+ "panel": "right_btorso",
985
+ "edge": 2
986
+ }
987
+ ],
988
+ [
989
+ {
990
+ "panel": "right_sleeve_b",
991
+ "edge": 1
992
+ },
993
+ {
994
+ "panel": "right_btorso",
995
+ "edge": 3
996
+ }
997
+ ],
998
+ [
999
+ {
1000
+ "panel": "right_ftorso",
1001
+ "edge": 2
1002
+ },
1003
+ {
1004
+ "panel": "right_btorso",
1005
+ "edge": 4
1006
+ }
1007
+ ],
1008
+ [
1009
+ {
1010
+ "panel": "right_ftorso",
1011
+ "edge": 5
1012
+ },
1013
+ {
1014
+ "panel": "right_btorso",
1015
+ "edge": 1
1016
+ }
1017
+ ],
1018
+ [
1019
+ {
1020
+ "panel": "right_ftorso",
1021
+ "edge": 0
1022
+ },
1023
+ {
1024
+ "panel": "left_ftorso",
1025
+ "edge": 6
1026
+ }
1027
+ ],
1028
+ [
1029
+ {
1030
+ "panel": "right_btorso",
1031
+ "edge": 6
1032
+ },
1033
+ {
1034
+ "panel": "left_btorso",
1035
+ "edge": 0
1036
+ }
1037
+ ]
1038
+ ],
1039
+ "panel_order": [
1040
+ "right_sleeve_b",
1041
+ "right_sleeve_f",
1042
+ "right_btorso",
1043
+ "right_ftorso",
1044
+ "left_btorso",
1045
+ "left_ftorso",
1046
+ "left_sleeve_b",
1047
+ "left_sleeve_f"
1048
+ ]
1049
+ },
1050
+ "parameters": {},
1051
+ "parameter_order": [],
1052
+ "properties": {
1053
+ "curvature_coords": "relative",
1054
+ "normalize_panel_translation": false,
1055
+ "normalized_edge_loops": true,
1056
+ "units_in_meter": 100
1057
+ }
1058
+ }
GarmentCode/assets/Sim_props/default_sim_props.yaml ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ sim:
2
+ config:
3
+ optimize_storage: true
4
+
5
+ max_sim_steps: 2400
6
+ max_frame_time: 60
7
+ max_meshgen_time: 60
8
+ max_sim_time: 600
9
+ static_threshold: 0.03
10
+ non_static_percent: 1.5
11
+
12
+ max_body_collisions: 35
13
+ max_self_collisions: 300
14
+
15
+ zero_gravity_steps: 10
16
+ resolution_scale: 1.0
17
+ ground: false
18
+ material:
19
+ garment_tri_ka: 10000.0
20
+ garment_edge_ke: 1.0 # Very soft fabric
21
+ garment_tri_ke: 10000.0
22
+ spring_ke: 50000.0
23
+ garment_edge_kd: 10.0
24
+ garment_tri_kd: 1.0
25
+ spring_kd: 10.0
26
+ fabric_density: 1.0
27
+ fabric_thickness: 0.1
28
+ fabric_friction: 0.5
29
+ options:
30
+ enable_particle_particle_collisions: false
31
+ enable_triangle_particle_collisions: true
32
+ enable_edge_edge_collisions: true
33
+ enable_body_collision_filters: true
34
+ enable_global_collision_filter: true
35
+
36
+ global_damping_factor: 0.25
37
+ global_damping_effective_velocity: 0.0
38
+ global_max_velocity: 25.0
39
+
40
+ enable_attachment_constraint: true
41
+ attachment_stiffness:
42
+ - 1000.
43
+ - 1000.
44
+ - 1000.
45
+ - 1000.
46
+ attachment_damping:
47
+ - 10.
48
+ - 0.
49
+ - 0.
50
+ - 0.
51
+ attachment_frames: 400
52
+ attachment_label_names:
53
+ - lower_interface
54
+ - right_collar
55
+ - left_collar
56
+ - strapless_top
57
+
58
+ enable_cloth_reference_drag: true
59
+ cloth_reference_margin: 0.1
60
+ enable_body_smoothing: false
61
+ smoothing_total_smoothing_factor: 1.0
62
+ smoothing_recover_start_frame: 150
63
+ smoothing_num_steps: 100
64
+ smoothing_frame_gap_between_steps: 1
65
+ body_collision_thickness: 0.25
66
+ body_friction: 0.5
67
+ stats:
68
+ fails: {}
69
+ sim_time: {}
70
+ spf: {}
71
+ fin_frame: {}
72
+ self_collisions: {}
73
+ body_collisions: {}
74
+ render:
75
+ config:
76
+ resolution:
77
+ - 800
78
+ - 800
79
+ sides:
80
+ - front
81
+ - back
82
+ front_camera_location:
83
+ - 0
84
+ - 0.97
85
+ - 4.15
86
+ uv_texture:
87
+ seam_width: 0.5
88
+ dpi: 1500
89
+ fabric_grain_texture_path: ./assets/img/fabric_texture.png
90
+ fabric_grain_resolution: 5
91
+ stats:
92
+ render_time: {}
GarmentCode/assets/Sim_props/gui_sim_props.yaml ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ sim:
2
+ config:
3
+ optimize_storage: true
4
+
5
+ max_sim_steps: 2400
6
+ max_frame_time: null # NOTE: Important for GUI!!
7
+ # GUI runs the sim in a thread, which is not supported by timeouts on Linux/MacOS
8
+ max_meshgen_time: 60
9
+ max_sim_time: 600
10
+ static_threshold: 0.03
11
+ non_static_percent: 1.5
12
+
13
+ max_body_collisions: 35
14
+ max_self_collisions: 300
15
+
16
+ zero_gravity_steps: 10
17
+ resolution_scale: 1.0
18
+ ground: false
19
+ material:
20
+ garment_tri_ka: 10000.0
21
+ garment_edge_ke: 100.0 # Mid-softness fabric
22
+ garment_tri_ke: 10000.0
23
+ spring_ke: 50000.0
24
+ garment_edge_kd: 10.0
25
+ garment_tri_kd: 1.0
26
+ spring_kd: 10.0
27
+ fabric_density: 1.0
28
+ fabric_thickness: 0.1
29
+ fabric_friction: 0.5
30
+ options:
31
+ enable_particle_particle_collisions: false
32
+ enable_triangle_particle_collisions: true
33
+ enable_edge_edge_collisions: true
34
+ enable_body_collision_filters: true
35
+ enable_global_collision_filter: true
36
+
37
+ global_damping_factor: 0.25
38
+ global_damping_effective_velocity: 0.0
39
+ global_max_velocity: 25.0
40
+
41
+ enable_attachment_constraint: true
42
+ attachment_stiffness:
43
+ - 1000.
44
+ - 1000.
45
+ - 1000.
46
+ - 1000.
47
+ attachment_damping:
48
+ - 10.
49
+ - 0.
50
+ - 0.
51
+ - 0.
52
+ attachment_frames: 400
53
+ attachment_label_names:
54
+ - lower_interface
55
+ - right_collar
56
+ - left_collar
57
+ - strapless_top
58
+
59
+ enable_cloth_reference_drag: true
60
+ cloth_reference_margin: 0.1
61
+ enable_body_smoothing: false
62
+ smoothing_total_smoothing_factor: 1.0
63
+ smoothing_recover_start_frame: 150
64
+ smoothing_num_steps: 100
65
+ smoothing_frame_gap_between_steps: 1
66
+ body_collision_thickness: 0.25
67
+ body_friction: 0.5
68
+ stats:
69
+ fails: {}
70
+ sim_time: {}
71
+ spf: {}
72
+ fin_frame: {}
73
+ self_collisions: {}
74
+ body_collisions: {}
75
+ render:
76
+ config:
77
+ resolution:
78
+ - 800
79
+ - 800
80
+ sides:
81
+ - front
82
+ - back
83
+ front_camera_location:
84
+ - 0
85
+ - 0.97
86
+ - 4.15
87
+ uv_texture:
88
+ seam_width: 0.5
89
+ dpi: 1500
90
+ fabric_grain_texture_path: ./assets/img/fabric_texture.png
91
+ fabric_grain_resolution: 5
92
+ stats:
93
+ render_time: {}
GarmentCode/assets/Sim_props/mid_bending.yaml ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ sim:
2
+ config:
3
+ optimize_storage: true
4
+
5
+ max_sim_steps: 2400
6
+ max_frame_time: 60
7
+ max_meshgen_time: 60
8
+ max_sim_time: 600
9
+ static_threshold: 0.03
10
+ non_static_percent: 1.5
11
+
12
+ max_body_collisions: 35
13
+ max_self_collisions: 300
14
+
15
+ zero_gravity_steps: 10
16
+ resolution_scale: 1.0
17
+ ground: false
18
+ material:
19
+ garment_tri_ka: 10000.0
20
+ garment_edge_ke: 100.0
21
+ garment_tri_ke: 10000.0
22
+ spring_ke: 50000.0
23
+ garment_edge_kd: 10.0
24
+ garment_tri_kd: 1.0
25
+ spring_kd: 10.0
26
+ fabric_density: 1.0
27
+ fabric_thickness: 0.1
28
+ fabric_friction: 0.5
29
+ options:
30
+ enable_particle_particle_collisions: false
31
+ enable_triangle_particle_collisions: true
32
+ enable_edge_edge_collisions: true
33
+ enable_body_collision_filters: true
34
+ enable_global_collision_filter: true
35
+
36
+ global_damping_factor: 0.25
37
+ global_damping_effective_velocity: 0.0
38
+ global_max_velocity: 25.0
39
+
40
+ enable_attachment_constraint: true
41
+ attachment_stiffness:
42
+ - 1000.
43
+ - 1000.
44
+ - 1000.
45
+ - 1000.
46
+ attachment_damping:
47
+ - 10.
48
+ - 0.
49
+ - 0.
50
+ - 0.
51
+ attachment_frames: 400
52
+ attachment_label_names:
53
+ - lower_interface
54
+ - right_collar
55
+ - left_collar
56
+ - strapless_top
57
+
58
+ enable_cloth_reference_drag: true
59
+ cloth_reference_margin: 0.1
60
+ enable_body_smoothing: false
61
+ smoothing_total_smoothing_factor: 1.0
62
+ smoothing_recover_start_frame: 150
63
+ smoothing_num_steps: 100
64
+ smoothing_frame_gap_between_steps: 1
65
+ body_collision_thickness: 0.25
66
+ body_friction: 0.5
67
+ stats:
68
+ fails: {}
69
+ sim_time: {}
70
+ spf: {}
71
+ fin_frame: {}
72
+ self_collisions: {}
73
+ body_collisions: {}
74
+ render:
75
+ config:
76
+ resolution:
77
+ - 800
78
+ - 800
79
+ sides:
80
+ - front
81
+ - back
82
+ front_camera_location:
83
+ - 0
84
+ - 0.97
85
+ - 4.15
86
+ uv_texture:
87
+ seam_width: 0.5
88
+ dpi: 1500
89
+ fabric_grain_texture_path: ./assets/img/fabric_texture.png
90
+ fabric_grain_resolution: 5
91
+ stats:
92
+ render_time: {}
GarmentCode/assets/Sim_props/minimal_bending.yaml ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ sim:
2
+ config:
3
+ optimize_storage: true
4
+
5
+ max_sim_steps: 2400
6
+ max_frame_time: 60
7
+ max_meshgen_time: 60
8
+ max_sim_time: 600
9
+ static_threshold: 0.03
10
+ non_static_percent: 1.5
11
+
12
+ max_body_collisions: 35
13
+ max_self_collisions: 300
14
+
15
+ zero_gravity_steps: 10
16
+ resolution_scale: 1.0
17
+ ground: false
18
+ material:
19
+ garment_tri_ka: 10000.0
20
+ garment_edge_ke: 500.0
21
+ garment_tri_ke: 10000.0
22
+ spring_ke: 50000.0
23
+ garment_edge_kd: 10.0
24
+ garment_tri_kd: 1.0
25
+ spring_kd: 10.0
26
+ fabric_density: 1.0
27
+ fabric_thickness: 0.1
28
+ fabric_friction: 0.5
29
+ options:
30
+ enable_particle_particle_collisions: false
31
+ enable_triangle_particle_collisions: true
32
+ enable_edge_edge_collisions: true
33
+ enable_body_collision_filters: true
34
+ enable_global_collision_filter: true
35
+
36
+ global_damping_factor: 0.25
37
+ global_damping_effective_velocity: 0.0
38
+ global_max_velocity: 25.0
39
+
40
+ enable_attachment_constraint: true
41
+ attachment_stiffness:
42
+ - 1000.
43
+ - 1000.
44
+ - 1000.
45
+ - 1000.
46
+ attachment_damping:
47
+ - 10.
48
+ - 0.
49
+ - 0.
50
+ - 0.
51
+ attachment_frames: 400
52
+ attachment_label_names:
53
+ - lower_interface
54
+ - right_collar
55
+ - left_collar
56
+ - strapless_top
57
+
58
+ enable_cloth_reference_drag: true
59
+ cloth_reference_margin: 0.1
60
+ enable_body_smoothing: false
61
+ smoothing_total_smoothing_factor: 1.0
62
+ smoothing_recover_start_frame: 150
63
+ smoothing_num_steps: 100
64
+ smoothing_frame_gap_between_steps: 1
65
+ body_collision_thickness: 0.25
66
+ body_friction: 0.5
67
+ stats:
68
+ fails: {}
69
+ sim_time: {}
70
+ spf: {}
71
+ fin_frame: {}
72
+ self_collisions: {}
73
+ body_collisions: {}
74
+ render:
75
+ config:
76
+ resolution:
77
+ - 800
78
+ - 800
79
+ sides:
80
+ - front
81
+ - back
82
+ front_camera_location:
83
+ - 0
84
+ - 0.97
85
+ - 4.15
86
+ uv_texture:
87
+ seam_width: 0.5
88
+ dpi: 1500
89
+ fabric_grain_texture_path: ./assets/img/fabric_texture.png
90
+ fabric_grain_resolution: 5
91
+ stats:
92
+ render_time: {}
GarmentCode/assets/Sim_props/soft_flexy_ochra 30s.json ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "body": "f_average_A40.obj",
3
+ "render": {
4
+ "config": {
5
+ "garment_color": [
6
+ 0.6359999775886536,
7
+ 0.43511512875556946,
8
+ 0.04769999161362648
9
+ ],
10
+ "resolution": [
11
+ 800,
12
+ 800
13
+ ]
14
+ },
15
+ "stats": {
16
+ "render_time": {}
17
+ }
18
+ },
19
+ "scan_imitation": {
20
+ "config": {
21
+ "test_rays_num": 30,
22
+ "visible_rays_num": 4
23
+ },
24
+ "stats": {}
25
+ },
26
+ "sim": {
27
+ "config": {
28
+ "body_friction": 0.25,
29
+ "collision_thickness": 0.04,
30
+ "material": {
31
+ "air_drag": 0.01,
32
+ "bend_angle_dropoff": 0.11,
33
+ "bend_damp": 0.1,
34
+ "bend_damp_dropoff": 0.0,
35
+ "bend_plasticity": 0.0,
36
+ "bend_resistance": 0.03,
37
+ "bend_yield": 0.0,
38
+ "compression_resistance": 100.0,
39
+ "density": 0.015,
40
+ "friction": 0.01,
41
+ "length_scale": 1.0,
42
+ "pressure": 0.0,
43
+ "rubber": 1,
44
+ "shear_resistance": 0.4,
45
+ "stretch_damp": 0.2,
46
+ "stretch_resistance": 25.0,
47
+ "viscous_damp": 0.0,
48
+ "warp_resistance_scale": 1.0,
49
+ "warp_rubber_scale": 1.0,
50
+ "weft_resistance_scale": 1.0,
51
+ "weft_rubber_scale": 1.0
52
+ },
53
+ "max_sim_steps": 1500,
54
+ "non_static_percent": 1.5,
55
+ "object_intersect_border_threshold": 100,
56
+ "resolution_scale": 9.0,
57
+ "self_intersect_hit_threshold": 0,
58
+ "static_threshold": 0.01,
59
+ "zero_gravity_steps": 5
60
+ },
61
+ "stats": {
62
+ "fails": {
63
+ "crashes": [],
64
+ "fast_finish": [],
65
+ "intersect_colliders": [],
66
+ "intersect_self": [],
67
+ "pattern_loading": [],
68
+ "static_equilibrium": []
69
+ },
70
+ "fin_frame": {},
71
+ "sim_time": {},
72
+ "spf": {}
73
+ }
74
+ }
75
+ }
GarmentCode/assets/Sim_props/soft_ochra.json ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "body": "f_average_A40.obj",
3
+ "render": {
4
+ "config": {
5
+ "garment_color": [
6
+ 0.6359999775886536,
7
+ 0.43511512875556946,
8
+ 0.04769999161362648
9
+ ],
10
+ "resolution": [
11
+ 800,
12
+ 800
13
+ ]
14
+ },
15
+ "stats": {
16
+ "render_time": {}
17
+ }
18
+ },
19
+ "scan_imitation": {
20
+ "config": {
21
+ "test_rays_num": 30,
22
+ "visible_rays_num": 4
23
+ },
24
+ "stats": {}
25
+ },
26
+ "sim": {
27
+ "config": {
28
+ "body_friction": 0.25,
29
+ "collision_thickness": 0.04,
30
+ "material": {
31
+ "air_drag": 0.01,
32
+ "bend_angle_dropoff": 0.11,
33
+ "bend_damp": 0.1,
34
+ "bend_damp_dropoff": 0.0,
35
+ "bend_plasticity": 0.0,
36
+ "bend_resistance": 0.03,
37
+ "bend_yield": 0.0,
38
+ "compression_resistance": 100.0,
39
+ "density": 0.015,
40
+ "friction": 0.01,
41
+ "length_scale": 1.0,
42
+ "pressure": 0.0,
43
+ "rubber": 1,
44
+ "shear_resistance": 0.4,
45
+ "stretch_damp": 0.2,
46
+ "stretch_resistance": 400.0,
47
+ "viscous_damp": 0.0,
48
+ "warp_resistance_scale": 1.0,
49
+ "warp_rubber_scale": 1.0,
50
+ "weft_resistance_scale": 1.0,
51
+ "weft_rubber_scale": 1.0
52
+ },
53
+ "max_sim_steps": 1500,
54
+ "non_static_percent": 1.5,
55
+ "object_intersect_border_threshold": 100,
56
+ "resolution_scale": 9.0,
57
+ "self_intersect_hit_threshold": 0,
58
+ "static_threshold": 0.01,
59
+ "zero_gravity_steps": 5
60
+ },
61
+ "stats": {
62
+ "fails": {
63
+ "crashes": [],
64
+ "fast_finish": [],
65
+ "intersect_colliders": [],
66
+ "intersect_self": [],
67
+ "pattern_loading": [],
68
+ "static_equilibrium": []
69
+ },
70
+ "fin_frame": {},
71
+ "sim_time": {},
72
+ "spf": {}
73
+ }
74
+ }
75
+ }
GarmentCode/assets/Sim_props/stiff_ochra.json ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "body": "f_average_A40.obj",
3
+ "render": {
4
+ "config": {
5
+ "garment_color": [
6
+ 0.6359999775886536,
7
+ 0.43511512875556946,
8
+ 0.04769999161362648
9
+ ],
10
+ "resolution": [
11
+ 800,
12
+ 800
13
+ ]
14
+ },
15
+ "stats": {
16
+ "render_time": {}
17
+ }
18
+ },
19
+ "scan_imitation": {
20
+ "config": {
21
+ "test_rays_num": 30,
22
+ "visible_rays_num": 4
23
+ },
24
+ "stats": {}
25
+ },
26
+ "sim": {
27
+ "config": {
28
+ "body_friction": 0.25,
29
+ "collision_thickness": 0.04,
30
+ "material": {
31
+ "air_drag": 0.01,
32
+ "bend_angle_dropoff": 0.11,
33
+ "bend_damp": 0.1,
34
+ "bend_damp_dropoff": 0.0,
35
+ "bend_plasticity": 0.0,
36
+ "bend_resistance": 2.0,
37
+ "bend_yield": 0.0,
38
+ "compression_resistance": 100.0,
39
+ "density": 0.015,
40
+ "friction": 0.01,
41
+ "length_scale": 1.0,
42
+ "pressure": 0.0,
43
+ "rubber": 1,
44
+ "shear_resistance": 0.4,
45
+ "stretch_damp": 0.2,
46
+ "stretch_resistance": 400.0,
47
+ "viscous_damp": 0.0,
48
+ "warp_resistance_scale": 1.0,
49
+ "warp_rubber_scale": 1.0,
50
+ "weft_resistance_scale": 1.0,
51
+ "weft_rubber_scale": 1.0
52
+ },
53
+ "max_sim_steps": 1500,
54
+ "non_static_percent": 1.5,
55
+ "object_intersect_border_threshold": 100,
56
+ "resolution_scale": 4.0,
57
+ "self_intersect_hit_threshold": 0,
58
+ "static_threshold": 0.01,
59
+ "zero_gravity_steps": 10
60
+ },
61
+ "stats": {
62
+ "fails": {
63
+ "crashes": [],
64
+ "fast_finish": [],
65
+ "intersect_colliders": [],
66
+ "intersect_self": [],
67
+ "pattern_loading": [],
68
+ "static_equilibrium": []
69
+ },
70
+ "fin_frame": {},
71
+ "sim_time": {},
72
+ "spf": {}
73
+ }
74
+ }
75
+ }
GarmentCode/assets/bodies/Readme.md ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ # Attribution
2
+ Body models in this folder with "smpl" in the name are based on the female and male average body models of [SMPL](https://smpl.is.tue.mpg.de/) (licensed under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/)).
3
+
4
+ Body models without "smpl" in the name are based on our own body model, see https://github.com/mbotsch/GarmentMeasurements
5
+
6
+ ### Disclaimer
7
+ Due to the restrictions of the SMPL license, we cannot share all 3D models of the body shapes used in GarmentCode paper, except for the base average bodies for male and female versions of SMPL.
GarmentCode/assets/bodies/body_params.py ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+
3
+ import pygarment as pyg
4
+
5
+
6
+ class BodyParameters(pyg.BodyParametrizationBase):
7
+ """Custom class that defines calculated body parameters"""
8
+
9
+ def __init__(self, param_file='') -> None:
10
+ super().__init__(param_file)
11
+
12
+ def eval_dependencies(self, key=None):
13
+ super().eval_dependencies(key)
14
+
15
+ if key in ['height', 'head_l', 'waist_line', 'hips_line', None]:
16
+ self.params['_waist_level'] = self.params['height'] - self.params['head_l'] - self.params['waist_line']
17
+ self.params['_leg_length'] = self.params['_waist_level'] - self.params['hips_line']
18
+
19
+ if key in ['shoulder_w', None]:
20
+ # Correct sleeve line location is a little closer to the neck
21
+ # than the true shoulder width
22
+ self.params['_base_sleeve_balance'] = self.params['shoulder_w'] - 2
23
+
24
+ # Balance for the bust dart location
25
+ if key in ['bust_line', 'vert_bust_line', None]:
26
+ if 'vert_bust_line' in self.params:
27
+ self.params['_bust_line'] = (1 - 1/3) * self.params['vert_bust_line'] + 1/3 * self.params['bust_line']
28
+ else:
29
+ self.params['_bust_line'] = self.params['bust_line']
30
+
31
+ # Half of the slopes for use in garment (smoother fabric distribution)
32
+ if key in ['hip_inclination', None]:
33
+ self.params['_hip_inclination'] = self.params['hip_inclination'] / 2
34
+ if key in ['shoulder_incl', None]:
35
+ self.params['_shoulder_incl'] = self.params['shoulder_incl']
36
+
37
+ # Add ease to armhole
38
+ if key in ['armscye_depth', None]:
39
+ self.params['_armscye_depth'] = self.params['armscye_depth'] + 2.5
GarmentCode/assets/bodies/f_smpl_average_A40.obj ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b41a11a126fed9d26087ef230d2212102ac32a2d04accbde2754ec87a2033c84
3
+ size 997644
GarmentCode/assets/bodies/f_smpl_average_A40.yaml ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ # Measurments of the body
3
+ body:
4
+ height: 165
5
+ head_l: 25 # nape of the neck to the top -- ok to use some average value
6
+
7
+ neck_w: 15
8
+ shoulder_w: 38
9
+ armscye_depth: 15 # Nape of the Neck to armscye depth on the back
10
+ shoulder_incl: 10 # degrees
11
+
12
+ arm_pose_angle: 40 # Degrees
13
+ arm_length: 80
14
+ wrist: 17
15
+
16
+ waist: 80 # 82 adjusted for 'dips'
17
+ waist_line: 36 # Nape of the Neck to waist (on the back)
18
+ waist_over_bust_line: 43 # -- measurement + addition for the shoulder
19
+ waist_back_width: 37
20
+
21
+ bust_line: 23
22
+ bust: 90 # adjust for the 'dips' from 96
23
+ bust_points: 21 #
24
+ underbust: 83
25
+ back_width: 45 # 32 + 2 * between-size
26
+
27
+ hips: 107
28
+ hip_back_width: 55
29
+ hips_line: 22 # From the waist
30
+ hip_inclination: 6
31
+ bum_points: 16
32
+ crotch_hip_diff: 10.5 # NOTE Waist-crotch = 25 # NOTE vertical projection of the level
33
+ leg_circ: 64
34
+
35
+
GarmentCode/assets/bodies/ggg_body_segmentation.json ADDED
The diff for this file is too large to render. See raw diff
 
GarmentCode/assets/bodies/m_smpl_average_A40.obj ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a0ee3d85b190da9dff5f2a22786977217ea8bcb5e2005a12233612e179ab2ed3
3
+ size 997608
GarmentCode/assets/bodies/m_smpl_average_A40.yaml ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ body:
2
+ arm_pose_angle: 40
3
+ arm_length: 80
4
+ wrist: 25
5
+ armscye_depth: 17.5
6
+ back_width: 52 # 46
7
+ bum_points: 19.3
8
+ bust: 100.0
9
+ bust_line: 24.4
10
+ bust_points: 17
11
+ crotch_hip_diff: 13.0
12
+ head_l: 25.6
13
+ height: 178.1
14
+ hips: 100.0
15
+ hips_line: 17.0
16
+ hip_back_width: 52
17
+ hip_inclination: 4
18
+ leg_circ: 63
19
+ neck_w: 17
20
+ shoulder_w: 38.2
21
+ shoulder_incl: 10
22
+ underbust: 98
23
+ waist: 80.0
24
+ waist_line: 44.2
25
+ waist_over_bust_line: 47
26
+ waist_back_width: 38
GarmentCode/assets/bodies/mean_all.obj ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f6b2bdf2881b839089a6da06c39e63993a77607939b21522ae906c0131fa54d9
3
+ size 1869269
GarmentCode/assets/bodies/mean_all.stl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:41f9b46ddcb70352d24a11b7365e1ee6d3e124ebd93004adb4b4f1e083af048d
3
+ size 2375084
GarmentCode/assets/bodies/mean_all.yaml ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ body:
2
+ arm_length: 53.9697
3
+ arm_pose_angle: 45.483
4
+ armscye_depth: 12.8679
5
+ back_width: 47.6761
6
+ bum_points: 18.2342
7
+ bust: 99.8407
8
+ bust_line: 25.6947
9
+ bust_points: 16.9463
10
+ crotch_hip_diff: 8.81363
11
+ head_l: 26.3262
12
+ height: 171.99
13
+ hip_back_width: 54.8237
14
+ hip_inclination: 9.86489
15
+ hips: 103.478
16
+ hips_line: 23.4837
17
+ leg_circ: 60.2039
18
+ neck_w: 18.9328
19
+ shoulder_incl: 21.6777
20
+ shoulder_w: 36.4568
21
+ underbust: 86.2455
22
+ vert_bust_line: 21.1388
23
+ waist: 84.3338
24
+ waist_back_width: 39.1358
25
+ waist_line: 36.8913
26
+ waist_over_bust_line: 40.5603
27
+ wrist: 16.5945
GarmentCode/assets/bodies/mean_all_apart.obj ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:cb9bdda33d85dbbd7de6ecf007236eadf7020369aaf2c71a46f443315fe6c198
3
+ size 1869419
GarmentCode/assets/bodies/mean_all_tpose.obj ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f11ad859be7e29034446a68841dd27d37b583c427381fe4cde75c58f3335c729
3
+ size 1595071
GarmentCode/assets/bodies/mean_all_tpose.yaml ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ body:
2
+ arm_length: 53.9697
3
+ arm_pose_angle: 0.0
4
+ armscye_depth: 12.8679
5
+ back_width: 47.6761
6
+ bum_points: 18.2342
7
+ bust: 99.8407
8
+ bust_line: 25.6947
9
+ bust_points: 16.9463
10
+ crotch_hip_diff: 8.81363
11
+ head_l: 26.3262
12
+ height: 171.99
13
+ hip_back_width: 54.8237
14
+ hip_inclination: 9.86489
15
+ hips: 103.478
16
+ hips_line: 23.4837
17
+ leg_circ: 60.2039
18
+ neck_w: 18.9328
19
+ shoulder_incl: 21.6777
20
+ shoulder_w: 36.4568
21
+ underbust: 86.2455
22
+ vert_bust_line: 21.1388
23
+ waist: 84.3338
24
+ waist_back_width: 39.1358
25
+ waist_line: 36.8913
26
+ waist_over_bust_line: 40.5603
27
+ wrist: 16.5945
GarmentCode/assets/bodies/mean_female.obj ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:05d2b3357f5d1def188b880ff249d9cbcd63a5ff55963f0ace447cadcb2460fc
3
+ size 1869212
GarmentCode/assets/bodies/mean_female.yaml ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ body:
2
+ arm_length: 51.594
3
+ arm_pose_angle: 45.487
4
+ armscye_depth: 12.6489
5
+ back_width: 46.1652
6
+ bum_points: 17.6707
7
+ bust: 97.4076
8
+ bust_line: 25.5656
9
+ bust_points: 16.212
10
+ crotch_hip_diff: 7.8731
11
+ head_l: 25.5328
12
+ height: 166.194
13
+ hip_back_width: 55.6788
14
+ hip_inclination: 12.6783
15
+ hips: 104.091
16
+ hips_line: 22.6309
17
+ leg_circ: 60.6592
18
+ neck_w: 17.772
19
+ shoulder_incl: 20.905
20
+ shoulder_w: 34.7129
21
+ underbust: 80.7483
22
+ vert_bust_line: 20.7686
23
+ waist: 80.3442
24
+ waist_back_width: 37.7747
25
+ waist_line: 35.7549
26
+ waist_over_bust_line: 39.9902
27
+ wrist: 15.8636
GarmentCode/assets/bodies/mean_male.obj ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:2e72141acea5c7f8ba64cd245cc2eb3b0580e535f3afd99a0fc10c68c652cf6d
3
+ size 1869776
GarmentCode/assets/bodies/mean_male.yaml ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ body:
2
+ arm_length: 56.8064
3
+ arm_pose_angle: 45.4775
4
+ armscye_depth: 13.1301
5
+ back_width: 50.7175
6
+ bum_points: 17.736
7
+ bust: 102.787
8
+ bust_line: 25.9217
9
+ bust_points: 17.8195
10
+ crotch_hip_diff: 9.92969
11
+ head_l: 27.2653
12
+ height: 178.873
13
+ hip_back_width: 53.9145
14
+ hip_inclination: 6.7451
15
+ hips: 102.85
16
+ hips_line: 24.4948
17
+ leg_circ: 59.9882
18
+ neck_w: 20.3361
19
+ shoulder_incl: 22.5059
20
+ shoulder_w: 38.5276
21
+ underbust: 93.0277
22
+ vert_bust_line: 21.5796
23
+ waist: 89.003
24
+ waist_back_width: 40.7068
25
+ waist_line: 38.3492
26
+ waist_over_bust_line: 41.6141
27
+ wrist: 17.4648
GarmentCode/assets/bodies/smpl_vert_segmentation.json ADDED
The diff for this file is too large to render. See raw diff
 
GarmentCode/assets/design_params/default.yaml ADDED
@@ -0,0 +1,885 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ design:
2
+ meta:
3
+ upper:
4
+ v: null
5
+ range:
6
+ - FittedShirt
7
+ - Shirt
8
+ - null
9
+ type: select_null
10
+ default_prob: 0.3
11
+ wb:
12
+ v: null
13
+ range:
14
+ - StraightWB
15
+ - FittedWB
16
+ - null
17
+ type: select_null
18
+ default_prob: 0.5
19
+ bottom:
20
+ v: null
21
+ range:
22
+ - SkirtCircle
23
+ - AsymmSkirtCircle
24
+ - GodetSkirt
25
+ - Pants
26
+ - Skirt2
27
+ - SkirtManyPanels
28
+ - PencilSkirt
29
+ - SkirtLevels
30
+ - null
31
+ type: select_null
32
+ default_prob: 0.3
33
+ waistband:
34
+ waist:
35
+ v: 1.0
36
+ range:
37
+ - 1.0
38
+ - 2
39
+ type: float
40
+ default_prob: 0.7
41
+ width:
42
+ v: 0.2
43
+ range:
44
+ - 0.1
45
+ - 1.
46
+ type: float
47
+ default_prob: 0.5
48
+ shirt:
49
+ strapless:
50
+ v: false
51
+ range:
52
+ - true
53
+ - false
54
+ type: bool
55
+ default_prob: 0.8
56
+ length:
57
+ v: 1.2
58
+ range:
59
+ - 0.5
60
+ - 3.5
61
+ type: float
62
+ default_prob: 0.7
63
+ width:
64
+ v: 1.05
65
+ range:
66
+ - 1.0
67
+ - 1.3
68
+ type: float
69
+ default_prob: 0.4
70
+ flare:
71
+ v: 1.0
72
+ range:
73
+ - 0.7
74
+ - 1.6
75
+ type: float
76
+ default_prob: 0.4
77
+ collar:
78
+ f_collar:
79
+ v: CircleNeckHalf
80
+ range:
81
+ - CircleNeckHalf
82
+ - CurvyNeckHalf
83
+ - VNeckHalf
84
+ - SquareNeckHalf
85
+ - TrapezoidNeckHalf
86
+ - CircleArcNeckHalf
87
+ - Bezier2NeckHalf
88
+ type: select
89
+ default_prob: 0.4
90
+ b_collar:
91
+ v: CircleNeckHalf
92
+ range:
93
+ - CircleNeckHalf
94
+ - CurvyNeckHalf
95
+ - VNeckHalf
96
+ - SquareNeckHalf
97
+ - TrapezoidNeckHalf
98
+ - CircleArcNeckHalf
99
+ - Bezier2NeckHalf
100
+ type: select
101
+ default_prob: 0.8
102
+ width:
103
+ v: 0.2
104
+ range:
105
+ - -0.5
106
+ - 1
107
+ type: float
108
+ default_prob: 0.4
109
+ fc_depth:
110
+ v: 0.4
111
+ range:
112
+ - 0.3
113
+ - 2
114
+ type: float
115
+ default_prob: 0.3
116
+ bc_depth:
117
+ v: 0
118
+ range:
119
+ - 0
120
+ - 2
121
+ type: float
122
+ default_prob: 0.4
123
+ fc_angle:
124
+ v: 95
125
+ range:
126
+ - 70
127
+ - 110
128
+ type: int
129
+ bc_angle:
130
+ v: 95
131
+ range:
132
+ - 70
133
+ - 110
134
+ type: int
135
+ f_bezier_x:
136
+ v: 0.3
137
+ range:
138
+ - 0.05
139
+ - 0.95
140
+ type: float
141
+ default_prob: 0.4
142
+ f_bezier_y:
143
+ v: 0.55
144
+ range:
145
+ - 0.05
146
+ - 0.95
147
+ type: float
148
+ default_prob: 0.4
149
+ b_bezier_x:
150
+ v: 0.15
151
+ range:
152
+ - 0.05
153
+ - 0.95
154
+ type: float
155
+ default_prob: 0.4
156
+ b_bezier_y:
157
+ v: 0.1
158
+ range:
159
+ - 0.05
160
+ - 0.95
161
+ type: float
162
+ default_prob: 0.4
163
+ f_flip_curve:
164
+ v: false
165
+ range:
166
+ - true
167
+ - false
168
+ type: bool
169
+ default_prob: 0.8
170
+ b_flip_curve:
171
+ v: false
172
+ range:
173
+ - true
174
+ - false
175
+ type: bool
176
+ default_prob: 0.8
177
+ component:
178
+ style:
179
+ v: null
180
+ range:
181
+ - Turtle
182
+ - SimpleLapel
183
+ - Hood2Panels
184
+ - null
185
+ type: select_null
186
+ default_prob: 0.6
187
+ depth:
188
+ v: 7
189
+ range:
190
+ - 2
191
+ - 8
192
+ type: int
193
+ lapel_standing:
194
+ v: false
195
+ range:
196
+ - true
197
+ - false
198
+ type: bool
199
+ hood_depth:
200
+ v: 1
201
+ range:
202
+ - 1
203
+ - 2
204
+ type: float
205
+ default_prob: 0.6
206
+ hood_length:
207
+ v: 1
208
+ range:
209
+ - 1
210
+ - 1.5
211
+ type: float
212
+ default_prob: 0.6
213
+ sleeve:
214
+ sleeveless:
215
+ v: true
216
+ range:
217
+ - true
218
+ - false
219
+ type: bool
220
+ default_prob: 0.7
221
+ armhole_shape:
222
+ v: ArmholeCurve
223
+ range:
224
+ - ArmholeSquare
225
+ - ArmholeAngle
226
+ - ArmholeCurve
227
+ type: select
228
+ default_prob: 0.7
229
+ length:
230
+ v: 0.3
231
+ range:
232
+ - 0.1
233
+ - 1.15
234
+ type: float
235
+ connecting_width:
236
+ v: 0.2
237
+ range:
238
+ - 0
239
+ - 2
240
+ type: float
241
+ default_prob: 0.6
242
+ end_width:
243
+ v: 1.0
244
+ range:
245
+ - 0.2
246
+ - 2
247
+ type: float
248
+ default_prob: 0.4
249
+ sleeve_angle:
250
+ v: 10
251
+ range:
252
+ - 10
253
+ - 50
254
+ type: int
255
+ opening_dir_mix:
256
+ v: 0.1
257
+ range:
258
+ - -0.9
259
+ - 0.8
260
+ type: float
261
+ default_prob: 1.
262
+ standing_shoulder:
263
+ v: false
264
+ range:
265
+ - true
266
+ - false
267
+ type: bool
268
+ default_prob: 0.8
269
+ standing_shoulder_len:
270
+ v: 5.0
271
+ range:
272
+ - 4
273
+ - 10
274
+ type: float
275
+ connect_ruffle:
276
+ v: 1
277
+ range:
278
+ - 1
279
+ - 2
280
+ type: float
281
+ default_prob: 0.4
282
+ smoothing_coeff:
283
+ v: 0.25
284
+ range:
285
+ - 0.1
286
+ - 0.4
287
+ type: float
288
+ default_prob: 0.8
289
+ cuff:
290
+ type:
291
+ v: null
292
+ range:
293
+ - CuffBand
294
+ - CuffSkirt
295
+ - CuffBandSkirt
296
+ - null
297
+ type: select_null
298
+ top_ruffle:
299
+ v: 1
300
+ range:
301
+ - 1
302
+ - 3
303
+ type: float
304
+ cuff_len:
305
+ v: 0.1
306
+ range:
307
+ - 0.05
308
+ - 0.9
309
+ type: float
310
+ default_prob: 0.7
311
+ skirt_fraction:
312
+ v: 0.5
313
+ range:
314
+ - 0.1
315
+ - 0.9
316
+ type: float
317
+ default_prob: 0.5
318
+ skirt_flare:
319
+ v: 1.2
320
+ range:
321
+ - 1
322
+ - 2
323
+ type: float
324
+ skirt_ruffle:
325
+ v: 1.0
326
+ range:
327
+ - 1
328
+ - 1.5
329
+ type: float
330
+ default_prob: 0.3
331
+ left:
332
+ enable_asym:
333
+ v: false
334
+ range:
335
+ - true
336
+ - false
337
+ type: bool
338
+ default_prob: 0.8
339
+ shirt:
340
+ strapless:
341
+ v: false
342
+ range:
343
+ - true
344
+ - false
345
+ type: bool
346
+ default_prob: 0.8
347
+ width:
348
+ v: 1.0
349
+ range:
350
+ - 1.0
351
+ - 1.3
352
+ type: float
353
+ default_prob: 0.4
354
+ flare:
355
+ v: 1.0
356
+ range:
357
+ - 0.7
358
+ - 1.6
359
+ type: float
360
+ default_prob: 0.4
361
+ collar:
362
+ f_collar:
363
+ v: CircleNeckHalf
364
+ range:
365
+ - CircleNeckHalf
366
+ - CurvyNeckHalf
367
+ - VNeckHalf
368
+ - SquareNeckHalf
369
+ - TrapezoidNeckHalf
370
+ - CircleArcNeckHalf
371
+ - Bezier2NeckHalf
372
+ type: select
373
+ default_prob: 0.4
374
+ b_collar:
375
+ v: CircleNeckHalf
376
+ range:
377
+ - CircleNeckHalf
378
+ - CurvyNeckHalf
379
+ - VNeckHalf
380
+ - SquareNeckHalf
381
+ - TrapezoidNeckHalf
382
+ - CircleArcNeckHalf
383
+ - Bezier2NeckHalf
384
+ type: select
385
+ default_prob: 0.8
386
+ width:
387
+ v: 0.5
388
+ range:
389
+ - 0
390
+ - 1
391
+ type: float
392
+ default_prob: 0.4
393
+ fc_angle:
394
+ v: 95
395
+ range:
396
+ - 70
397
+ - 110
398
+ type: int
399
+ bc_angle:
400
+ v: 95
401
+ range:
402
+ - 70
403
+ - 110
404
+ type: int
405
+ f_bezier_x:
406
+ v: 0.5
407
+ range:
408
+ - 0.05
409
+ - 0.95
410
+ type: float
411
+ default_prob: 0.4
412
+ f_bezier_y:
413
+ v: 0.3
414
+ range:
415
+ - 0.05
416
+ - 0.95
417
+ type: float
418
+ b_bezier_x:
419
+ v: 0.5
420
+ range:
421
+ - 0.05
422
+ - 0.95
423
+ type: float
424
+ default_prob: 0.4
425
+ b_bezier_y:
426
+ v: 0.3
427
+ range:
428
+ - 0.05
429
+ - 0.95
430
+ type: float
431
+ f_flip_curve:
432
+ v: false
433
+ range:
434
+ - true
435
+ - false
436
+ type: bool
437
+ default_prob: 0.8
438
+ b_flip_curve:
439
+ v: false
440
+ range:
441
+ - true
442
+ - false
443
+ type: bool
444
+ default_prob: 0.8
445
+ sleeve:
446
+ sleeveless:
447
+ v: true
448
+ range:
449
+ - true
450
+ - false
451
+ type: bool
452
+ default_prob: 0.7
453
+ armhole_shape:
454
+ v: ArmholeCurve
455
+ range:
456
+ - ArmholeSquare
457
+ - ArmholeAngle
458
+ - ArmholeCurve
459
+ type: select
460
+ default_prob: 0.7
461
+ length:
462
+ v: 0.3
463
+ range:
464
+ - 0.1
465
+ - 1.15
466
+ type: float
467
+ connecting_width:
468
+ v: 0.2
469
+ range:
470
+ - 0
471
+ - 2
472
+ type: float
473
+ default_prob: 0.6
474
+ end_width:
475
+ v: 1.0
476
+ range:
477
+ - 0.2
478
+ - 2
479
+ type: float
480
+ default_prob: 0.4
481
+ sleeve_angle:
482
+ v: 10
483
+ range:
484
+ - 10
485
+ - 50
486
+ type: int
487
+ opening_dir_mix:
488
+ v: 0.2
489
+ range:
490
+ - -0.9
491
+ - 0.8
492
+ type: float
493
+ default_prob: 1.
494
+ standing_shoulder:
495
+ v: false
496
+ range:
497
+ - true
498
+ - false
499
+ type: bool
500
+ default_prob: 0.8
501
+ standing_shoulder_len:
502
+ v: 5.0
503
+ range:
504
+ - 4
505
+ - 10
506
+ type: float
507
+ connect_ruffle:
508
+ v: 1
509
+ range:
510
+ - 1
511
+ - 2
512
+ type: float
513
+ default_prob: 0.4
514
+ smoothing_coeff:
515
+ v: 0.25
516
+ range:
517
+ - 0.1
518
+ - 0.4
519
+ type: float
520
+ default_prob: 0.8
521
+ cuff:
522
+ type:
523
+ v: null
524
+ range:
525
+ - CuffBand
526
+ - CuffSkirt
527
+ - CuffBandSkirt
528
+ - null
529
+ type: select_null
530
+ top_ruffle:
531
+ v: 1
532
+ range:
533
+ - 1
534
+ - 2
535
+ type: float
536
+ cuff_len:
537
+ v: 0.1
538
+ range:
539
+ - 0.05
540
+ - 0.9
541
+ type: float
542
+ default_prob: 0.7
543
+ skirt_fraction:
544
+ v: 0.5
545
+ range:
546
+ - 0.1
547
+ - 0.9
548
+ type: float
549
+ default_prob: 0.5
550
+ skirt_flare:
551
+ v: 1.2
552
+ range:
553
+ - 1
554
+ - 2
555
+ type: float
556
+ skirt_ruffle:
557
+ v: 1.0
558
+ range:
559
+ - 1
560
+ - 1.5
561
+ type: float
562
+ default_prob: 0.3
563
+ skirt:
564
+ length:
565
+ v: 0.2
566
+ range:
567
+ - -0.2
568
+ - 0.95
569
+ type: float
570
+ rise:
571
+ v: 1
572
+ range:
573
+ - 0.5
574
+ - 1
575
+ type: float
576
+ default_prob: 0.3
577
+ ruffle:
578
+ v: 1.3
579
+ range:
580
+ - 1
581
+ - 2
582
+ type: float
583
+ default_prob: 0.3
584
+ bottom_cut:
585
+ v: 0
586
+ range:
587
+ - 0
588
+ - 0.9
589
+ type: float
590
+ default_prob: 0.3
591
+ flare:
592
+ v: 0
593
+ range:
594
+ - 0
595
+ - 20
596
+ type: int
597
+ default_prob: 0.5
598
+ flare-skirt:
599
+ length:
600
+ v: 0.2
601
+ range:
602
+ - -0.2
603
+ - 0.95
604
+ type: float
605
+ rise:
606
+ v: 1
607
+ range:
608
+ - 0.5
609
+ - 1
610
+ type: float
611
+ default_prob: 0.3
612
+ suns:
613
+ v: 0.75
614
+ range:
615
+ - 0.1
616
+ - 1.95
617
+ type: float
618
+ skirt-many-panels:
619
+ n_panels:
620
+ v: 4
621
+ range:
622
+ - 4
623
+ - 15
624
+ type: int
625
+ panel_curve:
626
+ v: 0
627
+ range:
628
+ - -0.35
629
+ - -0.25
630
+ - -0.15
631
+ - 0
632
+ - 0.15
633
+ - 0.25
634
+ - 0.35
635
+ - 0.45
636
+ type: select
637
+ asymm:
638
+ front_length:
639
+ v: 0.5
640
+ range:
641
+ - 0.1
642
+ - 0.9
643
+ type: float
644
+ default_prob: 0.5
645
+ cut:
646
+ add:
647
+ v: false
648
+ range:
649
+ - true
650
+ - false
651
+ type: bool
652
+ default_prob: 0.6
653
+ depth:
654
+ v: 0.5
655
+ range:
656
+ - 0.05
657
+ - 0.95
658
+ type: float
659
+ default_prob: 0.6
660
+ width:
661
+ v: 0.1
662
+ range:
663
+ - 0.05
664
+ - 0.4
665
+ type: float
666
+ place:
667
+ v: -0.5
668
+ range:
669
+ - -1
670
+ - 1
671
+ type: float
672
+ godet-skirt:
673
+ base:
674
+ v: PencilSkirt
675
+ range:
676
+ - Skirt2
677
+ - PencilSkirt
678
+ type: select
679
+ default_prob: 0.7
680
+ insert_w:
681
+ v: 15
682
+ range:
683
+ - 10
684
+ - 50
685
+ type: int
686
+ insert_depth:
687
+ v: 20
688
+ range:
689
+ - 10
690
+ - 50
691
+ type: int
692
+ num_inserts:
693
+ v: 4
694
+ range:
695
+ - 4
696
+ - 6
697
+ - 8
698
+ - 10
699
+ - 12
700
+ type: select
701
+ cuts_distance:
702
+ v: 5
703
+ range:
704
+ - 0
705
+ - 10
706
+ type: int
707
+ pencil-skirt:
708
+ length:
709
+ v: 0.4
710
+ range:
711
+ - 0.2
712
+ - 0.95
713
+ type: float
714
+ rise:
715
+ v: 1
716
+ range:
717
+ - 0.5
718
+ - 1
719
+ type: float
720
+ default_prob: 0.3
721
+ flare:
722
+ v: 1.
723
+ range:
724
+ - 0.6
725
+ - 1.5
726
+ type: float
727
+ default_prob: 0.3
728
+ low_angle:
729
+ v: 0
730
+ range:
731
+ - -30
732
+ - 30
733
+ type: int
734
+ default_prob: 0.7
735
+ front_slit:
736
+ v: 0
737
+ range:
738
+ - 0
739
+ - 0.9
740
+ type: float
741
+ default_prob: 0.4
742
+ back_slit:
743
+ v: 0
744
+ range:
745
+ - 0
746
+ - 0.9
747
+ type: float
748
+ default_prob: 0.4
749
+ left_slit:
750
+ v: 0
751
+ range:
752
+ - 0
753
+ - 0.9
754
+ type: float
755
+ default_prob: 0.6
756
+ right_slit:
757
+ v: 0
758
+ range:
759
+ - 0
760
+ - 0.9
761
+ type: float
762
+ default_prob: 0.6
763
+ style_side_cut:
764
+ v: null
765
+ range:
766
+ - Sun
767
+ - SIGGRAPH_logo
768
+ type: select_null
769
+ default_prob: 1.
770
+ levels-skirt:
771
+ base:
772
+ v: PencilSkirt
773
+ range:
774
+ - Skirt2
775
+ - PencilSkirt
776
+ - SkirtCircle
777
+ - AsymmSkirtCircle
778
+ type: select
779
+ level:
780
+ v: Skirt2
781
+ range:
782
+ - Skirt2
783
+ - SkirtCircle
784
+ - AsymmSkirtCircle
785
+ type: select
786
+ num_levels:
787
+ v: 1
788
+ range:
789
+ - 1
790
+ - 5
791
+ type: int
792
+ level_ruffle:
793
+ v: 1.0
794
+ range:
795
+ - 1
796
+ - 1.7
797
+ type: float
798
+ length:
799
+ v: 0.5
800
+ range:
801
+ - 0.2
802
+ - 0.95
803
+ type: float
804
+ rise:
805
+ v: 1
806
+ range:
807
+ - 0.5
808
+ - 1
809
+ type: float
810
+ default_prob: 0.3
811
+ base_length_frac:
812
+ v: 0.5
813
+ range:
814
+ - 0.2
815
+ - 0.8
816
+ type: float
817
+ pants:
818
+ length:
819
+ v: 0.3
820
+ range:
821
+ - 0.2
822
+ - 0.9
823
+ type: float
824
+ width:
825
+ v: 1.0
826
+ range:
827
+ - 1.0
828
+ - 1.5
829
+ type: float
830
+ default_prob: 0.5
831
+ flare:
832
+ v: 1.0
833
+ range:
834
+ - 0.5
835
+ - 1.2
836
+ type: float
837
+ default_prob: 0.3
838
+ rise:
839
+ v: 1.0
840
+ range:
841
+ - 0.5
842
+ - 1
843
+ type: float
844
+ default_prob: 0.3
845
+ cuff:
846
+ type:
847
+ v: null
848
+ range:
849
+ - CuffBand
850
+ - CuffSkirt
851
+ - CuffBandSkirt
852
+ - null
853
+ type: select_null
854
+ default_prob: 0.5
855
+ top_ruffle:
856
+ v: 1.0
857
+ range:
858
+ - 1
859
+ - 2
860
+ type: float
861
+ cuff_len:
862
+ v: 0.1
863
+ range:
864
+ - 0.05
865
+ - 0.9
866
+ type: float
867
+ default_prob: 0.3
868
+ skirt_fraction:
869
+ v: 0.5
870
+ range:
871
+ - 0.1
872
+ - 0.9
873
+ type: float
874
+ skirt_flare:
875
+ v: 1.2
876
+ range:
877
+ - 1
878
+ - 2
879
+ type: float
880
+ skirt_ruffle:
881
+ v: 1.0
882
+ range:
883
+ - 1
884
+ - 1.5
885
+ type: float
GarmentCode/assets/design_params/t-shirt.yaml ADDED
@@ -0,0 +1,885 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ design:
2
+ meta:
3
+ upper:
4
+ v: Shirt
5
+ range:
6
+ - FittedShirt
7
+ - Shirt
8
+ - null
9
+ type: select_null
10
+ default_prob: 0.3
11
+ wb:
12
+ v: null
13
+ range:
14
+ - StraightWB
15
+ - FittedWB
16
+ - null
17
+ type: select_null
18
+ default_prob: 0.5
19
+ bottom:
20
+ v: null
21
+ range:
22
+ - SkirtCircle
23
+ - AsymmSkirtCircle
24
+ - GodetSkirt
25
+ - Pants
26
+ - Skirt2
27
+ - SkirtManyPanels
28
+ - PencilSkirt
29
+ - SkirtLevels
30
+ - null
31
+ type: select_null
32
+ default_prob: 0.3
33
+ waistband:
34
+ waist:
35
+ v: 1.0
36
+ range:
37
+ - 1.0
38
+ - 2
39
+ type: float
40
+ default_prob: 0.7
41
+ width:
42
+ v: 0.2
43
+ range:
44
+ - 0.1
45
+ - 1.
46
+ type: float
47
+ default_prob: 0.5
48
+ shirt:
49
+ strapless:
50
+ v: false
51
+ range:
52
+ - true
53
+ - false
54
+ type: bool
55
+ default_prob: 0.8
56
+ length:
57
+ v: 1.2
58
+ range:
59
+ - 0.5
60
+ - 3.5
61
+ type: float
62
+ default_prob: 0.7
63
+ width:
64
+ v: 1.05
65
+ range:
66
+ - 1.0
67
+ - 1.3
68
+ type: float
69
+ default_prob: 0.4
70
+ flare:
71
+ v: 1.0
72
+ range:
73
+ - 0.7
74
+ - 1.6
75
+ type: float
76
+ default_prob: 0.4
77
+ collar:
78
+ f_collar:
79
+ v: CircleNeckHalf
80
+ range:
81
+ - CircleNeckHalf
82
+ - CurvyNeckHalf
83
+ - VNeckHalf
84
+ - SquareNeckHalf
85
+ - TrapezoidNeckHalf
86
+ - CircleArcNeckHalf
87
+ - Bezier2NeckHalf
88
+ type: select
89
+ default_prob: 0.4
90
+ b_collar:
91
+ v: CircleNeckHalf
92
+ range:
93
+ - CircleNeckHalf
94
+ - CurvyNeckHalf
95
+ - VNeckHalf
96
+ - SquareNeckHalf
97
+ - TrapezoidNeckHalf
98
+ - CircleArcNeckHalf
99
+ - Bezier2NeckHalf
100
+ type: select
101
+ default_prob: 0.8
102
+ width:
103
+ v: 0.2
104
+ range:
105
+ - -0.5
106
+ - 1
107
+ type: float
108
+ default_prob: 0.4
109
+ fc_depth:
110
+ v: 0.4
111
+ range:
112
+ - 0.3
113
+ - 2
114
+ type: float
115
+ default_prob: 0.3
116
+ bc_depth:
117
+ v: 0
118
+ range:
119
+ - 0
120
+ - 2
121
+ type: float
122
+ default_prob: 0.4
123
+ fc_angle:
124
+ v: 95
125
+ range:
126
+ - 70
127
+ - 110
128
+ type: int
129
+ bc_angle:
130
+ v: 95
131
+ range:
132
+ - 70
133
+ - 110
134
+ type: int
135
+ f_bezier_x:
136
+ v: 0.3
137
+ range:
138
+ - 0.05
139
+ - 0.95
140
+ type: float
141
+ default_prob: 0.4
142
+ f_bezier_y:
143
+ v: 0.55
144
+ range:
145
+ - 0.05
146
+ - 0.95
147
+ type: float
148
+ default_prob: 0.4
149
+ b_bezier_x:
150
+ v: 0.15
151
+ range:
152
+ - 0.05
153
+ - 0.95
154
+ type: float
155
+ default_prob: 0.4
156
+ b_bezier_y:
157
+ v: 0.1
158
+ range:
159
+ - 0.05
160
+ - 0.95
161
+ type: float
162
+ default_prob: 0.4
163
+ f_flip_curve:
164
+ v: false
165
+ range:
166
+ - true
167
+ - false
168
+ type: bool
169
+ default_prob: 0.8
170
+ b_flip_curve:
171
+ v: false
172
+ range:
173
+ - true
174
+ - false
175
+ type: bool
176
+ default_prob: 0.8
177
+ component:
178
+ style:
179
+ v: null
180
+ range:
181
+ - Turtle
182
+ - SimpleLapel
183
+ - Hood2Panels
184
+ - null
185
+ type: select_null
186
+ default_prob: 0.6
187
+ depth:
188
+ v: 7
189
+ range:
190
+ - 2
191
+ - 8
192
+ type: int
193
+ lapel_standing:
194
+ v: false
195
+ range:
196
+ - true
197
+ - false
198
+ type: bool
199
+ hood_depth:
200
+ v: 1
201
+ range:
202
+ - 1
203
+ - 2
204
+ type: float
205
+ default_prob: 0.6
206
+ hood_length:
207
+ v: 1
208
+ range:
209
+ - 1
210
+ - 1.5
211
+ type: float
212
+ default_prob: 0.6
213
+ sleeve:
214
+ sleeveless:
215
+ v: false
216
+ range:
217
+ - true
218
+ - false
219
+ type: bool
220
+ default_prob: 0.7
221
+ armhole_shape:
222
+ v: ArmholeCurve
223
+ range:
224
+ - ArmholeSquare
225
+ - ArmholeAngle
226
+ - ArmholeCurve
227
+ type: select
228
+ default_prob: 0.7
229
+ length:
230
+ v: 0.3
231
+ range:
232
+ - 0.1
233
+ - 1.15
234
+ type: float
235
+ connecting_width:
236
+ v: 0.2
237
+ range:
238
+ - 0
239
+ - 2
240
+ type: float
241
+ default_prob: 0.6
242
+ end_width:
243
+ v: 1.0
244
+ range:
245
+ - 0.2
246
+ - 2
247
+ type: float
248
+ default_prob: 0.4
249
+ sleeve_angle:
250
+ v: 10
251
+ range:
252
+ - 10
253
+ - 50
254
+ type: int
255
+ opening_dir_mix:
256
+ v: 0.1
257
+ range:
258
+ - -0.9
259
+ - 0.8
260
+ type: float
261
+ default_prob: 1.
262
+ standing_shoulder:
263
+ v: false
264
+ range:
265
+ - true
266
+ - false
267
+ type: bool
268
+ default_prob: 0.8
269
+ standing_shoulder_len:
270
+ v: 5.0
271
+ range:
272
+ - 4
273
+ - 10
274
+ type: float
275
+ connect_ruffle:
276
+ v: 1
277
+ range:
278
+ - 1
279
+ - 2
280
+ type: float
281
+ default_prob: 0.4
282
+ smoothing_coeff:
283
+ v: 0.25
284
+ range:
285
+ - 0.1
286
+ - 0.4
287
+ type: float
288
+ default_prob: 0.8
289
+ cuff:
290
+ type:
291
+ v: null
292
+ range:
293
+ - CuffBand
294
+ - CuffSkirt
295
+ - CuffBandSkirt
296
+ - null
297
+ type: select_null
298
+ top_ruffle:
299
+ v: 1
300
+ range:
301
+ - 1
302
+ - 3
303
+ type: float
304
+ cuff_len:
305
+ v: 0.1
306
+ range:
307
+ - 0.05
308
+ - 0.9
309
+ type: float
310
+ default_prob: 0.7
311
+ skirt_fraction:
312
+ v: 0.5
313
+ range:
314
+ - 0.1
315
+ - 0.9
316
+ type: float
317
+ default_prob: 0.5
318
+ skirt_flare:
319
+ v: 1.2
320
+ range:
321
+ - 1
322
+ - 2
323
+ type: float
324
+ skirt_ruffle:
325
+ v: 1.0
326
+ range:
327
+ - 1
328
+ - 1.5
329
+ type: float
330
+ default_prob: 0.3
331
+ left:
332
+ enable_asym:
333
+ v: false
334
+ range:
335
+ - true
336
+ - false
337
+ type: bool
338
+ default_prob: 0.8
339
+ shirt:
340
+ strapless:
341
+ v: false
342
+ range:
343
+ - true
344
+ - false
345
+ type: bool
346
+ default_prob: 0.8
347
+ width:
348
+ v: 1.0
349
+ range:
350
+ - 1.0
351
+ - 1.3
352
+ type: float
353
+ default_prob: 0.4
354
+ flare:
355
+ v: 1.0
356
+ range:
357
+ - 0.7
358
+ - 1.6
359
+ type: float
360
+ default_prob: 0.4
361
+ collar:
362
+ f_collar:
363
+ v: CircleNeckHalf
364
+ range:
365
+ - CircleNeckHalf
366
+ - CurvyNeckHalf
367
+ - VNeckHalf
368
+ - SquareNeckHalf
369
+ - TrapezoidNeckHalf
370
+ - CircleArcNeckHalf
371
+ - Bezier2NeckHalf
372
+ type: select
373
+ default_prob: 0.4
374
+ b_collar:
375
+ v: CircleNeckHalf
376
+ range:
377
+ - CircleNeckHalf
378
+ - CurvyNeckHalf
379
+ - VNeckHalf
380
+ - SquareNeckHalf
381
+ - TrapezoidNeckHalf
382
+ - CircleArcNeckHalf
383
+ - Bezier2NeckHalf
384
+ type: select
385
+ default_prob: 0.8
386
+ width:
387
+ v: 0.5
388
+ range:
389
+ - 0
390
+ - 1
391
+ type: float
392
+ default_prob: 0.4
393
+ fc_angle:
394
+ v: 95
395
+ range:
396
+ - 70
397
+ - 110
398
+ type: int
399
+ bc_angle:
400
+ v: 95
401
+ range:
402
+ - 70
403
+ - 110
404
+ type: int
405
+ f_bezier_x:
406
+ v: 0.5
407
+ range:
408
+ - 0.05
409
+ - 0.95
410
+ type: float
411
+ default_prob: 0.4
412
+ f_bezier_y:
413
+ v: 0.3
414
+ range:
415
+ - 0.05
416
+ - 0.95
417
+ type: float
418
+ b_bezier_x:
419
+ v: 0.5
420
+ range:
421
+ - 0.05
422
+ - 0.95
423
+ type: float
424
+ default_prob: 0.4
425
+ b_bezier_y:
426
+ v: 0.3
427
+ range:
428
+ - 0.05
429
+ - 0.95
430
+ type: float
431
+ f_flip_curve:
432
+ v: false
433
+ range:
434
+ - true
435
+ - false
436
+ type: bool
437
+ default_prob: 0.8
438
+ b_flip_curve:
439
+ v: false
440
+ range:
441
+ - true
442
+ - false
443
+ type: bool
444
+ default_prob: 0.8
445
+ sleeve:
446
+ sleeveless:
447
+ v: true
448
+ range:
449
+ - true
450
+ - false
451
+ type: bool
452
+ default_prob: 0.7
453
+ armhole_shape:
454
+ v: ArmholeCurve
455
+ range:
456
+ - ArmholeSquare
457
+ - ArmholeAngle
458
+ - ArmholeCurve
459
+ type: select
460
+ default_prob: 0.7
461
+ length:
462
+ v: 0.3
463
+ range:
464
+ - 0.1
465
+ - 1.15
466
+ type: float
467
+ connecting_width:
468
+ v: 0.2
469
+ range:
470
+ - 0
471
+ - 2
472
+ type: float
473
+ default_prob: 0.6
474
+ end_width:
475
+ v: 1.0
476
+ range:
477
+ - 0.2
478
+ - 2
479
+ type: float
480
+ default_prob: 0.4
481
+ sleeve_angle:
482
+ v: 10
483
+ range:
484
+ - 10
485
+ - 50
486
+ type: int
487
+ opening_dir_mix:
488
+ v: 0.2
489
+ range:
490
+ - -0.9
491
+ - 0.8
492
+ type: float
493
+ default_prob: 1.
494
+ standing_shoulder:
495
+ v: false
496
+ range:
497
+ - true
498
+ - false
499
+ type: bool
500
+ default_prob: 0.8
501
+ standing_shoulder_len:
502
+ v: 5.0
503
+ range:
504
+ - 4
505
+ - 10
506
+ type: float
507
+ connect_ruffle:
508
+ v: 1
509
+ range:
510
+ - 1
511
+ - 2
512
+ type: float
513
+ default_prob: 0.4
514
+ smoothing_coeff:
515
+ v: 0.25
516
+ range:
517
+ - 0.1
518
+ - 0.4
519
+ type: float
520
+ default_prob: 0.8
521
+ cuff:
522
+ type:
523
+ v: null
524
+ range:
525
+ - CuffBand
526
+ - CuffSkirt
527
+ - CuffBandSkirt
528
+ - null
529
+ type: select_null
530
+ top_ruffle:
531
+ v: 1
532
+ range:
533
+ - 1
534
+ - 2
535
+ type: float
536
+ cuff_len:
537
+ v: 0.1
538
+ range:
539
+ - 0.05
540
+ - 0.9
541
+ type: float
542
+ default_prob: 0.7
543
+ skirt_fraction:
544
+ v: 0.5
545
+ range:
546
+ - 0.1
547
+ - 0.9
548
+ type: float
549
+ default_prob: 0.5
550
+ skirt_flare:
551
+ v: 1.2
552
+ range:
553
+ - 1
554
+ - 2
555
+ type: float
556
+ skirt_ruffle:
557
+ v: 1.0
558
+ range:
559
+ - 1
560
+ - 1.5
561
+ type: float
562
+ default_prob: 0.3
563
+ skirt:
564
+ length:
565
+ v: 0.2
566
+ range:
567
+ - -0.2
568
+ - 0.95
569
+ type: float
570
+ rise:
571
+ v: 1
572
+ range:
573
+ - 0.5
574
+ - 1
575
+ type: float
576
+ default_prob: 0.3
577
+ ruffle:
578
+ v: 1.3
579
+ range:
580
+ - 1
581
+ - 2
582
+ type: float
583
+ default_prob: 0.3
584
+ bottom_cut:
585
+ v: 0
586
+ range:
587
+ - 0
588
+ - 0.9
589
+ type: float
590
+ default_prob: 0.3
591
+ flare:
592
+ v: 0
593
+ range:
594
+ - 0
595
+ - 20
596
+ type: int
597
+ default_prob: 0.5
598
+ flare-skirt:
599
+ length:
600
+ v: 0.2
601
+ range:
602
+ - -0.2
603
+ - 0.95
604
+ type: float
605
+ rise:
606
+ v: 1
607
+ range:
608
+ - 0.5
609
+ - 1
610
+ type: float
611
+ default_prob: 0.3
612
+ suns:
613
+ v: 0.75
614
+ range:
615
+ - 0.1
616
+ - 1.95
617
+ type: float
618
+ skirt-many-panels:
619
+ n_panels:
620
+ v: 4
621
+ range:
622
+ - 4
623
+ - 15
624
+ type: int
625
+ panel_curve:
626
+ v: 0
627
+ range:
628
+ - -0.35
629
+ - -0.25
630
+ - -0.15
631
+ - 0
632
+ - 0.15
633
+ - 0.25
634
+ - 0.35
635
+ - 0.45
636
+ type: select
637
+ asymm:
638
+ front_length:
639
+ v: 0.5
640
+ range:
641
+ - 0.1
642
+ - 0.9
643
+ type: float
644
+ default_prob: 0.5
645
+ cut:
646
+ add:
647
+ v: false
648
+ range:
649
+ - true
650
+ - false
651
+ type: bool
652
+ default_prob: 0.6
653
+ depth:
654
+ v: 0.5
655
+ range:
656
+ - 0.05
657
+ - 0.95
658
+ type: float
659
+ default_prob: 0.6
660
+ width:
661
+ v: 0.1
662
+ range:
663
+ - 0.05
664
+ - 0.4
665
+ type: float
666
+ place:
667
+ v: -0.5
668
+ range:
669
+ - -1
670
+ - 1
671
+ type: float
672
+ godet-skirt:
673
+ base:
674
+ v: PencilSkirt
675
+ range:
676
+ - Skirt2
677
+ - PencilSkirt
678
+ type: select
679
+ default_prob: 0.7
680
+ insert_w:
681
+ v: 15
682
+ range:
683
+ - 10
684
+ - 50
685
+ type: int
686
+ insert_depth:
687
+ v: 20
688
+ range:
689
+ - 10
690
+ - 50
691
+ type: int
692
+ num_inserts:
693
+ v: 4
694
+ range:
695
+ - 4
696
+ - 6
697
+ - 8
698
+ - 10
699
+ - 12
700
+ type: select
701
+ cuts_distance:
702
+ v: 5
703
+ range:
704
+ - 0
705
+ - 10
706
+ type: int
707
+ pencil-skirt:
708
+ length:
709
+ v: 0.4
710
+ range:
711
+ - 0.2
712
+ - 0.95
713
+ type: float
714
+ rise:
715
+ v: 1
716
+ range:
717
+ - 0.5
718
+ - 1
719
+ type: float
720
+ default_prob: 0.3
721
+ flare:
722
+ v: 1.
723
+ range:
724
+ - 0.6
725
+ - 1.5
726
+ type: float
727
+ default_prob: 0.3
728
+ low_angle:
729
+ v: 0
730
+ range:
731
+ - -30
732
+ - 30
733
+ type: int
734
+ default_prob: 0.7
735
+ front_slit:
736
+ v: 0
737
+ range:
738
+ - 0
739
+ - 0.9
740
+ type: float
741
+ default_prob: 0.4
742
+ back_slit:
743
+ v: 0
744
+ range:
745
+ - 0
746
+ - 0.9
747
+ type: float
748
+ default_prob: 0.4
749
+ left_slit:
750
+ v: 0
751
+ range:
752
+ - 0
753
+ - 0.9
754
+ type: float
755
+ default_prob: 0.6
756
+ right_slit:
757
+ v: 0
758
+ range:
759
+ - 0
760
+ - 0.9
761
+ type: float
762
+ default_prob: 0.6
763
+ style_side_cut:
764
+ v: null
765
+ range:
766
+ - Sun
767
+ - SIGGRAPH_logo
768
+ type: select_null
769
+ default_prob: 1.
770
+ levels-skirt:
771
+ base:
772
+ v: PencilSkirt
773
+ range:
774
+ - Skirt2
775
+ - PencilSkirt
776
+ - SkirtCircle
777
+ - AsymmSkirtCircle
778
+ type: select
779
+ level:
780
+ v: Skirt2
781
+ range:
782
+ - Skirt2
783
+ - SkirtCircle
784
+ - AsymmSkirtCircle
785
+ type: select
786
+ num_levels:
787
+ v: 1
788
+ range:
789
+ - 1
790
+ - 5
791
+ type: int
792
+ level_ruffle:
793
+ v: 1.0
794
+ range:
795
+ - 1
796
+ - 1.7
797
+ type: float
798
+ length:
799
+ v: 0.5
800
+ range:
801
+ - 0.2
802
+ - 0.95
803
+ type: float
804
+ rise:
805
+ v: 1
806
+ range:
807
+ - 0.5
808
+ - 1
809
+ type: float
810
+ default_prob: 0.3
811
+ base_length_frac:
812
+ v: 0.5
813
+ range:
814
+ - 0.2
815
+ - 0.8
816
+ type: float
817
+ pants:
818
+ length:
819
+ v: 0.3
820
+ range:
821
+ - 0.2
822
+ - 0.9
823
+ type: float
824
+ width:
825
+ v: 1.0
826
+ range:
827
+ - 1.0
828
+ - 1.5
829
+ type: float
830
+ default_prob: 0.5
831
+ flare:
832
+ v: 1.0
833
+ range:
834
+ - 0.5
835
+ - 1.2
836
+ type: float
837
+ default_prob: 0.3
838
+ rise:
839
+ v: 1.0
840
+ range:
841
+ - 0.5
842
+ - 1
843
+ type: float
844
+ default_prob: 0.3
845
+ cuff:
846
+ type:
847
+ v: null
848
+ range:
849
+ - CuffBand
850
+ - CuffSkirt
851
+ - CuffBandSkirt
852
+ - null
853
+ type: select_null
854
+ default_prob: 0.5
855
+ top_ruffle:
856
+ v: 1.0
857
+ range:
858
+ - 1
859
+ - 2
860
+ type: float
861
+ cuff_len:
862
+ v: 0.1
863
+ range:
864
+ - 0.05
865
+ - 0.9
866
+ type: float
867
+ default_prob: 0.3
868
+ skirt_fraction:
869
+ v: 0.5
870
+ range:
871
+ - 0.1
872
+ - 0.9
873
+ type: float
874
+ skirt_flare:
875
+ v: 1.2
876
+ range:
877
+ - 1
878
+ - 2
879
+ type: float
880
+ skirt_ruffle:
881
+ v: 1.0
882
+ range:
883
+ - 1
884
+ - 1.5
885
+ type: float
GarmentCode/assets/garment_programs/bands.py ADDED
@@ -0,0 +1,262 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pygarment as pyg
2
+ from assets.garment_programs.circle_skirt import CircleArcPanel
3
+ from assets.garment_programs import skirt_paneled
4
+ from assets.garment_programs.base_classes import BaseBand
5
+
6
+ class StraightBandPanel(pyg.Panel):
7
+ """One panel for a panel skirt"""
8
+
9
+ def __init__(self, name, width, depth, match_int_proportion=None) -> None:
10
+ super().__init__(name)
11
+
12
+ # define edge loop
13
+ self.edges = pyg.EdgeSeqFactory.from_verts(
14
+ [0, 0], [0, depth], [width, depth], [width, 0], loop=True)
15
+
16
+ # define interface
17
+ self.interfaces = {
18
+ 'right': pyg.Interface(self, self.edges[0]),
19
+ 'top': pyg.Interface(self,
20
+ self.edges[1],
21
+ ruffle=width / match_int_proportion if match_int_proportion is not None else 1.
22
+ ).reverse(True),
23
+ 'left': pyg.Interface(self, self.edges[2]),
24
+ 'bottom': pyg.Interface(self,
25
+ self.edges[3],
26
+ ruffle=width / match_int_proportion if match_int_proportion is not None else 1.
27
+ )
28
+ }
29
+
30
+ # Default translation
31
+ self.top_center_pivot()
32
+ self.center_x()
33
+
34
+
35
+ class StraightWB(BaseBand):
36
+ """Simple 2 panel waistband"""
37
+ def __init__(self, body, design, rise=1.) -> None:
38
+ """Simple 2 panel waistband
39
+
40
+ * rise -- the rise value of the bottoms that the WB is attached to
41
+ Adapts the shape of the waistband to sit tight on top
42
+ of the given rise level (top measurement). If 1. or anything less than waistband width,
43
+ the rise is ignored and the StraightWB is created to sit well on the waist
44
+
45
+ """
46
+ super().__init__(body, design, rise=rise)
47
+
48
+ # Measurements
49
+ self.waist = design['waistband']['waist']['v'] * body['waist']
50
+ self.waist_back_frac = body['waist_back_width'] / body['waist']
51
+ self.hips = body['hips'] * design['waistband']['waist']['v']
52
+ self.hips_back_frac = body['hip_back_width'] / body['hips']
53
+
54
+ # Params
55
+ self.width = design['waistband']['width']['v']
56
+ self.rise = rise
57
+ # Check correct values
58
+ if self.rise + self.width > 1:
59
+ self.rise = 1 - self.width
60
+
61
+ self.top_width = pyg.utils.lin_interpolation(
62
+ self.hips, self.waist, self.rise + self.width)
63
+ self.top_back_fraction = pyg.utils.lin_interpolation(
64
+ self.hips_back_frac, self.waist_back_frac, self.rise + self.width)
65
+
66
+ self.width = self.width * body['hips_line']
67
+
68
+ self.define_panels()
69
+
70
+ self.front.translate_by([0, body['_waist_level'], 20])
71
+ self.back.translate_by([0, body['_waist_level'], -15])
72
+
73
+ self.stitching_rules = pyg.Stitches(
74
+ (self.front.interfaces['right'], self.back.interfaces['right']),
75
+ (self.front.interfaces['left'], self.back.interfaces['left'])
76
+ )
77
+
78
+ self.interfaces = {
79
+ 'bottom_f': self.front.interfaces['bottom'],
80
+ 'bottom_b': self.back.interfaces['bottom'],
81
+
82
+ 'top_f': self.front.interfaces['top'],
83
+ 'top_b': self.back.interfaces['top'],
84
+
85
+ 'bottom': pyg.Interface.from_multiple(
86
+ self.front.interfaces['bottom'],
87
+ self.back.interfaces['bottom']),
88
+ 'top': pyg.Interface.from_multiple(
89
+ self.front.interfaces['top'],
90
+ self.back.interfaces['top']),
91
+ }
92
+
93
+ def define_panels(self):
94
+ back_width = self.top_width * self.top_back_fraction
95
+
96
+ self.front = StraightBandPanel(
97
+ 'wb_front',
98
+ self.top_width - back_width,
99
+ self.width,
100
+ match_int_proportion=self.body['waist'] - self.body['waist_back_width']
101
+ )
102
+
103
+ self.back = StraightBandPanel(
104
+ 'wb_back',
105
+ back_width,
106
+ self.width,
107
+ match_int_proportion=self.body['waist_back_width']
108
+ )
109
+
110
+
111
+ class FittedWB(StraightWB):
112
+ """Also known as Yoke: a waistband that ~follows the body curvature,
113
+ and hence sits tight
114
+ Made out of two circular arc panels
115
+ """
116
+ def __init__(self, body, design, rise=1.) -> None:
117
+ """A waistband that ~follows the body curvature, and hence sits tight
118
+
119
+ * rise -- the rise value of the bottoms that the WB is attached to
120
+ Adapts the shape of the waistband to sit tight on top
121
+ of the given rise level. If 1. or anything less than waistband width,
122
+ the rise is ignored and the FittedWB is created to sit well on the waist
123
+ """
124
+ self.bottom_width = None
125
+ self.bottom_back_fraction = None
126
+ super().__init__(body, design, rise)
127
+
128
+ def define_panels(self):
129
+ self.bottom_width = pyg.utils.lin_interpolation(
130
+ self.hips, self.waist, self.rise)
131
+ self.bottom_back_fraction = pyg.utils.lin_interpolation(
132
+ self.hips_back_frac, self.waist_back_frac, self.rise)
133
+
134
+ self.front = CircleArcPanel.from_all_length(
135
+ 'wb_front',
136
+ self.width,
137
+ self.top_width * (1 - self.top_back_fraction),
138
+ self.bottom_width * (1 - self.bottom_back_fraction),
139
+ match_top_int_proportion=self.body['waist'] - self.body['waist_back_width'],
140
+ match_bottom_int_proportion=self.body['waist'] - self.body['waist_back_width']
141
+ )
142
+
143
+ self.back = CircleArcPanel.from_all_length(
144
+ 'wb_back',
145
+ self.width,
146
+ self.top_width * self.top_back_fraction,
147
+ self.bottom_width * self.bottom_back_fraction,
148
+ match_top_int_proportion=self.body['waist_back_width'],
149
+ match_bottom_int_proportion=self.body['waist_back_width']
150
+ )
151
+
152
+
153
+ class CuffBand(BaseBand):
154
+ """ Cuff class for sleeves or pants
155
+ band-like piece of fabric with optional "skirt"
156
+ """
157
+ def __init__(self, tag, design, length=None) -> None:
158
+ super().__init__(body=None, design=design, tag=tag)
159
+
160
+ self.design = design['cuff']
161
+
162
+ if length is None:
163
+ length = self.design['cuff_len']['v']
164
+
165
+ self.front = StraightBandPanel(
166
+ f'{tag}_cuff_f', self.design['b_width']['v'] / 2, length)
167
+ self.front.translate_by([0, 0, 15])
168
+ self.back = StraightBandPanel(
169
+ f'{tag}_cuff_b', self.design['b_width']['v'] / 2, length)
170
+ self.back.translate_by([0, 0, -15])
171
+
172
+ self.stitching_rules = pyg.Stitches(
173
+ (self.front.interfaces['right'], self.back.interfaces['right']),
174
+ (self.front.interfaces['left'], self.back.interfaces['left'])
175
+ )
176
+
177
+ self.interfaces = {
178
+ 'bottom': pyg.Interface.from_multiple(
179
+ self.front.interfaces['bottom'],
180
+ self.back.interfaces['bottom']),
181
+ 'top_front': self.front.interfaces['top'],
182
+ 'top_back': self.back.interfaces['top'],
183
+ 'top': pyg.Interface.from_multiple(
184
+ self.front.interfaces['top'],
185
+ self.back.interfaces['top']),
186
+ }
187
+
188
+
189
+ class CuffSkirt(BaseBand):
190
+ """A skirt-like flared cuff """
191
+
192
+ def __init__(self, tag, design, length=None) -> None:
193
+ super().__init__(body=None, design=design, tag=tag)
194
+
195
+ self.design = design['cuff']
196
+ width = self.design['b_width']['v']
197
+ flare_diff = (self.design['skirt_flare']['v'] - 1) * width / 2
198
+
199
+ if length is None:
200
+ length = self.design['cuff_len']['v']
201
+
202
+ self.front = skirt_paneled.SkirtPanel(
203
+ f'{tag}_cuff_skirt_f', ruffles=self.design['skirt_ruffle']['v'],
204
+ waist_length=width / 2, length=length,
205
+ flare=flare_diff)
206
+ self.front.translate_by([0, 0, 15])
207
+ self.back = skirt_paneled.SkirtPanel(
208
+ f'{tag}_cuff_skirt_b', ruffles=self.design['skirt_ruffle']['v'],
209
+ waist_length=width / 2, length=length,
210
+ flare=flare_diff)
211
+ self.back.translate_by([0, 0, -15])
212
+
213
+ self.stitching_rules = pyg.Stitches(
214
+ (self.front.interfaces['right'], self.back.interfaces['right']),
215
+ (self.front.interfaces['left'], self.back.interfaces['left'])
216
+ )
217
+
218
+ self.interfaces = {
219
+ 'top': pyg.Interface.from_multiple(
220
+ self.front.interfaces['top'], self.back.interfaces['top']),
221
+ 'top_front': self.front.interfaces['top'],
222
+ 'top_back': self.back.interfaces['top'],
223
+ 'bottom': pyg.Interface.from_multiple(
224
+ self.front.interfaces['bottom'],
225
+ self.back.interfaces['bottom']),
226
+ }
227
+
228
+
229
+ class CuffBandSkirt(pyg.Component):
230
+ """ Cuff class for sleeves or pants
231
+ band-like piece of fabric with optional "skirt"
232
+ """
233
+ def __init__(self, tag, design) -> None:
234
+ super().__init__(self.__class__.__name__)
235
+
236
+ self.cuff = CuffBand(
237
+ tag,
238
+ design,
239
+ length=design['cuff']['cuff_len']['v'] * (1 - design['cuff']['skirt_fraction']['v'])
240
+ )
241
+ self.skirt = CuffSkirt(
242
+ tag,
243
+ design,
244
+ length=design['cuff']['cuff_len']['v'] * design['cuff']['skirt_fraction']['v']
245
+ )
246
+
247
+ # Align
248
+ self.skirt.place_below(self.cuff)
249
+
250
+ self.stitching_rules = pyg.Stitches(
251
+ (self.cuff.interfaces['bottom'], self.skirt.interfaces['top']),
252
+ )
253
+
254
+ self.interfaces = {
255
+ 'top': self.cuff.interfaces['top'],
256
+ 'top_front': self.cuff.interfaces['top_front'],
257
+ 'top_back': self.cuff.interfaces['top_back'],
258
+ 'bottom': self.skirt.interfaces['bottom']
259
+ }
260
+
261
+ def length(self):
262
+ return self.cuff.length() + self.skirt.length()
GarmentCode/assets/garment_programs/base_classes.py ADDED
@@ -0,0 +1,122 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pygarment as pyg
2
+
3
+ class BaseBodicePanel(pyg.Panel):
4
+ """Base class for bodice panels that defines expected interfaces and common functions"""
5
+ def __init__(self, name, body, design) -> None:
6
+ super().__init__(name)
7
+ self.body = body
8
+ self.design = design
9
+
10
+ self.interfaces = {
11
+ 'outside': object(),
12
+ 'inside': object(),
13
+ 'shoulder': object(),
14
+ 'bottom': object(),
15
+
16
+ 'shoulder_corner': object(),
17
+ 'collar_corner': object(),
18
+ }
19
+
20
+ def get_width(self, level):
21
+ """Return the panel width at a given level (excluding darts)
22
+ * Level is counted from the top of the panel
23
+
24
+ NOTE: for fitted bodice, the request is only valid for values between 0 and bust_level
25
+ """
26
+ # NOTE: this evaluation assumes that the top edge width is the same as bodice shoulder width
27
+ side_edge = self.interfaces['outside'].edges[-1]
28
+
29
+ x = side_edge.end[0] - side_edge.start[0]
30
+ y = side_edge.end[1] - side_edge.start[1]
31
+
32
+ # If the orientation of the edge is "looking down"
33
+ # instead of "looking up" as calculations above expect, flip the values
34
+ if y < 0:
35
+ x, y = -x, -y
36
+
37
+ return (level * x / y) + self.body['shoulder_w'] / 2
38
+
39
+
40
+ class BaseBottoms(pyg.Component):
41
+ """A base class for all the bottom components.
42
+ Defines common elements:
43
+ * List of interfaces
44
+ * Presence of the rise value
45
+ """
46
+ def __init__(self, body, design, tag='', rise=None) -> None:
47
+ """Base bottoms initialization
48
+ """
49
+ super().__init__(
50
+ self.__class__.__name__ if not tag else f'{self.__class__.__name__}_{tag}')
51
+
52
+ self.body = body
53
+ self.design = design
54
+ self.rise = rise
55
+
56
+ # Set of interfaces that need to be implemented
57
+ self.interfaces = {
58
+ 'top': object()
59
+ }
60
+
61
+ def get_rise(self):
62
+ """Return a rise value for a given component"""
63
+ return self.rise
64
+
65
+ def eval_rise(self, rise):
66
+ """Evaluate updated hip and waist-related measurements,
67
+ corresponding to the provided rise value
68
+ """
69
+ waist, hips = self.body['waist'], self.body['hips']
70
+ hips_level = self.body['hips_line']
71
+ self.adj_hips_depth = rise * hips_level
72
+ self.adj_waist = pyg.utils.lin_interpolation(hips, waist, rise)
73
+
74
+ self_adj_back_waist = pyg.utils.lin_interpolation(
75
+ self.body['hip_back_width'], self.body['waist_back_width'], rise)
76
+
77
+ return self.adj_waist, self.adj_hips_depth, self_adj_back_waist
78
+
79
+ class StackableSkirtComponent(BaseBottoms):
80
+ """
81
+ Abstract definition of a skirt that can be stacked with other stackable skirts
82
+ (connecting bottom to another StackableSkirtComponent())
83
+ """
84
+
85
+ def __init__(self, body, design, tag='', length=None, rise=None, slit=True, top_ruffles=True) -> None:
86
+ """Skirt initialization
87
+
88
+ Extra parameters (length, sleets, top_ruffles)
89
+ can be used to overwrite parameters in design dictionary
90
+ """
91
+ super().__init__(body, design, tag, rise=rise)
92
+
93
+ pass
94
+
95
+ # Set of interfaces that need to be implemented
96
+ self.interfaces = {
97
+ 'top': object(),
98
+ 'bottom_f': object(),
99
+ 'bottom_b': object(),
100
+ 'bottom': object()
101
+ }
102
+
103
+
104
+ class BaseBand(pyg.Component):
105
+ def __init__(self, body, design, tag='', rise=None) -> None:
106
+ """Base band initialization
107
+ """
108
+ super().__init__(
109
+ self.__class__.__name__ if not tag else f'{self.__class__.__name__}_{tag}')
110
+ self.body = body
111
+ self.design = design
112
+ self.rise = rise
113
+
114
+ # Set of interfaces that need to be implemented
115
+ self.interfaces = {
116
+ 'top': object(),
117
+ 'bottom': object()
118
+ }
119
+
120
+ def length(self):
121
+ """Base length == Length of a first panel"""
122
+ return self._get_subcomponents()[0].length()
GarmentCode/assets/garment_programs/bodice.py ADDED
@@ -0,0 +1,491 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from copy import deepcopy
2
+ import numpy as np
3
+
4
+ import pygarment as pyg
5
+
6
+
7
+ from assets.garment_programs.base_classes import BaseBodicePanel
8
+ from assets.garment_programs import sleeves
9
+ from assets.garment_programs import collars
10
+ from assets.garment_programs import tee
11
+ from scipy.spatial.transform import Rotation as R
12
+
13
+ class BodiceFrontHalf(BaseBodicePanel):
14
+ def __init__(self, name, body, design) -> None:
15
+ super().__init__(name, body, design)
16
+
17
+ m_bust = body['bust']
18
+ m_waist = body['waist']
19
+
20
+ # sizes
21
+ bust_point = body['bust_points'] / 2
22
+ front_frac = (body['bust'] - body['back_width']) / 2 / body['bust']
23
+
24
+ self.width = front_frac * m_bust
25
+ waist = (m_waist - body['waist_back_width']) / 2
26
+ sh_tan = np.tan(np.deg2rad(body['_shoulder_incl']))
27
+ shoulder_incl = sh_tan * self.width
28
+ bottom_d_width = (self.width - waist) * 2 / 3
29
+
30
+ adjustment = sh_tan * (self.width - body['shoulder_w'] / 2)
31
+ max_len = body['waist_over_bust_line'] - adjustment
32
+
33
+ # side length is adjusted due to shoulder inclination
34
+ # for the correct sleeve fitting
35
+ fb_diff = (front_frac - (0.5 - front_frac)) * body['bust']
36
+ back_adjustment = sh_tan * (body['back_width'] / 2 - body['shoulder_w'] / 2)
37
+ side_len = body['waist_line'] - back_adjustment - sh_tan * fb_diff
38
+
39
+ self.edges.append(pyg.EdgeSeqFactory.from_verts(
40
+ [0, 0],
41
+ [-self.width, 0],
42
+ [-self.width, max_len],
43
+ [0, max_len + shoulder_incl]
44
+ ))
45
+ self.edges.close_loop()
46
+
47
+ # Side dart
48
+ bust_line = body['waist_line'] - body['_bust_line']
49
+ side_d_depth = 0.75 * (self.width - bust_point) # NOTE: calculated value
50
+ side_d_width = max_len - side_len
51
+ s_edge, side_interface = self.add_dart(
52
+ pyg.EdgeSeqFactory.dart_shape(side_d_width, side_d_depth),
53
+ self.edges[1],
54
+ offset=bust_line + side_d_width / 2)
55
+ self.edges.substitute(1, s_edge)
56
+
57
+ # Take some fabric from the top to match the shoulder width
58
+ s_edge[-1].end[0] += (x_upd:=self.width - body['shoulder_w'] / 2)
59
+ s_edge[-1].end[1] += (sh_tan * x_upd)
60
+
61
+ # Bottom dart
62
+ b_edge, b_interface = self.add_dart(
63
+ pyg.EdgeSeqFactory.dart_shape(bottom_d_width, 0.9 * bust_line),
64
+ self.edges[0],
65
+ offset=bust_point + bottom_d_width / 2
66
+ )
67
+ self.edges.substitute(0, b_edge)
68
+ # Take some fabric from side in the bottom (!: after side dart insertion)
69
+ b_edge[-1].end[0] = - (waist + bottom_d_width)
70
+
71
+ # Interfaces
72
+ self.interfaces = {
73
+ 'outside': pyg.Interface(self, side_interface), # side_interface, # pyp.Interface(self, [side_interface]), #, self.edges[-3]]),
74
+ 'inside': pyg.Interface(self, self.edges[-1]),
75
+ 'shoulder': pyg.Interface(self, self.edges[-2]),
76
+ 'bottom': pyg.Interface(self, b_interface),
77
+
78
+ # Reference to the corner for sleeve and collar projections
79
+ 'shoulder_corner': pyg.Interface(
80
+ self, [self.edges[-3], self.edges[-2]]),
81
+ 'collar_corner': pyg.Interface(
82
+ self, [self.edges[-2], self.edges[-1]])
83
+ }
84
+
85
+ # default placement
86
+ self.translate_by([0, body['height'] - body['head_l'] - max_len - shoulder_incl, 0])
87
+
88
+
89
+ class BodiceBackHalf(BaseBodicePanel):
90
+ """Panel for the back of basic fitted bodice block"""
91
+
92
+ def __init__(self, name, body, design) -> None:
93
+ super().__init__(name, body, design)
94
+
95
+ # Overall measurements
96
+ self.width = body['back_width'] / 2
97
+ waist = body['waist_back_width'] / 2
98
+ # NOTE: no inclination on the side, since there is not much to begin with
99
+ waist_width = self.width if waist < self.width else waist
100
+ shoulder_incl = (sh_tan:=np.tan(np.deg2rad(body['_shoulder_incl']))) * self.width
101
+
102
+ # Adjust to make sure length is measured from the shoulder
103
+ # and not the de-fact side of the garment
104
+ back_adjustment = sh_tan * (self.width - body['shoulder_w'] / 2)
105
+ length = body['waist_line'] - back_adjustment
106
+
107
+ # Base edge loop
108
+ edge_0 = pyg.CurveEdgeFactory.curve_from_tangents(
109
+ start=[0, shoulder_incl / 4], # back a little shorter
110
+ end=[-waist_width, 0],
111
+ target_tan0=[-1, 0]
112
+ )
113
+ self.edges.append(edge_0)
114
+ self.edges.append(pyg.EdgeSeqFactory.from_verts(
115
+ edge_0.end,
116
+ [-self.width, body['waist_line'] - body['_bust_line']], # from the bottom
117
+ [-self.width, length],
118
+ [0, length + shoulder_incl], # Add some fabric for the neck (inclination of shoulders)
119
+ ))
120
+ self.edges.close_loop()
121
+
122
+ # Take some fabric from the top to match the shoulder width
123
+ self.interfaces = {
124
+ 'outside': pyg.Interface(
125
+ self, [self.edges[1], self.edges[2]]),
126
+ 'inside': pyg.Interface(self, self.edges[-1]),
127
+ 'shoulder': pyg.Interface(self, self.edges[-2]),
128
+ 'bottom': pyg.Interface(self, self.edges[0]),
129
+ # Reference to the corners for sleeve and collar projections
130
+ 'shoulder_corner': pyg.Interface(
131
+ self, pyg.EdgeSequence(self.edges[-3], self.edges[-2])),
132
+ 'collar_corner': pyg.Interface(
133
+ self, pyg.EdgeSequence(self.edges[-2], self.edges[-1]))
134
+ }
135
+
136
+ # Bottom dart as cutout -- for straight line
137
+ if waist < self.get_width(self.edges[2].end[1] - self.edges[2].start[1]):
138
+ w_diff = waist_width - waist
139
+ side_adj = 0 if w_diff < 4 else w_diff / 6 # NOTE: don't take from sides if the difference is too small
140
+ bottom_d_width = w_diff - side_adj
141
+ bottom_d_width /= 2 # double darts
142
+ bottom_d_depth = 1. * (length - body['_bust_line']) # calculated value
143
+ bottom_d_position = body['bum_points'] / 2
144
+
145
+ # TODOLOW Avoid hardcoding for matching with the bottoms?
146
+ dist = bottom_d_position * 0.5 # Dist between darts -> dist between centers
147
+ b_edge, b_interface = self.add_dart(
148
+ pyg.EdgeSeqFactory.dart_shape(bottom_d_width, 0.9 * bottom_d_depth),
149
+ self.edges[0],
150
+ offset=bottom_d_position + dist / 2 + bottom_d_width + bottom_d_width / 2,
151
+ )
152
+ b_edge, b_interface = self.add_dart(
153
+ pyg.EdgeSeqFactory.dart_shape(bottom_d_width, bottom_d_depth),
154
+ b_edge[0],
155
+ offset=bottom_d_position - dist / 2 + bottom_d_width / 2,
156
+ edge_seq=b_edge,
157
+ int_edge_seq=b_interface,
158
+ )
159
+
160
+ self.edges.substitute(0, b_edge)
161
+ self.interfaces['bottom'] = pyg.Interface(self, b_interface)
162
+
163
+ # Remove fabric from the sides if the diff is big enough
164
+ b_edge[-1].end[0] += side_adj
165
+
166
+ # default placement
167
+ self.translate_by([0, body['height'] - body['head_l'] - length - shoulder_incl, 0])
168
+
169
+ def get_width(self, level):
170
+ return self.width
171
+
172
+ class BodiceHalf(pyg.Component):
173
+ """Definition of a half of an upper garment with sleeves and collars"""
174
+
175
+ def __init__(self, name, body, design, fitted=True) -> None:
176
+ super().__init__(name)
177
+
178
+ design = deepcopy(design) # Recalculate freely!
179
+
180
+ # Torso
181
+ if fitted:
182
+ self.ftorso = BodiceFrontHalf(
183
+ f'{name}_ftorso', body, design).translate_by([0, 0, 30])
184
+ self.btorso = BodiceBackHalf(
185
+ f'{name}_btorso', body, design).translate_by([0, 0, -25])
186
+ else:
187
+ self.ftorso = tee.TorsoFrontHalfPanel(
188
+ f'{name}_ftorso', body, design).translate_by([0, 0, 30])
189
+ self.btorso = tee.TorsoBackHalfPanel(
190
+ f'{name}_btorso', body, design).translate_by([0, 0, -25])
191
+
192
+ # Interfaces
193
+ self.interfaces.update({
194
+ 'f_bottom': self.ftorso.interfaces['bottom'],
195
+ 'b_bottom': self.btorso.interfaces['bottom'],
196
+ 'front_in': self.ftorso.interfaces['inside'],
197
+ 'back_in': self.btorso.interfaces['inside']
198
+ })
199
+
200
+ # Sleeves/collar cuts
201
+ self.sleeve = None
202
+ self.collar_comp = None
203
+ self.eval_dep_params(body, design)
204
+
205
+ if design['shirt']['strapless']['v'] and fitted: # NOTE: Strapless design only for fitted tops
206
+ self.make_strapless(body, design)
207
+ else:
208
+ # Sleeves and collars
209
+ self.add_sleeves(name, body, design)
210
+ self.add_collars(name, body, design)
211
+ self.stitching_rules.append((
212
+ self.ftorso.interfaces['shoulder'],
213
+ self.btorso.interfaces['shoulder']
214
+ )) # tops
215
+
216
+ # Main connectivity
217
+ self.stitching_rules.append((
218
+ self.ftorso.interfaces['outside'], self.btorso.interfaces['outside'])) # sides
219
+
220
+ def eval_dep_params(self, body, design):
221
+
222
+ # Sleeves
223
+ # NOTE assuming the vertical side is the first argument
224
+ max_cwidth = self.ftorso.interfaces['shoulder_corner'].edges[0].length() - 1 # cm
225
+ min_cwidth = body['_armscye_depth']
226
+ v = design['sleeve']['connecting_width']['v']
227
+ design['sleeve']['connecting_width']['v'] = min(min_cwidth + min_cwidth * v, max_cwidth)
228
+
229
+ # Collars
230
+ # NOTE: Assuming the first is the top edge
231
+ # Width
232
+ # TODOLOW What if sleeve inclination is variable?
233
+ # NOTE: Back panel is more narrow, so using it
234
+ max_w = body['_base_sleeve_balance'] - 2 # 1 cm from default sleeve
235
+ min_w = body['neck_w']
236
+
237
+ if design['collar']['width']['v'] >= 0:
238
+ design['collar']['width']['v'] = width = pyg.utils.lin_interpolation(min_w, max_w, design['collar']['width']['v'])
239
+ else:
240
+ design['collar']['width']['v'] = width = pyg.utils.lin_interpolation(0, min_w, 1 + design['collar']['width']['v'])
241
+
242
+ # Depth
243
+ # Collar depth is given w.r.t. length.
244
+ # adjust for the shoulder inclination
245
+ tg = np.tan(np.deg2rad(body['_shoulder_incl']))
246
+ f_depth_adj = tg * (self.ftorso.get_width(0) - width / 2)
247
+ b_depth_adj = tg * (self.btorso.get_width(0) - width / 2)
248
+
249
+ max_f_len = self.ftorso.interfaces['collar_corner'].edges[1].length() - tg * self.ftorso.get_width(0) - 1 # cm
250
+ max_b_len = self.btorso.interfaces['collar_corner'].edges[1].length() - tg * self.btorso.get_width(0) - 1 # cm
251
+
252
+ design['collar']['f_strapless_depth'] = {}
253
+ design['collar']['f_strapless_depth']['v'] = min(
254
+ design['collar']['fc_depth']['v'] * body['_bust_line'],
255
+ max_f_len)
256
+ design['collar']['fc_depth']['v'] = design['collar']['f_strapless_depth']['v'] + f_depth_adj
257
+
258
+
259
+ design['collar']['b_strapless_depth'] = {}
260
+ design['collar']['b_strapless_depth']['v'] = min(
261
+ design['collar']['bc_depth']['v'] * body['_bust_line'],
262
+ max_b_len)
263
+ design['collar']['bc_depth']['v'] = design['collar']['b_strapless_depth']['v'] + b_depth_adj
264
+
265
+ def add_sleeves(self, name, body, design):
266
+ self.sleeve = sleeves.Sleeve(
267
+ name, body, design,
268
+ front_w=self.ftorso.get_width,
269
+ back_w=self.btorso.get_width
270
+ )
271
+
272
+ _, f_sleeve_int = pyg.ops.cut_corner(
273
+ self.sleeve.interfaces['in_front_shape'].edges,
274
+ self.ftorso.interfaces['shoulder_corner'],
275
+ verbose=self.verbose
276
+ )
277
+ _, b_sleeve_int = pyg.ops.cut_corner(
278
+ self.sleeve.interfaces['in_back_shape'].edges,
279
+ self.btorso.interfaces['shoulder_corner'],
280
+ verbose=self.verbose
281
+ )
282
+
283
+ if not design['sleeve']['sleeveless']['v']:
284
+ # Ordering
285
+ bodice_sleeve_int = pyg.Interface.from_multiple(
286
+ f_sleeve_int.reverse(with_edge_dir_reverse=True),
287
+ b_sleeve_int.reverse(),
288
+ )
289
+ self.stitching_rules.append((
290
+ self.sleeve.interfaces['in'],
291
+ bodice_sleeve_int
292
+ ))
293
+
294
+ # NOTE: This is a heuristic tuned for arm poses 30 deg-60 deg
295
+ # used in the dataset
296
+ # FIXME Needs a better general solution
297
+ gap = -1 - body['arm_pose_angle'] / 10
298
+ self.sleeve.place_by_interface(
299
+ self.sleeve.interfaces['in'],
300
+ bodice_sleeve_int,
301
+ gap=gap,
302
+ alignment='top',
303
+ )
304
+
305
+ # Add edge labels
306
+ f_sleeve_int.edges.propagate_label(f'{self.name}_armhole')
307
+ b_sleeve_int.edges.propagate_label(f'{self.name}_armhole')
308
+
309
+ def add_collars(self, name, body, design):
310
+ # Front
311
+ collar_type = getattr(
312
+ collars,
313
+ str(design['collar']['component']['style']['v']),
314
+ collars.NoPanelsCollar
315
+ )
316
+
317
+ self.collar_comp = collar_type(name, body, design)
318
+
319
+ # Project shape
320
+ _, fc_interface = pyg.ops.cut_corner(
321
+ self.collar_comp.interfaces['front_proj'].edges,
322
+ self.ftorso.interfaces['collar_corner'],
323
+ verbose=self.verbose
324
+ )
325
+ _, bc_interface = pyg.ops.cut_corner(
326
+ self.collar_comp.interfaces['back_proj'].edges,
327
+ self.btorso.interfaces['collar_corner'],
328
+ verbose=self.verbose
329
+ )
330
+
331
+ # Add stitches/interfaces
332
+ if 'bottom' in self.collar_comp.interfaces:
333
+ self.stitching_rules.append((
334
+ pyg.Interface.from_multiple(fc_interface, bc_interface),
335
+ self.collar_comp.interfaces['bottom']
336
+ ))
337
+
338
+ # Upd front interfaces accordingly
339
+ if 'front' in self.collar_comp.interfaces:
340
+ self.interfaces['front_collar'] = self.collar_comp.interfaces['front']
341
+ self.interfaces['front_in'] = pyg.Interface.from_multiple(
342
+ self.ftorso.interfaces['inside'], self.interfaces['front_collar']
343
+ )
344
+ if 'back' in self.collar_comp.interfaces:
345
+ self.interfaces['back_collar'] = self.collar_comp.interfaces['back']
346
+ self.interfaces['back_in'] = pyg.Interface.from_multiple(
347
+ self.btorso.interfaces['inside'], self.interfaces['back_collar']
348
+ )
349
+
350
+ # Add edge labels
351
+ fc_interface.edges.propagate_label(f'{self.name}_collar')
352
+ bc_interface.edges.propagate_label(f'{self.name}_collar')
353
+
354
+ def make_strapless(self, body, design):
355
+
356
+ out_depth = design['sleeve']['connecting_width']['v']
357
+ f_in_depth = design['collar']['f_strapless_depth']['v']
358
+ b_in_depth = design['collar']['b_strapless_depth']['v']
359
+
360
+ # Shoulder adjustment for the back
361
+ # TODOLOW Shoulder adj evaluation should be a function
362
+ shoulder_angle = np.deg2rad(body['_shoulder_incl'])
363
+ sleeve_balance = body['_base_sleeve_balance'] / 2
364
+ back_w = self.btorso.get_width(0)
365
+ shoulder_adj = np.tan(shoulder_angle) * (back_w - sleeve_balance)
366
+ out_depth -= shoulder_adj
367
+
368
+ # Upd back
369
+ self._adjust_top_level(self.btorso, out_depth, b_in_depth)
370
+
371
+ # Front depth determined by ~compensating for lenght difference
372
+ len_back = self.btorso.interfaces['outside'].edges.length()
373
+ len_front = self.ftorso.interfaces['outside'].edges.length()
374
+ self._adjust_top_level(self.ftorso, out_depth, f_in_depth, target_remove=(len_front - len_back))
375
+
376
+ # Placement
377
+ # NOTE: The commented line places the top a bit higher, increasing the chanced of correct drape
378
+ # Surcumvented by attachment constraint, so removed for nicer alignment in asymmetric garments
379
+ # self.translate_by([0, out_depth - body['_armscye_depth'] * 0.75, 0]) # adjust for better localisation
380
+
381
+ # Add a label
382
+ self.ftorso.interfaces['shoulder'].edges.propagate_label('strapless_top')
383
+ self.btorso.interfaces['shoulder'].edges.propagate_label('strapless_top')
384
+
385
+
386
+ def _adjust_top_level(self, panel, out_level, in_level, target_remove=None):
387
+ """Crops the top of the bodice front/back panel for strapless style
388
+
389
+ * out_length_diff -- if set, determined the length difference that should be compensates
390
+ after cutting the depth
391
+ """
392
+ # TODOLOW Should this be the panel's function?
393
+
394
+ panel_top = panel.interfaces['shoulder'].edges[0]
395
+ min_y = min(panel_top.start[1], panel_top.end[1])
396
+
397
+ # Order vertices
398
+ ins, out = panel_top.start, panel_top.end
399
+ if panel_top.start[1] < panel_top.end[1]:
400
+ ins, out = out, ins
401
+
402
+ # Inside is a simple vertical line and can be adjusted by chaning Y value
403
+ ins[1] = min_y - in_level
404
+
405
+ # Outside could be inclined, so needs further calculations
406
+ outside_edge = panel.interfaces['outside'].edges[-1]
407
+ bot, top = outside_edge.start, outside_edge.end
408
+ if bot is out:
409
+ bot, top = top, bot
410
+
411
+ if target_remove is not None:
412
+ # Adjust the depth to remove this length exactly
413
+ angle_sin = abs(out[1] - bot[1]) / outside_edge.length()
414
+ curr_remove = out_level / angle_sin
415
+ length_diff = target_remove - curr_remove
416
+ adjustment = length_diff * angle_sin
417
+ out_level += adjustment
418
+
419
+ angle_cotan = abs(out[0] - bot[0]) / abs(out[1] - bot[1])
420
+ out[0] -= out_level * angle_cotan
421
+ out[1] = min_y - out_level
422
+
423
+
424
+ def length(self):
425
+ return self.btorso.length()
426
+
427
+ class Shirt(pyg.Component):
428
+ """Panel for the front of upper garments with darts to properly fit it to
429
+ the shape"""
430
+
431
+ def __init__(self, body, design, fitted=False) -> None:
432
+ name_with_params = f"{self.__class__.__name__}"
433
+ super().__init__(name_with_params)
434
+
435
+ design = self.eval_dep_params(design)
436
+
437
+ self.right = BodiceHalf(f'right', body, design, fitted=fitted)
438
+ self.left = BodiceHalf(
439
+ f'left', body,
440
+ design['left'] if design['left']['enable_asym']['v'] else design,
441
+ fitted=fitted).mirror()
442
+
443
+ self.stitching_rules.append((self.right.interfaces['front_in'],
444
+ self.left.interfaces['front_in']))
445
+ self.stitching_rules.append((self.right.interfaces['back_in'],
446
+ self.left.interfaces['back_in']))
447
+
448
+ # Adjust interface ordering for correct connectivity
449
+ self.interfaces = { # Bottom connection
450
+ 'bottom': pyg.Interface.from_multiple(
451
+ self.right.interfaces['f_bottom'].reverse(),
452
+ self.left.interfaces['f_bottom'],
453
+ self.left.interfaces['b_bottom'].reverse(),
454
+ self.right.interfaces['b_bottom'],)
455
+ }
456
+
457
+ def eval_dep_params(self, design):
458
+ # NOTE: Support for full collars with partially strapless top
459
+ # or combination of paneled collar styles
460
+ # requres further development
461
+ # TODOLOW enable this one to work
462
+ if design['left']['enable_asym']['v']:
463
+ # Force no collars since they are not compatible with each other
464
+ design = deepcopy(design)
465
+ design['collar']['component']['style']['v'] = None
466
+ design['left']['collar']['component'] = dict(style=dict(v=None))
467
+
468
+ # Left-right design compatibility
469
+ design['left']['shirt'].update(length={})
470
+ design['left']['shirt']['length']['v'] = design['shirt']['length']['v']
471
+
472
+ design['left']['collar'].update(fc_depth={}, bc_depth={})
473
+ design['left']['collar']['fc_depth']['v'] = design['collar']['fc_depth']['v']
474
+ design['left']['collar']['bc_depth']['v'] = design['collar']['bc_depth']['v']
475
+
476
+ return design
477
+
478
+ def length(self):
479
+ return self.right.length()
480
+
481
+ class FittedShirt(Shirt):
482
+ """Creates fitted shirt
483
+
484
+ NOTE: Separate class is used for selection convenience.
485
+ Even though most of the processing is the same
486
+ (hence implemented with the same components except for panels),
487
+ design parametrization differs significantly.
488
+ With that, we decided to separate the top level names
489
+ """
490
+ def __init__(self, body, design) -> None:
491
+ super().__init__(body, design, fitted=True)
GarmentCode/assets/garment_programs/circle_skirt.py ADDED
@@ -0,0 +1,234 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ import pygarment as pyg
3
+
4
+ from assets.garment_programs.base_classes import StackableSkirtComponent
5
+
6
+
7
+ class CircleArcPanel(pyg.Panel):
8
+ """One panel circle skirt"""
9
+
10
+ def __init__(self,
11
+ name,
12
+ top_rad, length, angle,
13
+ match_top_int_proportion=None,
14
+ match_bottom_int_proportion=None
15
+ ) -> None:
16
+ super().__init__(name)
17
+
18
+ halfarc = angle / 2
19
+
20
+ dist_w = 2 * top_rad * np.sin(halfarc)
21
+ dist_out = 2 * (top_rad + length) * np.sin(halfarc)
22
+
23
+ vert_len = length * np.cos(halfarc)
24
+
25
+ # top
26
+ self.edges.append(pyg.CircleEdgeFactory.from_points_radius(
27
+ [-dist_w/2, 0], [dist_w/2, 0],
28
+ radius=top_rad, large_arc=halfarc > np.pi / 2))
29
+
30
+ self.edges.append(pyg.Edge(
31
+ self.edges[-1].end, [dist_out / 2, -vert_len]))
32
+
33
+ # Bottom
34
+ self.edges.append(pyg.CircleEdgeFactory.from_points_radius(
35
+ self.edges[-1].end, [- dist_out / 2, -vert_len],
36
+ radius=top_rad + length,
37
+ large_arc=halfarc > np.pi / 2, right=False))
38
+
39
+ self.edges.close_loop()
40
+
41
+ # Interfaces
42
+ self.interfaces = {
43
+ 'top': pyg.Interface(self, self.edges[0],
44
+ ruffle=self.edges[0].length() / match_top_int_proportion if match_top_int_proportion is not None else 1.
45
+ ).reverse(True),
46
+ 'bottom': pyg.Interface(self, self.edges[2],
47
+ ruffle=self.edges[2].length() / match_bottom_int_proportion if match_bottom_int_proportion is not None else 1.
48
+ ),
49
+ 'left': pyg.Interface(self, self.edges[1]),
50
+ 'right': pyg.Interface(self, self.edges[3])
51
+ }
52
+
53
+ def length(self, *args):
54
+ return self.interfaces['right'].edges.length()
55
+
56
+ @staticmethod
57
+ def from_w_length_suns(name, length, top_width, sun_fraction, **kwargs):
58
+ arc = sun_fraction * 2 * np.pi
59
+ rad = top_width / arc
60
+
61
+ return CircleArcPanel(name, rad, length, arc, **kwargs)
62
+
63
+ @staticmethod
64
+ def from_all_length(name, length, top_width, bottom_width, **kwargs):
65
+
66
+ diff = bottom_width - top_width
67
+ arc = diff / length
68
+ rad = top_width / arc
69
+
70
+ return CircleArcPanel(name, rad, length, arc, **kwargs)
71
+
72
+ @staticmethod
73
+ def from_length_rad(name, length, top_width, rad, **kwargs):
74
+
75
+ arc = top_width / rad
76
+
77
+ return CircleArcPanel(name, rad, length, arc, **kwargs)
78
+
79
+ class AsymHalfCirclePanel(pyg.Panel):
80
+ """Panel for a asymmetrci circle skirt"""
81
+
82
+ def __init__(self,
83
+ name,
84
+ top_rad, length_f, length_s,
85
+ match_top_int_proportion=None,
86
+ match_bottom_int_proportion=None
87
+ ) -> None:
88
+ """ Half a shifted arc section
89
+ """
90
+ super().__init__(name)
91
+
92
+ dist_w = 2 * top_rad
93
+ dist_out = 2 * (top_rad + length_s)
94
+
95
+ # top
96
+ self.edges.append(pyg.CircleEdgeFactory.from_points_radius(
97
+ [-dist_w/2, 0], [dist_w/2, 0],
98
+ radius=top_rad, large_arc=False))
99
+
100
+ self.edges.append(pyg.Edge(
101
+ self.edges[-1].end, [dist_out / 2, 0]))
102
+
103
+ # Bottom
104
+ self.edges.append(
105
+ pyg.CircleEdgeFactory.from_three_points(
106
+ self.edges[-1].end, [- dist_out / 2, 0],
107
+ point_on_arc=[0, -(top_rad + length_f)]
108
+ )
109
+ )
110
+
111
+ self.edges.close_loop()
112
+
113
+ # Interfaces
114
+ self.interfaces = {
115
+ 'top': pyg.Interface(self, self.edges[0],
116
+ ruffle=self.edges[0].length() / match_top_int_proportion if match_top_int_proportion is not None else 1.
117
+ ).reverse(True),
118
+ 'bottom': pyg.Interface(self, self.edges[2],
119
+ ruffle=self.edges[2].length() / match_bottom_int_proportion if match_bottom_int_proportion is not None else 1.
120
+ ),
121
+ 'left': pyg.Interface(self, self.edges[1]),
122
+ 'right': pyg.Interface(self, self.edges[3])
123
+ }
124
+
125
+ def length(self, *args):
126
+ return self.interfaces['right'].edges.length()
127
+
128
+ class SkirtCircle(StackableSkirtComponent):
129
+ """Simple circle skirt"""
130
+ def __init__(self, body, design, tag='', length=None, rise=None, slit=True, asymm=False, min_len=5, **kwargs) -> None:
131
+ super().__init__(body, design, tag)
132
+
133
+ design = design['flare-skirt']
134
+ suns = design['suns']['v']
135
+ self.rise = design['rise']['v'] if rise is None else rise
136
+ waist, hips_depth, _ = self.eval_rise(self.rise)
137
+
138
+ if length is None: # take from design parameters
139
+ length = hips_depth + design['length']['v'] * body['_leg_length']
140
+
141
+ # NOTE: with some combinations of rise and length parameters length may become too small/negative
142
+ # Hence putting a min positive value here
143
+ length = max(length, min_len)
144
+
145
+ # panels
146
+ if not asymm: # Typical symmetric skirt
147
+ self.front = CircleArcPanel.from_w_length_suns(
148
+ f'skirt_front_{tag}' if tag else 'skirt_front',
149
+ length, waist / 2, suns / 2,
150
+ match_top_int_proportion=self.body['waist'] - self.body['waist_back_width'],
151
+ ).translate_by([0, body['_waist_level'], 15])
152
+
153
+ self.back = CircleArcPanel.from_w_length_suns(
154
+ f'skirt_back_{tag}' if tag else 'skirt_back',
155
+ length, waist / 2, suns / 2,
156
+ match_top_int_proportion=self.body['waist_back_width'],
157
+ ).translate_by([0, body['_waist_level'], -15])
158
+ else:
159
+ # NOTE: Asymmetic front/back is only defined on full skirt (1 sun)
160
+ w_rad = waist / 2 / np.pi
161
+ f_length = design['asymm']['front_length']['v'] * length
162
+ tot_len = w_rad * 2 + length + f_length
163
+ del_r = tot_len / 2 - f_length - w_rad
164
+ s_length = np.sqrt((tot_len / 2)**2 - del_r**2) - w_rad
165
+
166
+ self.front = AsymHalfCirclePanel(
167
+ f'skirt_front_{tag}' if tag else 'skirt_front',
168
+ w_rad, f_length, s_length,
169
+ match_top_int_proportion=self.body['waist'] - self.body['waist_back_width'],
170
+ ).translate_by([0, body['_waist_level'], 15])
171
+
172
+ self.back = AsymHalfCirclePanel(
173
+ f'skirt_back_{tag}' if tag else 'skirt_back',
174
+ w_rad, length, s_length,
175
+ match_top_int_proportion=self.body['waist_back_width'],
176
+ ).translate_by([0, body['_waist_level'], -15])
177
+
178
+ # Add a cut
179
+ if design['cut']['add']['v'] and slit:
180
+ self.add_cut(
181
+ self.front if design['cut']['place']['v'] > 0 else self.back,
182
+ design, length)
183
+
184
+ # Stitches
185
+ self.stitching_rules = pyg.Stitches(
186
+ (self.front.interfaces['right'], self.back.interfaces['right']),
187
+ (self.front.interfaces['left'], self.back.interfaces['left'])
188
+ )
189
+
190
+ # Interfaces
191
+ self.interfaces = {
192
+ 'top': pyg.Interface.from_multiple(self.front.interfaces['top'], self.back.interfaces['top']),
193
+ 'bottom_f': self.front.interfaces['bottom'],
194
+ 'bottom_b': self.back.interfaces['bottom'],
195
+ 'bottom': pyg.Interface.from_multiple(self.front.interfaces['bottom'], self.back.interfaces['bottom'])
196
+ }
197
+
198
+ def add_cut(self, panel, design, sk_length):
199
+ """Add a cut to the skirt"""
200
+ width, depth = design['cut']['width']['v'] * sk_length, design['cut']['depth']['v'] * sk_length
201
+
202
+ target_edge = panel.interfaces['bottom'].edges[0]
203
+ t_len = target_edge.length()
204
+ offset = abs(design['cut']['place']['v'] * t_len)
205
+
206
+ # Respect the placement boundaries
207
+ offset = max(offset, width / 2)
208
+ offset = min(offset, t_len - width / 2)
209
+
210
+ # NOTE: heuristic is specific for the panels that we use
211
+ right = target_edge.start[0] > target_edge.end[0]
212
+
213
+ # Make a cut
214
+ cut_shape = pyg.EdgeSeqFactory.dart_shape(width, depth=depth)
215
+
216
+ new_edges, _, interf_edges = pyg.ops.cut_into_edge(
217
+ cut_shape, target_edge,
218
+ offset=offset,
219
+ right=right
220
+ )
221
+
222
+ panel.edges.substitute(target_edge, new_edges)
223
+ panel.interfaces['bottom'].substitute(
224
+ target_edge, interf_edges,
225
+ [panel for _ in range(len(interf_edges))])
226
+
227
+ def length(self, *args):
228
+ return self.front.length()
229
+
230
+
231
+ class AsymmSkirtCircle(SkirtCircle):
232
+ """Front/back asymmetric skirt"""
233
+ def __init__(self, body, design, tag='', length=None, rise=None, slit=True, **kwargs):
234
+ super().__init__(body, design, tag, length, rise, slit, asymm=True)
GarmentCode/assets/garment_programs/collars.py ADDED
@@ -0,0 +1,370 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ from scipy.spatial.transform import Rotation as R
3
+
4
+ import pygarment as pyg
5
+
6
+ from assets.garment_programs.bands import StraightBandPanel
7
+ from assets.garment_programs.circle_skirt import CircleArcPanel
8
+
9
+
10
+ # # ------ Collar shapes withough extra panels ------
11
+
12
+ def VNeckHalf(depth, width, **kwargs):
13
+ """Simple VNeck design"""
14
+
15
+ edges = pyg.EdgeSequence(pyg.Edge([0, 0], [width / 2, -depth]))
16
+ return edges
17
+
18
+ def SquareNeckHalf(depth, width, **kwargs):
19
+ """Square design"""
20
+
21
+ edges = pyg.EdgeSeqFactory.from_verts([0, 0], [0, -depth], [width / 2, -depth])
22
+ return edges
23
+
24
+ def TrapezoidNeckHalf(depth, width, angle=90, verbose=True, **kwargs):
25
+ """Trapesoid neck design"""
26
+
27
+ # Special case when angle = 180 (sin = 0)
28
+ if (pyg.utils.close_enough(angle, 180, tol=1)
29
+ or pyg.utils.close_enough(angle, 0, tol=1)):
30
+ # degrades into VNeck
31
+ return VNeckHalf(depth, width)
32
+
33
+ rad_angle = np.deg2rad(angle)
34
+
35
+ bottom_x = -depth * np.cos(rad_angle) / np.sin(rad_angle)
36
+ if bottom_x > width / 2: # Invalid angle/depth/width combination resulted in invalid shape
37
+ if verbose:
38
+ print('TrapezoidNeckHalf::WARNING::Parameters are invalid and create overlap: '
39
+ f'{bottom_x} > {width / 2}. '
40
+ 'The collar is reverted to VNeck')
41
+
42
+ return VNeckHalf(depth, width)
43
+
44
+ edges = pyg.EdgeSeqFactory.from_verts([0, 0], [bottom_x, -depth], [width / 2, -depth])
45
+ return edges
46
+
47
+ def CurvyNeckHalf(depth, width, flip=False, **kwargs):
48
+ """Testing Curvy Collar design"""
49
+
50
+ sign = -1 if flip else 1
51
+ edges = pyg.EdgeSequence(pyg.CurveEdge(
52
+ [0, 0], [width / 2,-depth],
53
+ [[0.4, sign * 0.3], [0.8, sign * -0.3]]))
54
+
55
+ return edges
56
+
57
+ def CircleArcNeckHalf(depth, width, angle=90, flip=False, **kwargs):
58
+ """Collar with a side represented by a circle arc"""
59
+ # 1/4 of a circle
60
+ edges = pyg.EdgeSequence(pyg.CircleEdgeFactory.from_points_angle(
61
+ [0, 0], [width / 2,-depth], arc_angle=np.deg2rad(angle),
62
+ right=(not flip)
63
+ ))
64
+
65
+ return edges
66
+
67
+
68
+ def CircleNeckHalf(depth, width, **kwargs):
69
+ """Collar that forms a perfect circle arc when halfs are stitched"""
70
+
71
+ # Take a full desired arc and half it!
72
+ circle = pyg.CircleEdgeFactory.from_three_points(
73
+ [0, 0],
74
+ [width, 0],
75
+ [width / 2, -depth])
76
+ subdiv = circle.subdivide_len([0.5, 0.5])
77
+ return pyg.EdgeSequence(subdiv[0])
78
+
79
+ def Bezier2NeckHalf(depth, width, flip=False, x=0.5, y=0.3, **kwargs):
80
+ """2d degree Bezier curve as neckline"""
81
+
82
+ sign = 1 if flip else -1
83
+ edges = pyg.EdgeSequence(pyg.CurveEdge(
84
+ [0, 0], [width / 2,-depth],
85
+ [[x, sign*y]]))
86
+
87
+ return edges
88
+
89
+ # # ------ Collars with panels ------
90
+
91
+ class NoPanelsCollar(pyg.Component):
92
+ """Face collar class that only forms the projected shapes """
93
+
94
+ def __init__(self, name, body, design) -> None:
95
+ super().__init__(name)
96
+
97
+ # Front
98
+ collar_type = globals()[design['collar']['f_collar']['v']]
99
+ f_collar = collar_type(
100
+ design['collar']['fc_depth']['v'],
101
+ design['collar']['width']['v'],
102
+ angle=design['collar']['fc_angle']['v'],
103
+ flip=design['collar']['f_flip_curve']['v'],
104
+ x=design['collar']['f_bezier_x']['v'],
105
+ y=design['collar']['f_bezier_y']['v'],
106
+ verbose=self.verbose
107
+ )
108
+
109
+ # Back
110
+ collar_type = globals()[design['collar']['b_collar']['v']]
111
+ b_collar = collar_type(
112
+ design['collar']['bc_depth']['v'],
113
+ design['collar']['width']['v'],
114
+ angle=design['collar']['bc_angle']['v'],
115
+ flip=design['collar']['b_flip_curve']['v'],
116
+ x=design['collar']['b_bezier_x']['v'],
117
+ y=design['collar']['b_bezier_y']['v'],
118
+ verbose=self.verbose
119
+ )
120
+
121
+ self.interfaces = {
122
+ 'front_proj': pyg.Interface(self, f_collar),
123
+ 'back_proj': pyg.Interface(self, b_collar)
124
+ }
125
+
126
+ def length(self):
127
+ return 0
128
+
129
+
130
+ class Turtle(pyg.Component):
131
+
132
+ def __init__(self, tag, body, design) -> None:
133
+ super().__init__(f'Turtle_{tag}')
134
+
135
+ depth = design['collar']['component']['depth']['v']
136
+
137
+ # --Projecting shapes--
138
+ f_collar = CircleNeckHalf(
139
+ design['collar']['fc_depth']['v'],
140
+ design['collar']['width']['v'])
141
+ b_collar = CircleNeckHalf(
142
+ design['collar']['bc_depth']['v'],
143
+ design['collar']['width']['v'])
144
+
145
+ self.interfaces = {
146
+ 'front_proj': pyg.Interface(self, f_collar),
147
+ 'back_proj': pyg.Interface(self, b_collar)
148
+ }
149
+
150
+ # -- Panels --
151
+ length_f, length_b = f_collar.length(), b_collar.length()
152
+ height_p = body['height'] - body['head_l'] + depth
153
+
154
+ self.front = StraightBandPanel(
155
+ f'{tag}_collar_front', length_f, depth).translate_by(
156
+ [-length_f / 2, height_p, 10])
157
+ self.back = StraightBandPanel(
158
+ f'{tag}_collar_back', length_b, depth).translate_by(
159
+ [-length_b / 2, height_p, -10])
160
+
161
+ self.stitching_rules.append((
162
+ self.front.interfaces['right'],
163
+ self.back.interfaces['right']
164
+ ))
165
+
166
+ self.interfaces.update({
167
+ 'front': self.front.interfaces['left'],
168
+ 'back': self.back.interfaces['left'],
169
+ 'bottom': pyg.Interface.from_multiple(
170
+ self.front.interfaces['bottom'],
171
+ self.back.interfaces['bottom']
172
+ )
173
+ })
174
+
175
+ def length(self):
176
+ return self.interfaces['back'].edges.length()
177
+
178
+
179
+ class SimpleLapelPanel(pyg.Panel):
180
+ """A panel for the front part of simple Lapel"""
181
+ def __init__(self, name, length, max_depth) -> None:
182
+ super().__init__(name)
183
+
184
+ self.edges = pyg.EdgeSeqFactory.from_verts(
185
+ [0, 0], [max_depth, 0], [max_depth, -length]
186
+ )
187
+
188
+ self.edges.append(
189
+ pyg.CurveEdge(
190
+ self.edges[-1].end,
191
+ self.edges[0].start,
192
+ [[0.7, 0.2]]
193
+ )
194
+ )
195
+
196
+ self.interfaces = {
197
+ 'to_collar': pyg.Interface(self, self.edges[0]),
198
+ 'to_bodice': pyg.Interface(self, self.edges[1])
199
+ }
200
+
201
+
202
+ class SimpleLapel(pyg.Component):
203
+
204
+ def __init__(self, tag, body, design) -> None:
205
+ super().__init__(f'Turtle_{tag}')
206
+
207
+ depth = design['collar']['component']['depth']['v']
208
+ standing = design['collar']['component']['lapel_standing']['v']
209
+
210
+ # --Projecting shapes--
211
+ # Any front one!
212
+ collar_type = globals()[design['collar']['f_collar']['v']]
213
+ f_collar = collar_type(
214
+ design['collar']['fc_depth']['v'],
215
+ design['collar']['width']['v'],
216
+ angle=design['collar']['fc_angle']['v'],
217
+ flip=design['collar']['f_flip_curve']['v'])
218
+
219
+ b_collar = CircleNeckHalf(
220
+ design['collar']['bc_depth']['v'],
221
+ design['collar']['width']['v'])
222
+
223
+ self.interfaces = {
224
+ 'front_proj': pyg.Interface(self, f_collar),
225
+ 'back_proj': pyg.Interface(self, b_collar)
226
+ }
227
+
228
+ # -- Panels --
229
+ length_f, length_b = f_collar.length(), b_collar.length()
230
+ height_p = body['height'] - body['head_l'] + depth * 2
231
+
232
+ self.front = SimpleLapelPanel(
233
+ f'{tag}_collar_front', length_f, depth).translate_by(
234
+ [-depth * 2, height_p, 35]) # TODOLOW This should be related with the bodice panels' placement
235
+
236
+ if standing:
237
+ self.back = StraightBandPanel(
238
+ f'{tag}_collar_back', length_b, depth).translate_by(
239
+ [-length_b / 2, height_p, -10])
240
+ else:
241
+ # A curved back panel that follows the collar opening
242
+ rad, angle, _ = b_collar[0].as_radius_angle()
243
+ self.back = CircleArcPanel(
244
+ f'{tag}_collar_back', rad, depth, angle
245
+ ).translate_by([-length_b, height_p, -10])
246
+ self.back.rotate_by(R.from_euler('XYZ', [90, 45, 0], degrees=True))
247
+
248
+ if standing:
249
+ self.back.interfaces['right'].set_right_wrong(True)
250
+
251
+ self.stitching_rules.append((
252
+ self.front.interfaces['to_collar'],
253
+ self.back.interfaces['right']
254
+ ))
255
+
256
+ self.interfaces.update({
257
+ #'front': NOTE: no front interface here
258
+ 'back': self.back.interfaces['left'],
259
+ 'bottom': pyg.Interface.from_multiple(
260
+ self.front.interfaces['to_bodice'].set_right_wrong(True),
261
+ self.back.interfaces['bottom'] if standing else self.back.interfaces['top'].set_right_wrong(True),
262
+ )
263
+ })
264
+
265
+ def length(self):
266
+ return self.interfaces['back'].edges.length()
267
+
268
+ class HoodPanel(pyg.Panel):
269
+ """A panel for the side of the hood"""
270
+ def __init__(self, name, f_depth, b_depth, f_length, b_length, width, in_length, depth) -> None:
271
+ super().__init__(name)
272
+
273
+ width = width / 2 # Panel covers one half only
274
+ length = in_length + width / 2
275
+
276
+ # Bottom-back
277
+ bottom_back_in = pyg.CurveEdge(
278
+ [-width, -b_depth],
279
+ [0, 0],
280
+ [[0.3, -0.2], [0.6, 0.2]]
281
+ )
282
+ bottom_back = pyg.ops.curve_match_tangents(
283
+ bottom_back_in.as_curve(),
284
+ [1, 0], # Full opening is vertically aligned
285
+ [1, 0],
286
+ target_len=b_length,
287
+ return_as_edge=True,
288
+ verbose=self.verbose
289
+ )
290
+ self.edges.append(bottom_back)
291
+
292
+ # Bottom front
293
+ bottom_front_in = pyg.CurveEdge(
294
+ self.edges[-1].end,
295
+ [width, -f_depth],
296
+ [[0.3, 0.2], [0.6, -0.2]]
297
+ )
298
+ bottom_front = pyg.ops.curve_match_tangents(
299
+ bottom_front_in.as_curve(),
300
+ [1, 0], # Full opening is vertically aligned
301
+ [1, 0],
302
+ target_len=f_length,
303
+ return_as_edge=True,
304
+ verbose=self.verbose
305
+ )
306
+ self.edges.append(bottom_front)
307
+
308
+ # Front-top straight section
309
+ self.edges.append(pyg.EdgeSeqFactory.from_verts(
310
+ self.edges[-1].end,
311
+ [width * 1.2, length], [width * 1.2 - depth, length]
312
+ ))
313
+ # Back of the hood
314
+ self.edges.append(
315
+ pyg.CurveEdge(
316
+ self.edges[-1].end,
317
+ self.edges[0].start,
318
+ [[0.2, -0.5]]
319
+ )
320
+ )
321
+
322
+ self.interfaces = {
323
+ 'to_other_side': pyg.Interface(self, self.edges[-2:]),
324
+ 'to_bodice': pyg.Interface(self, self.edges[0:2]).reverse()
325
+ }
326
+
327
+ self.rotate_by(R.from_euler('XYZ', [0, -90, 0], degrees=True))
328
+ self.translate_by([-width, 0, 0])
329
+
330
+ class Hood2Panels(pyg.Component):
331
+
332
+ def __init__(self, tag, body, design) -> None:
333
+ super().__init__(f'Hood_{tag}')
334
+
335
+ # --Projecting shapes--
336
+ width = design['collar']['width']['v']
337
+ f_collar = CircleNeckHalf(
338
+ design['collar']['fc_depth']['v'],
339
+ design['collar']['width']['v'])
340
+ b_collar = CircleNeckHalf(
341
+ design['collar']['bc_depth']['v'],
342
+ design['collar']['width']['v'])
343
+
344
+ self.interfaces = {
345
+ 'front_proj': pyg.Interface(self, f_collar),
346
+ 'back_proj': pyg.Interface(self, b_collar)
347
+ }
348
+
349
+ # -- Panel --
350
+ self.panel = HoodPanel(
351
+ f'{tag}_hood',
352
+ design['collar']['fc_depth']['v'],
353
+ design['collar']['bc_depth']['v'],
354
+ f_length=f_collar.length(),
355
+ b_length=b_collar.length(),
356
+ width=width,
357
+ in_length=body['head_l'] * design['collar']['component']['hood_length']['v'],
358
+ depth=width / 2 * design['collar']['component']['hood_depth']['v']
359
+ ).translate_by(
360
+ [0, body['height'] - body['head_l'] + 10, 0])
361
+
362
+ self.interfaces.update({
363
+ #'front': NOTE: no front interface here
364
+ 'back': self.panel.interfaces['to_other_side'],
365
+ 'bottom': self.panel.interfaces['to_bodice']
366
+ })
367
+
368
+ def length(self):
369
+ return self.panel.length()
370
+
GarmentCode/assets/garment_programs/godet.py ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import math
2
+ import numpy as np
3
+
4
+ import pygarment as pyg
5
+
6
+ from assets.garment_programs.base_classes import BaseBottoms
7
+ from assets.garment_programs import skirt_paneled as skirts
8
+
9
+
10
+ class Insert(pyg.Panel):
11
+ def __init__(self, id, width=30, depth=30) -> None:
12
+ super().__init__(f'Insert_{id}')
13
+
14
+ self.edges = pyg.EdgeSeqFactory.from_verts(
15
+ [0, 0],
16
+ [width/2, depth],
17
+ [width, 0], loop=True)
18
+
19
+ self.interfaces = [
20
+ pyg.Interface(self, self.edges[:2])
21
+ ]
22
+ self.top_center_pivot()
23
+ self.center_x()
24
+
25
+
26
+ class GodetSkirt(BaseBottoms):
27
+
28
+ def __init__(self, body, design, rise=None) -> None:
29
+ super().__init__(body, design, rise=rise)
30
+
31
+ gdesign = design['godet-skirt']
32
+ ins_w = gdesign['insert_w']['v']
33
+ ins_depth = gdesign['insert_depth']['v']
34
+
35
+ base_skirt = getattr(skirts, gdesign['base']['v'])
36
+ # NOTE: godets currently don't like slits on the front/back
37
+ # of the base skirt => Forcing to remove any slits
38
+ self.base = base_skirt(body, design, rise=rise, slit=False)
39
+
40
+ bintr = self.base.interfaces['bottom']
41
+ for edge, panel in zip(bintr.edges, bintr.panel):
42
+ self.inserts(
43
+ edge, panel, ins_w, ins_depth,
44
+ num_inserts=gdesign['num_inserts']['v'] / len(bintr),
45
+ cuts_dist=gdesign['cuts_distance']['v'])
46
+
47
+ self.interfaces = {
48
+ 'top': self.base.interfaces['top']
49
+ }
50
+
51
+ def inserts(
52
+ self, bottom_edge, panel, ins_w, ins_depth,
53
+ num_inserts=3, cuts_dist=0):
54
+ """Create insert panels, add cuts to the skirt panel,
55
+ and connect created insert panels with them
56
+ """
57
+
58
+ num_inserts = int(num_inserts)
59
+ bottom_len = bottom_edge.length()
60
+
61
+ pbbox = panel.bbox3D()
62
+ z_transl = panel.translation[-1] + np.sign(panel.translation[-1]) * 5
63
+ y_base = pbbox[0][1] # min Y
64
+ x_shift = (pbbox[0][0] + pbbox[1][0]) / 2
65
+
66
+ cut_width = (bottom_len - cuts_dist * num_inserts) / num_inserts
67
+ if cut_width < 1:
68
+ cut_width = 1 # 1 cm
69
+ cuts_dist_req = cuts_dist
70
+ cuts_dist = (bottom_len - cut_width * num_inserts) / num_inserts
71
+ if self.verbose:
72
+ print(f'{self.__class__.__name__}::WARNING:: Cannot place {num_inserts} cuts '
73
+ f'with requested distance between cuts ({cuts_dist_req}). '
74
+ f'Using the maximum possible distance ({cuts_dist})')
75
+
76
+ # Insert panels
77
+ insert = Insert(0, width=ins_w, depth=ins_depth).translate_by([
78
+ x_shift - num_inserts * ins_w / 2 + ins_w / 2, y_base + ins_depth, z_transl])
79
+ self.subs += pyg.ops.distribute_horisontally(
80
+ insert, num_inserts, -ins_w, 'ins_' + panel.name)
81
+
82
+ # make appropriate cuts and stitches
83
+ side_len = math.sqrt((ins_w / 2)**2 + ins_depth**2) # should be the same on the skirt and the insert
84
+
85
+ if side_len > cut_width / 2: # Normal case
86
+ cut_depth = math.sqrt(side_len**2 - (cut_width / 2)**2)
87
+ else:
88
+ old_cut_width = cut_width
89
+ cut_depth = 1
90
+ cut_width = 2 * math.sqrt(side_len**2 - cut_depth**2)
91
+ if self.verbose:
92
+ print(f'{self.__class__.__name__}::WARNING::Requested cut_width ({old_cut_width:.2f}) '
93
+ 'is too wide for given inserts. '
94
+ f'Using the maximum possible width ({cut_width:.2f})')
95
+
96
+ cut_shape = pyg.EdgeSeqFactory.from_verts(
97
+ [0, 0], [cut_width / 2, cut_depth], [cut_width, 0])
98
+
99
+ right = z_transl < 0 # NOTE: heuristic corresponding to skirts in our collection
100
+
101
+ for i in range(num_inserts):
102
+ offset = cut_width / 2 + (cuts_dist / 2 if i == 0 else cuts_dist) # start_offest + i * stride
103
+
104
+ new_bottom, cutted, _ = pyg.ops.cut_into_edge(
105
+ cut_shape, bottom_edge, offset=offset, right=right)
106
+ panel.edges.substitute(bottom_edge, new_bottom)
107
+ bottom_edge = new_bottom[-1] # New edge that needs to be cutted -- on the next step
108
+
109
+ cut_interface = pyg.Interface(panel, cutted)
110
+ if right:
111
+ cut_interface.reverse()
112
+
113
+ self.stitching_rules.append(
114
+ (self.subs[-1-i if right else -(num_inserts-i)].interfaces[0],
115
+ cut_interface))
116
+
117
+ def get_rise(self):
118
+ return self.base.get_rise()
119
+
120
+ def length(self):
121
+ return self.base.length()
GarmentCode/assets/garment_programs/meta_garment.py ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from assets.garment_programs.tee import *
2
+ from assets.garment_programs.godet import *
3
+ from assets.garment_programs.bodice import *
4
+ from assets.garment_programs.pants import *
5
+ from assets.garment_programs.bands import *
6
+ from assets.garment_programs.skirt_paneled import *
7
+ from assets.garment_programs.skirt_levels import *
8
+ from assets.garment_programs.circle_skirt import *
9
+ from assets.garment_programs.sleeves import *
10
+
11
+ class TotalLengthError(BaseException):
12
+ """Error indicating that the total length of a garment goes beyond
13
+ the floor length for a given person"""
14
+ pass
15
+
16
+ class IncorrectElementConfiguration(BaseException):
17
+ """Error indicating that given pattern is an empty garment"""
18
+ pass
19
+
20
+ class MetaGarment(pyg.Component):
21
+ """Meta garment component
22
+ Depending on parameter values it can generate sewing patterns
23
+ for various dresses and jumpsuit styles and fit them to the body
24
+ measurements
25
+ """
26
+ def __init__(self, name, body, design) -> None:
27
+ super().__init__(name)
28
+ self.body = body
29
+ self.design = design
30
+
31
+ # Elements
32
+ self.upper_name = design['meta']['upper']['v']
33
+ self.lower_name = design['meta']['bottom']['v']
34
+ self.belt_name = design['meta']['wb']['v']
35
+
36
+ # Upper garment
37
+ if self.upper_name:
38
+ upper = globals()[self.upper_name]
39
+ self.subs = [upper(body, design)]
40
+
41
+ # Set a label
42
+ self.subs[-1].set_panel_label('body', overwrite=False)
43
+
44
+ # Define Lower garment
45
+ if self.lower_name:
46
+ Lower_class = globals()[self.lower_name]
47
+ # NOTE: full rise for fitted tops
48
+ Lower = Lower_class(body, design, rise=1. if self.upper_name and 'Fitted' in self.upper_name else None)
49
+ else:
50
+ Lower = None
51
+
52
+ # Belt (or not)
53
+ # TODO Adapt the rise of the lower garment to the width of the belt for correct matching
54
+ if self.belt_name:
55
+ Belt_class = globals()[self.belt_name]
56
+
57
+ # Adjust rise to match the Lower garment if needed
58
+ Belt = Belt_class(body, design, Lower.get_rise() if Lower else 1.)
59
+
60
+ self.subs.append(Belt)
61
+
62
+ # Place below the upper garment
63
+ if len(self.subs) > 1:
64
+ self.subs[-1].place_by_interface(
65
+ self.subs[-1].interfaces['top'],
66
+ self.subs[-2].interfaces['bottom'],
67
+ gap=5
68
+ )
69
+
70
+ self.stitching_rules.append(
71
+ (self.subs[-2].interfaces['bottom'],
72
+ self.subs[-1].interfaces['top']))
73
+
74
+ # Add waist label
75
+ self.subs[-1].interfaces['top'].edges.propagate_label('lower_interface')
76
+ # Set panel segmentation labels
77
+ self.subs[-1].set_panel_label('body', overwrite=False)
78
+
79
+ # Attach Lower garment if present
80
+ if self.lower_name:
81
+ self.subs.append(Lower)
82
+ # Place below the upper garment or self.wb
83
+ if len(self.subs) > 1:
84
+ self.subs[-1].place_by_interface(
85
+ self.subs[-1].interfaces['top'],
86
+ self.subs[-2].interfaces['bottom'],
87
+ gap=5
88
+ )
89
+ self.stitching_rules.append(
90
+ (self.subs[-2].interfaces['bottom'],
91
+ self.subs[-1].interfaces['top']))
92
+
93
+ # Add waist label
94
+ if not self.belt_name:
95
+ self.subs[-1].interfaces['top'].edges.propagate_label('lower_interface')
96
+ # Set panel segmentation labels
97
+ self.subs[-1].set_panel_label('leg', overwrite=False)
98
+
99
+
100
+ def assert_total_length(self, tol=1):
101
+ """Check the total length of components"""
102
+ # Check that the total length of the components are less that body height
103
+ length = self.length()
104
+ floor = self.body['height'] - self.body['head_l']
105
+ if length > floor + tol:
106
+ raise TotalLengthError(f'{self.__class__.__name__}::{self.name}::ERROR:'
107
+ f':Total length {length} exceeds the floor length {floor}')
108
+
109
+ # TODO these checks don't require initialization of the pattern!
110
+ def assert_non_empty(self, filter_belts=True):
111
+ """Check that the garment is non-empty
112
+ * filter_wb -- if set, then garments consisting only of waistbands are considered empty
113
+ """
114
+ if not self.upper_name and not self.lower_name:
115
+ if filter_belts or not self.belt_name:
116
+ raise IncorrectElementConfiguration()
117
+
118
+ def assert_skirt_waistband(self):
119
+ """Check if a generated heavy skirt is created with a waistband"""
120
+
121
+ if self.lower_name and self.lower_name in ['SkirtCircle', 'AsymmSkirtCircle', 'SkirtManyPanels']:
122
+ if not (self.belt_name or self.upper_name):
123
+ raise IncorrectElementConfiguration()
GarmentCode/assets/garment_programs/pants.py ADDED
@@ -0,0 +1,312 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from copy import deepcopy
2
+ import numpy as np
3
+
4
+ import pygarment as pyg
5
+ from assets.garment_programs.base_classes import BaseBottoms
6
+ from assets.garment_programs import bands
7
+
8
+
9
+ class PantPanel(pyg.Panel):
10
+ def __init__(
11
+ self, name, body, design,
12
+ length,
13
+ waist,
14
+ hips,
15
+ hips_depth,
16
+ crotch_width,
17
+ dart_position,
18
+ match_top_int_to=None,
19
+ hipline_ext=1,
20
+ double_dart=False) -> None:
21
+ """
22
+ Basic pant panel with option to be fitted (with darts)
23
+ """
24
+ super().__init__(name)
25
+
26
+ flare = body['leg_circ'] * (design['flare']['v'] - 1) / 4
27
+ hips_depth = hips_depth * hipline_ext
28
+
29
+ hip_side_incl = np.deg2rad(body['_hip_inclination'])
30
+ dart_depth = hips_depth * 0.8
31
+
32
+ # Crotch cotrols
33
+ crotch_depth_diff = body['crotch_hip_diff']
34
+ crotch_extention = crotch_width
35
+
36
+ # eval pants shape
37
+ # TODO Return ruffle opportunity?
38
+
39
+ # amount of extra fabric at waist
40
+ w_diff = hips - waist # Assume its positive since waist is smaller then hips
41
+ # We distribute w_diff among the side angle and a dart
42
+ hw_shift = np.tan(hip_side_incl) * hips_depth
43
+ # Small difference
44
+ if hw_shift > w_diff:
45
+ hw_shift = w_diff
46
+
47
+ # --- Edges definition ---
48
+ # Right
49
+ if pyg.utils.close_enough(design['flare']['v'], 1): # skip optimization
50
+ right_bottom = pyg.Edge(
51
+ [-flare, 0],
52
+ [0, length]
53
+ )
54
+ else:
55
+ right_bottom = pyg.CurveEdgeFactory.curve_from_tangents(
56
+ [-flare, 0],
57
+ [0, length],
58
+ target_tan1=np.array([0, 1]),
59
+ # initial guess places control point closer to the hips
60
+ initial_guess=[0.75, 0]
61
+ )
62
+ right_top = pyg.CurveEdgeFactory.curve_from_tangents(
63
+ right_bottom.end,
64
+ [hw_shift, length + hips_depth],
65
+ target_tan0=np.array([0, 1]),
66
+ initial_guess=[0.5, 0]
67
+ )
68
+
69
+ top = pyg.Edge(
70
+ right_top.end,
71
+ [w_diff + waist, length + hips_depth]
72
+ )
73
+
74
+ crotch_top = pyg.Edge(
75
+ top.end,
76
+ [hips, length + 0.45 * hips_depth] # A bit higher than hip line
77
+ # NOTE: The point should be lower than the minimum rise value (0.5)
78
+ )
79
+ crotch_bottom = pyg.CurveEdgeFactory.curve_from_tangents(
80
+ crotch_top.end,
81
+ [hips + crotch_extention, length - crotch_depth_diff],
82
+ target_tan0=np.array([0, -1]),
83
+ target_tan1=np.array([1, 0]),
84
+ initial_guess=[0.5, -0.5]
85
+ )
86
+
87
+ left = pyg.CurveEdgeFactory.curve_from_tangents(
88
+ crotch_bottom.end,
89
+ [
90
+ # NOTE "Magic value" (-2 cm) which we use to define default width:
91
+ # just a little behing the crotch point
92
+ # NOTE: Ensuring same distance from the crotch point in both
93
+ # front and back for matching curves
94
+ crotch_bottom.end[0] - 2 + flare,
95
+ # NOTE: The inside edge either matches the length of the outside (0, normal case)
96
+ # or when the inteded length is smaller than crotch depth,
97
+ # inside edge covers of the inside leg a bit below the crotch (panties-like shorts)
98
+ y:=min(0, length - crotch_depth_diff * 1.5)
99
+ ],
100
+ target_tan1=[flare, y - crotch_bottom.end[1]],
101
+ initial_guess=[0.3, 0]
102
+ )
103
+
104
+ self.edges = pyg.EdgeSequence(
105
+ right_bottom, right_top, top, crotch_top, crotch_bottom, left
106
+ ).close_loop()
107
+ bottom = self.edges[-1]
108
+
109
+ # Default placement
110
+ self.set_pivot(crotch_bottom.end)
111
+ self.translation = [-0.5, - hips_depth - crotch_depth_diff + 5, 0]
112
+
113
+ # Out interfaces (easier to define before adding a dart)
114
+ self.interfaces = {
115
+ 'outside': pyg.Interface(
116
+ self,
117
+ pyg.EdgeSequence(right_bottom, right_top),
118
+ ruffle=[1, hipline_ext]),
119
+ 'crotch': pyg.Interface(self, pyg.EdgeSequence(crotch_top, crotch_bottom)),
120
+ 'inside': pyg.Interface(self, left),
121
+ 'bottom': pyg.Interface(self, bottom)
122
+ }
123
+
124
+ # Add top dart
125
+ # NOTE: Ruffle indicator to match to waistline proportion for correct balance line matching
126
+ dart_width = w_diff - hw_shift
127
+ if w_diff > hw_shift:
128
+ top_edges, int_edges = self.add_darts(
129
+ top, dart_width, dart_depth, dart_position, double_dart=double_dart)
130
+ self.interfaces['top'] = pyg.Interface(
131
+ self, int_edges,
132
+ ruffle=waist / match_top_int_to if match_top_int_to is not None else 1.
133
+ )
134
+ self.edges.substitute(top, top_edges)
135
+ else:
136
+ self.interfaces['top'] = pyg.Interface(
137
+ self, top,
138
+ ruffle=waist / match_top_int_to if match_top_int_to is not None else 1.
139
+ )
140
+
141
+
142
+
143
+ def add_darts(self, top, dart_width, dart_depth, dart_position, double_dart=False):
144
+
145
+ if double_dart:
146
+ # TODOLOW Avoid hardcoding for matching with the top?
147
+ dist = dart_position * 0.5 # Dist between darts -> dist between centers
148
+ offsets_mid = [
149
+ - (dart_position + dist / 2 + dart_width / 2 + dart_width / 4),
150
+ - (dart_position - dist / 2) - dart_width / 4,
151
+ ]
152
+
153
+ darts = [
154
+ pyg.EdgeSeqFactory.dart_shape(dart_width / 2, dart_depth * 0.9), # smaller
155
+ pyg.EdgeSeqFactory.dart_shape(dart_width / 2, dart_depth)
156
+ ]
157
+ else:
158
+ offsets_mid = [
159
+ - dart_position - dart_width / 2,
160
+ ]
161
+ darts = [
162
+ pyg.EdgeSeqFactory.dart_shape(dart_width, dart_depth)
163
+ ]
164
+ top_edges, int_edges = pyg.EdgeSequence(top), pyg.EdgeSequence(top)
165
+
166
+ for off, dart in zip(offsets_mid, darts):
167
+ left_edge_len = top_edges[-1].length()
168
+ top_edges, int_edges = self.add_dart(
169
+ dart,
170
+ top_edges[-1],
171
+ offset=left_edge_len + off,
172
+ edge_seq=top_edges,
173
+ int_edge_seq=int_edges
174
+ )
175
+
176
+ return top_edges, int_edges
177
+
178
+
179
+ class PantsHalf(BaseBottoms):
180
+ def __init__(self, tag, body, design, rise=None) -> None:
181
+ super().__init__(body, design, tag, rise=rise)
182
+ design = design['pants']
183
+ self.rise = design['rise']['v'] if rise is None else rise
184
+ waist, hips_depth, waist_back = self.eval_rise(self.rise)
185
+
186
+ # NOTE: min value = full sum > leg curcumference
187
+ # Max: pant leg falls flat from the back
188
+ # Mostly from the back side
189
+ # => This controls the foundation width of the pant
190
+ min_ext = body['leg_circ'] - body['hips'] / 2 + 5 # 2 inch ease: from pattern making book
191
+ front_hip = (body['hips'] - body['hip_back_width']) / 2
192
+ crotch_extention = min_ext * design['width']['v']
193
+ front_extention = front_hip / 4 # From pattern making book
194
+ back_extention = crotch_extention - front_extention
195
+
196
+ length, cuff_len = design['length']['v'], design['cuff']['cuff_len']['v']
197
+ if design['cuff']['type']['v']:
198
+ if length - cuff_len < design['length']['range'][0]: # Min length from paramss
199
+ # Cannot be longer then a pant
200
+ cuff_len = length - design['length']['range'][0]
201
+ # Include the cuff into the overall length,
202
+ # unless the requested length is too short to fit the cuff
203
+ # (to avoid negative length)
204
+ length -= cuff_len
205
+ length *= body['_leg_length']
206
+ cuff_len *= body['_leg_length']
207
+
208
+ self.front = PantPanel(
209
+ f'pant_f_{tag}', body, design,
210
+ length=length,
211
+ waist=(waist - waist_back) / 2,
212
+ hips=(body['hips'] - body['hip_back_width']) / 2,
213
+ hips_depth=hips_depth,
214
+ dart_position = body['bust_points'] / 2,
215
+ crotch_width=front_extention,
216
+ match_top_int_to=(body['waist'] - body['waist_back_width']) / 2
217
+ ).translate_by([0, body['_waist_level'] - 5, 25])
218
+ self.back = PantPanel(
219
+ f'pant_b_{tag}', body, design,
220
+ length=length,
221
+ waist=waist_back / 2,
222
+ hips=body['hip_back_width'] / 2,
223
+ hips_depth=hips_depth,
224
+ hipline_ext=1.1,
225
+ dart_position = body['bum_points'] / 2,
226
+ crotch_width=back_extention,
227
+ match_top_int_to=body['waist_back_width'] / 2,
228
+ double_dart=True
229
+ ).translate_by([0, body['_waist_level'] - 5, -20])
230
+
231
+ self.stitching_rules = pyg.Stitches(
232
+ (self.front.interfaces['outside'], self.back.interfaces['outside']),
233
+ (self.front.interfaces['inside'], self.back.interfaces['inside'])
234
+ )
235
+
236
+ # add a cuff
237
+ # TODOLOW This process is the same for sleeves -- make a function?
238
+ if design['cuff']['type']['v']:
239
+
240
+ pant_bottom = pyg.Interface.from_multiple(
241
+ self.front.interfaces['bottom'],
242
+ self.back.interfaces['bottom'])
243
+
244
+ # Copy to avoid editing original design dict
245
+ cdesign = deepcopy(design)
246
+ cdesign['cuff']['b_width'] = {}
247
+ cdesign['cuff']['b_width']['v'] = pant_bottom.edges.length() / design['cuff']['top_ruffle']['v']
248
+ cdesign['cuff']['cuff_len']['v'] = cuff_len
249
+
250
+ # Init
251
+ cuff_class = getattr(bands, cdesign['cuff']['type']['v'])
252
+ self.cuff = cuff_class(f'pant_{tag}', cdesign)
253
+
254
+ # Position
255
+ self.cuff.place_by_interface(
256
+ self.cuff.interfaces['top'],
257
+ pant_bottom,
258
+ gap=5,
259
+ alignment='left'
260
+ )
261
+
262
+ # Stitch
263
+ self.stitching_rules.append((
264
+ pant_bottom,
265
+ self.cuff.interfaces['top'])
266
+ )
267
+
268
+ self.interfaces = {
269
+ 'crotch_f': self.front.interfaces['crotch'],
270
+ 'crotch_b': self.back.interfaces['crotch'],
271
+ 'top_f': self.front.interfaces['top'],
272
+ 'top_b': self.back.interfaces['top']
273
+ }
274
+
275
+ def length(self):
276
+ if self.design['pants']['cuff']['type']['v']:
277
+ return self.front.length() + self.cuff.length()
278
+
279
+ return self.front.length()
280
+
281
+ class Pants(BaseBottoms):
282
+ def __init__(self, body, design, rise=None) -> None:
283
+ super().__init__(body, design)
284
+
285
+ self.right = PantsHalf('r', body, design, rise)
286
+ self.left = PantsHalf('l', body, design, rise).mirror()
287
+
288
+ self.stitching_rules = pyg.Stitches(
289
+ (self.right.interfaces['crotch_f'], self.left.interfaces['crotch_f']),
290
+ (self.right.interfaces['crotch_b'], self.left.interfaces['crotch_b']),
291
+ )
292
+
293
+ self.interfaces = {
294
+ 'top_f': pyg.Interface.from_multiple(
295
+ self.right.interfaces['top_f'], self.left.interfaces['top_f']),
296
+ 'top_b': pyg.Interface.from_multiple(
297
+ self.right.interfaces['top_b'], self.left.interfaces['top_b']),
298
+ # Some are reversed for correct connection
299
+ 'top': pyg.Interface.from_multiple( # around the body starting from front right
300
+ self.right.interfaces['top_f'].flip_edges(),
301
+ self.left.interfaces['top_f'].reverse(with_edge_dir_reverse=True),
302
+ self.left.interfaces['top_b'].flip_edges(),
303
+ self.right.interfaces['top_b'].reverse(with_edge_dir_reverse=True), # Flips the edges and restores the direction
304
+ )
305
+ }
306
+
307
+ def get_rise(self):
308
+ return self.right.get_rise()
309
+
310
+ def length(self):
311
+ return self.right.length()
312
+
GarmentCode/assets/garment_programs/shapes.py ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """A decorative shapes"""
2
+ import pygarment as pyg
3
+
4
+
5
+ def sample_arc(curve, length, stride, n_points, shift=0):
6
+ ts = [(shift + i*stride) / length for i in range(n_points)]
7
+ verts = [curve.point(t) for t in ts]
8
+
9
+ for i in range(len(verts)):
10
+ verts[i] = [verts[i].real, verts[i].imag]
11
+
12
+ return verts
13
+
14
+
15
+ def Sun(width, depth, n_rays=8, d_rays=5, **kwargs):
16
+ """Sun-like mark"""
17
+
18
+ # Outer arc
19
+ out_arc = pyg.CircleEdgeFactory.from_three_points(
20
+ [0, 0], [width, 0], [width/2, depth]
21
+ )
22
+ in_arc = pyg.CircleEdgeFactory.from_three_points(
23
+ [d_rays, 0], [width - d_rays, 0], [width/2, depth - d_rays]
24
+ )
25
+ out_curve = out_arc.as_curve()
26
+ in_curve = in_arc.as_curve()
27
+
28
+ # Sample with stride
29
+ out_stride = out_arc.length() / n_rays
30
+ in_stride = in_arc.length() / n_rays
31
+
32
+ out_verts = sample_arc(out_curve, out_arc.length(),
33
+ out_stride, n_rays, out_stride / 2)
34
+ in_verts = sample_arc(in_curve, in_arc.length(), in_stride, n_rays + 1, 0)
35
+
36
+ # Mix the vertices in the right order
37
+ verts = out_verts
38
+ for i in range(len(in_verts)):
39
+ verts.insert(i*2, in_verts[i])
40
+
41
+ shape = pyg.EdgeSeqFactory.from_verts(*verts)
42
+ return shape, shape
43
+
44
+
45
+ def SIGGRAPH_logo(width, depth=None, **kwargs):
46
+ """Shape of SIGGRAPH Logo (split vertically)"""
47
+
48
+ filename='./assets/img/siggraph_logo_thick_connection.svg' # NOTE assumes the script is run from the root
49
+ # TODOLOW path w.r.t. current file
50
+ left_seq, right_seq = pyg.EdgeSeqFactory.halfs_from_svg(
51
+ filename, target_height=width)
52
+
53
+ return left_seq, right_seq
54
+
55
+
56
+ def SVGFile(width, filename, depth=None, **kwargs):
57
+ """Shape loaded from any svg file:
58
+ The shape is expected to consist of non-nested loops
59
+ each passing through OY once
60
+ """
61
+
62
+ left_seq, right_seq = pyg.EdgeSeqFactory.halfs_from_svg(
63
+ filename, target_height=width)
64
+ return left_seq, right_seq
GarmentCode/assets/garment_programs/skirt_levels.py ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from assets.garment_programs.circle_skirt import *
2
+ from assets.garment_programs.skirt_paneled import *
3
+ from copy import deepcopy
4
+
5
+
6
+ class SkirtLevels(BaseBottoms):
7
+ """Skirt constiting of multuple stitched skirts"""
8
+
9
+ def __init__(self, body, design, rise=None) -> None:
10
+ super().__init__(body, design, rise=rise)
11
+
12
+ ldesign = design['levels-skirt']
13
+ lbody = deepcopy(body) # We will modify the values, so need a copy
14
+ n_levels = ldesign['num_levels']['v']
15
+ ruffle = ldesign['level_ruffle']['v']
16
+
17
+ # Adjust length to the common denominators
18
+ self.eval_length(ldesign, body)
19
+
20
+ # Definitions
21
+ self.rise = ldesign['rise']['v'] if rise is None else rise
22
+ base_skirt_class = globals()[ldesign['base']['v']]
23
+ self.subs.append(base_skirt_class(
24
+ body,
25
+ design,
26
+ length=self.base_len,
27
+ rise=self.rise,
28
+ slit=False))
29
+
30
+ if (hasattr(base := self.subs[0], 'design')
31
+ and 'low_angle' in base.design):
32
+ self.angle = base.design['low_angle']['v']
33
+ else:
34
+ self.angle = 0
35
+
36
+ # Place the levels
37
+ level_skirt_class = globals()[ldesign['level']['v']]
38
+ for i in range(n_levels):
39
+ # Adjust the mesurement to trick skirts into producing correct width
40
+ # TODOLOW More elegant overwrite
41
+ lbody['waist'] = ruffle * self.subs[-1].interfaces['bottom'].edges.length()
42
+ lbody['waist_back_width'] = ruffle * self.subs[-1].interfaces['bottom_b'].edges.length()
43
+ self.subs.append(level_skirt_class(
44
+ lbody,
45
+ design,
46
+ tag=str(i),
47
+ length=self.level_len,
48
+ slit=False,
49
+ top_ruffles=False))
50
+
51
+ # Placement
52
+ # Rotation if base is assymetric
53
+ self.subs[-1].rotate_by(R.from_euler(
54
+ 'XYZ', [0, 0, -self.angle], degrees=True))
55
+
56
+ self.subs[-1].place_by_interface(
57
+ self.subs[-1].interfaces['top'],
58
+ self.subs[-2].interfaces['bottom'],
59
+ gap=5
60
+ )
61
+ # Stitch
62
+ self.stitching_rules.append((
63
+ self.subs[-2].interfaces['bottom'],
64
+ self.subs[-1].interfaces['top']
65
+ ))
66
+
67
+ self.interfaces = {
68
+ 'top': self.subs[0].interfaces['top']
69
+ }
70
+
71
+ def eval_length(self, ldesign, body):
72
+
73
+ # With convertion to absolute values
74
+ total_length = ldesign['length']['v'] * body['_leg_length']
75
+ self.base_len = total_length * ldesign['base_length_frac']['v']
76
+ self.level_len = (total_length - self.base_len) / ldesign['num_levels']['v']
77
+
78
+ # Add hip_line (== zero length)
79
+ self.base_len = body['hips_line'] * ldesign['rise']['v'] + self.base_len
80
+
GarmentCode/assets/garment_programs/skirt_paneled.py ADDED
@@ -0,0 +1,512 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import numpy as np
2
+ from scipy.spatial.transform import Rotation as R
3
+
4
+ import pygarment as pyg
5
+ from assets.garment_programs.base_classes import StackableSkirtComponent
6
+ from assets.garment_programs.base_classes import BaseBottoms
7
+ from assets.garment_programs import shapes
8
+
9
+
10
+ class SkirtPanel(pyg.Panel):
11
+ """One panel of a panel skirt with ruffles on the waist"""
12
+
13
+ def __init__(self,
14
+ name,
15
+ waist_length=70, length=70,
16
+ ruffles=1,
17
+ match_top_int_to=None,
18
+ bottom_cut=0,
19
+ flare=0
20
+ ) -> None:
21
+ super().__init__(name)
22
+
23
+ base_width = waist_length
24
+ top_width = base_width * ruffles
25
+ low_width = top_width + 2*flare
26
+ x_shift_top = (low_width - top_width) / 2 # to account for flare at the bottom
27
+
28
+ # define edge loop
29
+ self.right = pyg.EdgeSeqFactory.side_with_cut(
30
+ [0, 0],
31
+ [x_shift_top, length],
32
+ start_cut=bottom_cut / length) if bottom_cut else pyg.EdgeSequence(
33
+ pyg.Edge([0, 0], [x_shift_top, length]))
34
+ self.waist = pyg.Edge(
35
+ self.right[-1].end, [x_shift_top + top_width, length])
36
+ self.left = pyg.EdgeSeqFactory.side_with_cut(
37
+ self.waist.end, [low_width, 0],
38
+ end_cut=bottom_cut / length) if bottom_cut else pyg.EdgeSequence(
39
+ pyg.Edge(self.waist.end, [low_width, 0]))
40
+ self.bottom = pyg.Edge(self.left[-1].end, self.right[0].start)
41
+
42
+ # define interface
43
+ self.interfaces = {
44
+ 'right': pyg.Interface(self, self.right[-1]),
45
+ 'top': pyg.Interface(self, self.waist,
46
+ ruffle=self.waist.length() / match_top_int_to if match_top_int_to is not None else ruffles
47
+ ).reverse(True),
48
+ 'left': pyg.Interface(self, self.left[0]),
49
+ 'bottom': pyg.Interface(self, self.bottom)
50
+ }
51
+ # Single sequence for correct assembly
52
+ self.edges = self.right
53
+ self.edges.append(self.waist) # on the waist
54
+ self.edges.append(self.left)
55
+ self.edges.append(self.bottom)
56
+
57
+ # default placement
58
+ self.top_center_pivot()
59
+ self.center_x() # Already know that this panel should be centered over Y
60
+
61
+
62
+ class ThinSkirtPanel(pyg.Panel):
63
+ """One panel of a panel skirt"""
64
+
65
+ def __init__(self, name, top_width=10, bottom_width=20, length=70, b_curvature=0) -> None:
66
+ super().__init__(name)
67
+
68
+ # define edge loop
69
+ self.flare = (bottom_width - top_width) / 2
70
+ self.edges = pyg.EdgeSeqFactory.from_verts(
71
+ [0, 0], [self.flare, length], [self.flare + top_width, length],
72
+ [self.flare * 2 + top_width, 0])
73
+
74
+ if pyg.utils.close_enough(b_curvature, 0):
75
+ self.edges.close_loop()
76
+ else:
77
+ self.edges.append(
78
+ pyg.CircleEdgeFactory.from_three_points(
79
+ self.edges[-1].end,
80
+ self.edges[0].start,
81
+ [0.5, b_curvature],
82
+ relative=True
83
+ )
84
+ )
85
+
86
+ # w.r.t. top left point
87
+ self.set_pivot(self.edges[0].end)
88
+
89
+ self.interfaces = {
90
+ 'right': pyg.Interface(self, self.edges[0]),
91
+ 'top': pyg.Interface(self, self.edges[1]),
92
+ 'left': pyg.Interface(self, self.edges[2]),
93
+ 'bottom': pyg.Interface(self, self.edges[-1])
94
+ }
95
+
96
+
97
+ class FittedSkirtPanel(pyg.Panel):
98
+ """Fitted panel for a pencil skirt"""
99
+ def __init__(
100
+ self, name, body, design,
101
+ waist, hips, hips_depth, # TODOLOW Half measurement instead of a quarter
102
+ length,
103
+ hipline_ext=1,
104
+ dart_position=None, dart_frac=0.5, double_dart=False,
105
+ match_top_int_to=None,
106
+ slit=0, left_slit=0, right_slit=0,
107
+ side_cut=None, flip_side_cut=False
108
+ ) -> None:
109
+ """ Fitted panel for a pencil skirt
110
+
111
+ Body/design values that differ between front and back panels are supplied as parameters,
112
+ the rest are taken from the body and design dictionaries
113
+ """
114
+ super().__init__(name)
115
+
116
+ # Shared params
117
+ low_angle = design['low_angle']['v']
118
+ hip_side_incl = np.deg2rad(body['_hip_inclination'])
119
+ flare = design['flare']['v']
120
+ low_width = body['hips'] * (flare - 1) / 4 + hips # Distribute the difference equally
121
+ # between front and back
122
+ # adjust for a rise
123
+ adj_hips_depth = hips_depth * hipline_ext
124
+ dart_depth = hips_depth * dart_frac
125
+ dart_depth = max(dart_depth - (hips_depth - adj_hips_depth), 0)
126
+
127
+ # amount of extra fabric
128
+ w_diff = hips - waist # Assume its positive since waist is smaller then hips
129
+ # We distribute w_diff among the side angle and a dart
130
+ hw_shift = np.tan(hip_side_incl) * adj_hips_depth
131
+ # Small difference
132
+ if hw_shift > w_diff:
133
+ hw_shift = w_diff
134
+
135
+ # Adjust the bottom edge to the desired angle
136
+ angle_shift = np.tan(np.deg2rad(low_angle)) * low_width
137
+
138
+ # --- Edges definition ---
139
+ # Right
140
+ if pyg.utils.close_enough(flare, 1): # skip optimization
141
+ right_bottom = pyg.Edge(
142
+ [hips - low_width, angle_shift],
143
+ [0, length]
144
+ )
145
+ else:
146
+ right_bottom = pyg.CurveEdgeFactory.curve_from_tangents(
147
+ [hips - low_width, angle_shift],
148
+ [0, length],
149
+ target_tan1=np.array([0, 1]),
150
+ # initial guess places control point closer to the hips
151
+ initial_guess=[0.75, 0]
152
+ )
153
+ right_top = pyg.CurveEdgeFactory.curve_from_tangents(
154
+ right_bottom.end,
155
+ [hw_shift, length + adj_hips_depth],
156
+ target_tan0=np.array([0, 1]),
157
+ initial_guess=[0.5, 0]
158
+ )
159
+ right = pyg.EdgeSequence(right_bottom, right_top)
160
+
161
+ # top
162
+ top = pyg.Edge(right[-1].end, [hips * 2 - hw_shift, length + adj_hips_depth])
163
+
164
+ # left
165
+ left_top = pyg.CurveEdgeFactory.curve_from_tangents(
166
+ top.end,
167
+ [hips * 2, length],
168
+ target_tan1=np.array([0, -1]),
169
+ initial_guess=[0.5, 0]
170
+ )
171
+ if pyg.utils.close_enough(flare, 1): # skip optimization for straight skirt
172
+ left_bottom = pyg.Edge(
173
+ left_top.end,
174
+ [hips + low_width, -angle_shift],
175
+ )
176
+ else:
177
+ left_bottom = pyg.CurveEdgeFactory.curve_from_tangents(
178
+ left_top.end,
179
+ [hips + low_width, -angle_shift],
180
+ target_tan0=np.array([0, -1]),
181
+ # initial guess places control point closer to the hips
182
+ initial_guess=[0.25, 0]
183
+ )
184
+ left = pyg.EdgeSequence(left_top, left_bottom)
185
+
186
+ # fin
187
+ self.edges = pyg.EdgeSequence(right, top, left).close_loop()
188
+ bottom = self.edges[-1]
189
+
190
+ if slit: # add a slit
191
+ # Use long and thin disconnected dart for a cutout
192
+ new_edges, _, int_edges = pyg.ops.cut_into_edge(
193
+ pyg.EdgeSeqFactory.dart_shape(2, depth=slit * length), # a very thin cutout
194
+ bottom,
195
+ offset=bottom.length() / 2,
196
+ right=True)
197
+
198
+ self.edges.substitute(bottom, new_edges)
199
+ bottom = int_edges
200
+
201
+ if left_slit:
202
+ frac = left_slit
203
+ new_left_bottom = left_bottom.subdivide_len([1 - frac, frac])
204
+ left.substitute(left_bottom, new_left_bottom[0])
205
+ self.edges.substitute(left_bottom, new_left_bottom)
206
+ left_bottom = new_left_bottom[0]
207
+
208
+ if right_slit:
209
+ frac = right_slit
210
+ new_rbottom = right_bottom.subdivide_len([frac, 1 - frac])
211
+ right.substitute(right_bottom, new_rbottom[1])
212
+ self.edges.substitute(right_bottom, new_rbottom)
213
+ right_bottom = new_rbottom[1]
214
+
215
+ if side_cut is not None:
216
+ try:
217
+ # Add a stylistic cutout to the skirt
218
+ new_edges, _, int_edges = pyg.ops.cut_into_edge(
219
+ side_cut, left_bottom,
220
+ offset=left_bottom.length() / 2,
221
+ right=True, flip_target=flip_side_cut)
222
+ except:
223
+ # Skip adding the cut if it doesn't fit (e.g. because of the slit)
224
+ pass
225
+ else:
226
+ self.edges.substitute(left_bottom, new_edges)
227
+ left.substitute(left_bottom, new_edges)
228
+
229
+ # Default placement
230
+ self.top_center_pivot()
231
+ self.translation = [-hips / 2, 5, 0]
232
+
233
+ # Out interfaces (easier to define before adding a dart)
234
+ # Adding ruffle factor on the hip line extention (used in back panel)
235
+ self.interfaces = {
236
+ 'bottom': pyg.Interface(self, bottom),
237
+ 'right': pyg.Interface(self, right, [1] * (len(right) - 1) + [hipline_ext]),
238
+ 'left': pyg.Interface(self, left, [hipline_ext] + [1] * (len(left) - 1)),
239
+ }
240
+ self.interfaces['left'].edges_flipping[0] = True
241
+ self.interfaces['right'].edges_flipping[-1] = True
242
+
243
+ # Add top darts
244
+ if w_diff > hw_shift:
245
+ dart_width = w_diff - hw_shift
246
+ top_edges, int_edges = self.add_darts(top, dart_width, dart_depth, dart_position, double_dart=double_dart)
247
+
248
+ self.interfaces['top'] = pyg.Interface(
249
+ self, int_edges,
250
+ ruffle=int_edges.length() / match_top_int_to if match_top_int_to is not None else 1.
251
+ )
252
+ self.edges.substitute(top, top_edges)
253
+ else:
254
+ self.interfaces['top'] = pyg.Interface(
255
+ self, top,
256
+ ruffle=top.length() / match_top_int_to if match_top_int_to is not None else 1.
257
+ )
258
+
259
+ def add_darts(self, top, dart_width, dart_depth, dart_position, double_dart=False):
260
+ top_edge_len = top.length()
261
+ if double_dart:
262
+ # TODOLOW Avoid hardcoding for matching with the top?
263
+ dist = dart_position * 0.5 # Dist between darts -> dist between centers
264
+ offsets_mid = [
265
+ - (dart_position + dist / 2 + dart_width / 2) - dart_width / 4,
266
+ - (dart_position - dist / 2) - dart_width / 4,
267
+ dart_position - dist / 2 + dart_width / 4,
268
+ dart_position + dist / 2 + dart_width / 2 + dart_width / 4,
269
+ ]
270
+
271
+ # dart_shape = pyp.EdgeSeqFactory.dart_shape(dart_width, dart_depth)
272
+ dart_shape_full = pyg.EdgeSeqFactory.dart_shape(dart_width / 2, dart_depth)
273
+ dart_shape_small = pyg.EdgeSeqFactory.dart_shape(dart_width / 2, dart_depth * 0.9)
274
+ darts = [
275
+ dart_shape_small,
276
+ dart_shape_full,
277
+ dart_shape_full,
278
+ dart_shape_small,
279
+ ]
280
+ else:
281
+ offsets_mid = [
282
+ - dart_position - dart_width / 2,
283
+ dart_position + dart_width / 2,
284
+ ]
285
+
286
+ dart_shape = pyg.EdgeSeqFactory.dart_shape(dart_width, dart_depth)
287
+ darts = [
288
+ dart_shape,
289
+ dart_shape,
290
+ ]
291
+ top_edges, int_edges = pyg.EdgeSequence(top), pyg.EdgeSequence(top)
292
+
293
+ for off, dart in zip(offsets_mid, darts):
294
+ left_edge_len = top_edges[-1].length()
295
+ top_edges, int_edges = self.add_dart(
296
+ dart,
297
+ top_edges[-1],
298
+ offset=(left_edge_len - top_edge_len / 2) + off,
299
+ edge_seq=top_edges,
300
+ int_edge_seq=int_edges
301
+ )
302
+
303
+ return top_edges, int_edges
304
+
305
+
306
+ # Full garments - Components
307
+ class PencilSkirt(StackableSkirtComponent):
308
+ def __init__(self, body, design, tag='', length=None, rise=None, slit=True, **kwargs) -> None:
309
+ super().__init__(body, design, tag)
310
+
311
+ design = design['pencil-skirt']
312
+ self.design = design # Make accessible from outside
313
+
314
+ # condition
315
+ if design['style_side_cut']['v'] is not None:
316
+ depth = 0.7 * (body['hips'] / 4 - body['bust_points'] / 2)
317
+ shape_class = getattr(shapes, design['style_side_cut']['v'])
318
+ style_shape_l, style_shape_r = shape_class(
319
+ width=depth * 1.5,
320
+ depth=depth, n_rays=6, d_rays=depth*0.2,
321
+ filename=design['style_side_file']['v'] if 'style_side_file' in design else None
322
+ )
323
+ else:
324
+ style_shape_l, style_shape_r = None, None
325
+
326
+ # Force from arguments if given
327
+ self.rise = design['rise']['v'] if rise is None else rise
328
+ waist, hips_depth, back_waist = self.eval_rise(self.rise)
329
+ if length is None:
330
+ length = design['length']['v'] * body['_leg_length'] # Depends on leg length
331
+ else:
332
+ length = length - hips_depth
333
+
334
+ self.front = FittedSkirtPanel(
335
+ 'skirt_front',
336
+ body,
337
+ design,
338
+ (waist - back_waist) / 2,
339
+ (body['hips'] - body['hip_back_width']) / 2,
340
+ hips_depth=hips_depth,
341
+ length=length,
342
+ dart_position=body['bust_points'] / 2,
343
+ dart_frac=0.8, # Diff for front and back
344
+ match_top_int_to=(body['waist'] - body['waist_back_width']),
345
+ slit=design['front_slit']['v'] if slit else 0,
346
+ left_slit=design['left_slit']['v'] if slit else 0,
347
+ right_slit=design['right_slit']['v'] if slit else 0,
348
+ side_cut=style_shape_l
349
+ ).translate_to([0, body['_waist_level'], 25])
350
+
351
+ self.back = FittedSkirtPanel(
352
+ 'skirt_back',
353
+ body,
354
+ design,
355
+ back_waist / 2,
356
+ body['hip_back_width'] / 2,
357
+ length=length,
358
+ hips_depth=hips_depth,
359
+ hipline_ext=1.05,
360
+ dart_position=body['bum_points'] / 2,
361
+ dart_frac=0.85,
362
+ double_dart=True,
363
+ match_top_int_to=body['waist_back_width'],
364
+ slit=design['back_slit']['v'] if slit else 0,
365
+ left_slit=design['left_slit']['v'] if slit else 0,
366
+ right_slit=design['right_slit']['v'] if slit else 0,
367
+ side_cut=style_shape_r,
368
+ flip_side_cut=False,
369
+ ).translate_to([0, body['_waist_level'], -20])
370
+
371
+ self.stitching_rules = pyg.Stitches(
372
+ (self.front.interfaces['right'], self.back.interfaces['right']),
373
+ (self.front.interfaces['left'], self.back.interfaces['left'])
374
+ )
375
+
376
+ # Reusing interfaces of sub-panels as interfaces of this component
377
+ self.interfaces = {
378
+ 'top_f': self.front.interfaces['top'],
379
+ 'top_b': self.back.interfaces['top'],
380
+ 'top': pyg.Interface.from_multiple(
381
+ self.front.interfaces['top'].flip_edges(),
382
+ self.back.interfaces['top'].reverse(with_edge_dir_reverse=True)
383
+ ),
384
+ 'bottom_f': self.front.interfaces['bottom'],
385
+ 'bottom_b': self.back.interfaces['bottom'],
386
+ 'bottom': pyg.Interface.from_multiple(
387
+ self.front.interfaces['bottom'], self.back.interfaces['bottom']
388
+ )
389
+ }
390
+
391
+ def length(self):
392
+ return self.front.length()
393
+
394
+ class Skirt2(StackableSkirtComponent):
395
+ """Simple 2 panel skirt"""
396
+ def __init__(self, body, design, tag='', length=None, rise=None, slit=True, top_ruffles=True, min_len=5) -> None:
397
+ super().__init__(body, design, tag)
398
+
399
+ design = design['skirt']
400
+
401
+ self.rise = design['rise']['v'] if rise is None else rise
402
+ waist, hip_line, back_waist = self.eval_rise(self.rise)
403
+
404
+ # Force from arguments if given
405
+ if length is None:
406
+ length = hip_line + design['length']['v'] * body['_leg_length'] # Depends on leg length
407
+
408
+ # NOTE: with some combinations of rise and length parameters length may become too small/negative
409
+ # Hence putting a min positive value here
410
+ length = max(length, min_len)
411
+
412
+ self.front = SkirtPanel(
413
+ f'skirt_front_{tag}' if tag else 'skirt_front',
414
+ waist_length=waist - back_waist,
415
+ length=length,
416
+ ruffles=design['ruffle']['v'] if top_ruffles else 1, # Only if on waistband
417
+ flare=design['flare']['v'],
418
+ bottom_cut=design['bottom_cut']['v'] * design['length']['v'] if slit else 0,
419
+ match_top_int_to=(body['waist'] - body['waist_back_width'])
420
+ ).translate_to([0, body['_waist_level'], 25])
421
+ self.back = SkirtPanel(
422
+ f'skirt_back_{tag}' if tag else 'skirt_back',
423
+ waist_length=back_waist,
424
+ length=length,
425
+ ruffles=design['ruffle']['v'] if top_ruffles else 1, # Only if on waistband
426
+ flare=design['flare']['v'],
427
+ bottom_cut=design['bottom_cut']['v'] * design['length']['v'] if slit else 0,
428
+ match_top_int_to=body['waist_back_width']
429
+ ).translate_to([0, body['_waist_level'], -20])
430
+
431
+ self.stitching_rules = pyg.Stitches(
432
+ (self.front.interfaces['right'], self.back.interfaces['right']),
433
+ (self.front.interfaces['left'], self.back.interfaces['left'])
434
+ )
435
+
436
+ # Reusing interfaces of sub-panels as interfaces of this component
437
+ self.interfaces = {
438
+ 'top_f': self.front.interfaces['top'],
439
+ 'top_b': self.back.interfaces['top'],
440
+ 'top': pyg.Interface.from_multiple(
441
+ self.front.interfaces['top'], self.back.interfaces['top']
442
+ ),
443
+ 'bottom_f': self.front.interfaces['bottom'],
444
+ 'bottom_b': self.back.interfaces['bottom'],
445
+ 'bottom': pyg.Interface.from_multiple(
446
+ self.front.interfaces['bottom'], self.back.interfaces['bottom']
447
+ )
448
+ }
449
+
450
+ def length(self):
451
+ return self.front.length()
452
+
453
+
454
+ class SkirtManyPanels(BaseBottoms):
455
+ """Round Skirt with many panels"""
456
+
457
+ def __init__(self, body, design, tag='', rise=None, min_len=5) -> None:
458
+ tag_extra = str(design['flare-skirt']['skirt-many-panels']['n_panels']['v'])
459
+ tag = f'{tag}_{tag_extra}' if tag else tag_extra
460
+ super().__init__(body, design, tag=tag, rise=rise)
461
+
462
+ design = design['flare-skirt']
463
+ self.rise = design['rise']['v'] if rise is None else rise
464
+ waist, hip_line, _ = self.eval_rise(self.rise)
465
+ n_panels = design['skirt-many-panels']['n_panels']['v']
466
+
467
+ # Length is dependent on length of legs
468
+ length = hip_line + design['length']['v'] * body['_leg_length']
469
+
470
+ # NOTE: with some combinations of rise and length parameters, length may become too small/negative
471
+ # Hence putting a min positive value here
472
+ length = max(length, min_len)
473
+
474
+ flare_coeff_pi = 1 + design['suns']['v'] * length * 2 * np.pi / waist
475
+
476
+ self.front = ThinSkirtPanel('front',
477
+ panel_w := waist / n_panels,
478
+ bottom_width=panel_w * flare_coeff_pi,
479
+ length=length,
480
+ b_curvature=design['skirt-many-panels']['panel_curve']['v'])
481
+
482
+ # Move far enough s.t. the widest part of the panels fit on the circle
483
+ dist = self.front.interfaces['bottom'].edges.length() / (2 * np.tan(np.pi / n_panels))
484
+
485
+ self.front.translate_to([-dist, body['_waist_level'], 0])
486
+ # Align orientation with a body
487
+ self.front.rotate_by(R.from_euler('XYZ', [0, -90, 0], degrees=True))
488
+ self.front.rotate_align([-dist, 0, panel_w / 2])
489
+
490
+ # Upd interface orientation
491
+ self.front.interfaces['top'].reverse(True)
492
+
493
+ # Create new panels
494
+ self.subs = pyg.ops.distribute_Y(self.front, n_panels, name_tag='skirt_panel')
495
+
496
+ # Stitch new components
497
+ for i in range(1, n_panels):
498
+ self.stitching_rules.append((self.subs[i - 1].interfaces['left'],
499
+ self.subs[i].interfaces['right']))
500
+
501
+ self.stitching_rules.append((self.subs[-1].interfaces['left'],
502
+ self.subs[0].interfaces['right']))
503
+
504
+ # Define the interface
505
+ self.interfaces = {
506
+ 'top': pyg.Interface.from_multiple(*[sub.interfaces['top']
507
+ for sub in self.subs])
508
+ }
509
+
510
+ def length(self):
511
+ return self.front.length()
512
+
GarmentCode/assets/garment_programs/sleeves.py ADDED
@@ -0,0 +1,364 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from copy import deepcopy
2
+
3
+ import numpy as np
4
+ from scipy.spatial.transform import Rotation as R
5
+
6
+ from assets.garment_programs import bands
7
+ import pygarment as pyg
8
+
9
+
10
+ # ------ Armhole shapes ------
11
+ def ArmholeSquare(incl, width, angle, invert=True, **kwargs):
12
+ """Simple square armhole cut-out
13
+ Not recommended to use for sleeves, stitching in 3D might be hard
14
+
15
+ if angle is provided, it also calculated the shape of the sleeve interface to attach
16
+
17
+ returns edge sequence and part to be preserved inverted
18
+ """
19
+
20
+ edges = pyg.EdgeSeqFactory.from_verts([0, 0], [incl, 0], [incl, width])
21
+ if not invert:
22
+ return edges, None
23
+
24
+ sina, cosa = np.sin(angle), np.cos(angle)
25
+ l = edges[0].length()
26
+ sleeve_edges = pyg.EdgeSeqFactory.from_verts(
27
+ [incl + l*sina, - l*cosa],
28
+ [incl, 0], [incl, width])
29
+
30
+ # TODOLOW Bend instead of rotating to avoid sharp connection
31
+ sleeve_edges.rotate(angle=-angle)
32
+
33
+ return edges, sleeve_edges
34
+
35
+
36
+ def ArmholeAngle(incl, width, angle, incl_coeff=0.2, w_coeff=0.2,
37
+ invert=True, **kwargs):
38
+ """Piece-wise smooth armhole shape"""
39
+ diff_incl = incl * (1 - incl_coeff)
40
+ edges = pyg.EdgeSeqFactory.from_verts(
41
+ [0, 0], [diff_incl, w_coeff * width], [incl, width])
42
+ if not invert:
43
+ return edges, None
44
+
45
+ sina, cosa = np.sin(angle), np.cos(angle)
46
+ l = edges[0].length()
47
+ sleeve_edges = pyg.EdgeSeqFactory.from_verts(
48
+ [diff_incl + l*sina, w_coeff * width - l*cosa],
49
+ [diff_incl, w_coeff * width], [incl, width])
50
+ # TODOLOW Bend instead of rotating to avoid sharp connection
51
+ sleeve_edges.rotate(angle=-angle)
52
+
53
+ return edges, sleeve_edges
54
+
55
+
56
+ def ArmholeCurve(incl, width, angle, bottom_angle_mix=0, invert=True, verbose=False, **kwargs):
57
+ """ Classic sleeve opening on Cubic Bezier curves
58
+ """
59
+ # Curvature as parameters?
60
+ cps = [[0.5, 0.2], [0.8, 0.35]]
61
+ edge = pyg.CurveEdge([incl, width], [0, 0], cps)
62
+ edge_as_seq = pyg.EdgeSequence(edge.reverse())
63
+
64
+ if not invert:
65
+ return edge_as_seq, None
66
+
67
+ # Initialize inverse (initial guess)
68
+ # Agle == 0
69
+ down_direction = np.array([0, -1]) # Full opening is vertically aligned
70
+ inv_cps = deepcopy(cps)
71
+ inv_cps[-1][1] *= -1 # Invert the last
72
+ inv_edge = pyg.CurveEdge(
73
+ start=[incl, width],
74
+ end=(np.array([incl, width]) + down_direction * edge._straight_len()).tolist(),
75
+ control_points=inv_cps
76
+ )
77
+
78
+ # Rotate by desired angle (usually desired sleeve rest angle)
79
+ inv_edge.rotate(angle=-angle)
80
+
81
+ # Optimize the inverse shape to be nice
82
+ shortcut = inv_edge.shortcut()
83
+ rotated_direction = shortcut[-1] - shortcut[0]
84
+ rotated_direction /= np.linalg.norm(rotated_direction)
85
+ left_direction = np.array([-1, 0])
86
+ mix_factor = bottom_angle_mix
87
+
88
+ dir = (1 - mix_factor) * rotated_direction + (
89
+ mix_factor * down_direction if mix_factor > 0 else (- mix_factor * left_direction))
90
+
91
+ # TODOLOW Remember relative curvature results and reuse them? (speed)
92
+ fin_inv_edge = pyg.ops.curve_match_tangents(
93
+ inv_edge.as_curve(),
94
+ down_direction, # Full opening is vertically aligned
95
+ dir,
96
+ target_len=edge.length(),
97
+ return_as_edge=True,
98
+ verbose=verbose
99
+ )
100
+
101
+ return edge_as_seq, pyg.EdgeSequence(fin_inv_edge.reverse())
102
+
103
+
104
+ # -------- New sleeve definitions -------
105
+
106
+ class SleevePanel(pyg.Panel):
107
+ """Trying proper sleeve panel"""
108
+
109
+ def __init__(self, name, body, design, open_shape, length_shift=0, _standing_margin=5):
110
+ """Define a standard sleeve panel (half a sleeve)
111
+ * length_shift -- force upd sleeve length by this amount.
112
+ Can be used to adjust length evaluation to fit the cuff
113
+ """
114
+ super().__init__(name)
115
+ MIN_LENGTH = 5 # Minimum sleeve length
116
+
117
+ shoulder_angle = np.deg2rad(body['_shoulder_incl'])
118
+ rest_angle = max(np.deg2rad(design['sleeve_angle']['v']),
119
+ shoulder_angle)
120
+ standing = design['standing_shoulder']['v']
121
+
122
+ # Calculating extension size & end size before applying ruffles
123
+ # Since ruffles add to pattern length & width, but not to de-facto
124
+ # sleeve length in 3D
125
+ end_width = design['end_width']['v'] * abs(open_shape[0].start[1] - open_shape[-1].end[1])
126
+ # Ensure it fits regardless of parameters
127
+ end_width = max(end_width, body['wrist'] / 2)
128
+
129
+ # Ruffles at opening
130
+ if not pyg.utils.close_enough(design['connect_ruffle']['v'], 1):
131
+ open_shape.extend(design['connect_ruffle']['v'])
132
+
133
+ # -- Main body of a sleeve --
134
+ opening_length = abs(open_shape[0].start[0] - open_shape[-1].end[0])
135
+ arm_width = abs(open_shape[0].start[1] - open_shape[-1].end[1])
136
+ # Length from the border of the opening to the end of the sleeve
137
+ length = design['length']['v'] * (body['arm_length'] - opening_length)
138
+ # NOTE: Asked to reduce by too much: reduce as much as possible
139
+ length = max(length + length_shift, MIN_LENGTH)
140
+
141
+ self.edges = pyg.EdgeSeqFactory.from_verts(
142
+ [0, 0], [0, -end_width], [length, -arm_width]
143
+ )
144
+
145
+ # Align the opening
146
+ open_shape.snap_to(self.edges[-1].end)
147
+ open_shape[0].start = self.edges[-1].end # chain
148
+ self.edges.append(open_shape)
149
+ # Fin
150
+ self.edges.close_loop()
151
+
152
+ if standing:
153
+ if rest_angle > (shoulder_angle + np.deg2rad(_standing_margin)): # Add a "shelve" to create square shoulder appearance
154
+ top_edge = self.edges[-1]
155
+ start = top_edge.start
156
+ len = design['standing_shoulder_len']['v']
157
+
158
+ x_shift = len * np.cos(rest_angle - shoulder_angle)
159
+ y_shift = len * np.sin(rest_angle - shoulder_angle)
160
+
161
+ standing_edge = pyg.Edge(
162
+ start=start,
163
+ end=[start[0] - x_shift, start[1] + y_shift]
164
+ )
165
+ top_edge.start = standing_edge.end
166
+
167
+ self.edges.substitute(top_edge, [standing_edge, top_edge])
168
+ else:
169
+ if self.verbose:
170
+ print(f'{self.__class__.__name__}::WARNING::'
171
+ f'Sleeve rest angle {np.rad2deg(rest_angle):.3f} should be '
172
+ f'larger than shoulder angle {body["_shoulder_incl"]} by '
173
+ f'at least {_standing_margin} deg to enable '
174
+ 'standing shoulder. Standing shoulder ignored')
175
+ standing = False
176
+
177
+ # Interfaces
178
+ self.interfaces = {
179
+ # NOTE: interface needs reversing because the open_shape was reversed for construction
180
+ 'in': pyg.Interface(self, open_shape, ruffle=design['connect_ruffle']['v']),
181
+ 'out': pyg.Interface(self, self.edges[0], ruffle=design['cuff']['top_ruffle']['v']),
182
+ 'top': pyg.Interface(self, self.edges[-2:] if standing else self.edges[-1]),
183
+ 'bottom': pyg.Interface(self, self.edges[1])
184
+ }
185
+
186
+ # Default placement
187
+ self.set_pivot(self.edges[-1].start)
188
+ self.translate_to([
189
+ - body['shoulder_w'] / 2,
190
+ body['height'] - body['head_l'],
191
+ 0,
192
+ ])
193
+
194
+ def length(self, longest_dim=False):
195
+ return self.interfaces['bottom'].edges.length()
196
+
197
+
198
+ class Sleeve(pyg.Component):
199
+ """Trying to do a proper sleeve"""
200
+ def __init__(self, tag, body, design, front_w, back_w):
201
+ """Defintion of a sleeve:
202
+ * front_w, back_w: the width front and the back of the top
203
+ the sleeve will attach to -- needed for correct share calculations
204
+ They may be
205
+ * Specified as scalar numbers
206
+ * Specified as functions w.r.t. the requested vertical level (=>
207
+ calculated width of a horizontal slice)
208
+ """
209
+ super().__init__(f'{self.__class__.__name__}_{tag}')
210
+
211
+ design = design['sleeve']
212
+ self.design = design
213
+ self.body = body
214
+
215
+ sleeve_balance = body['_base_sleeve_balance'] / 2
216
+
217
+ rest_angle = max(np.deg2rad(design['sleeve_angle']['v']),
218
+ np.deg2rad(body['_shoulder_incl']))
219
+
220
+ connecting_width = design['connecting_width']['v']
221
+ smoothing_coeff = design['smoothing_coeff']['v']
222
+
223
+ front_w = front_w(connecting_width) if callable(front_w) else front_w
224
+ back_w = back_w(connecting_width) if callable(back_w) else back_w
225
+
226
+ # --- Define sleeve opening shapes ----
227
+ # NOTE: Non-trad armholes only for sleeveless styles due to
228
+ # unclear inversion and stitching errors (see below)
229
+ armhole = globals()[design['armhole_shape']['v']] if design['sleeveless']['v'] else ArmholeCurve
230
+ front_project, front_opening = armhole(
231
+ front_w - sleeve_balance,
232
+ connecting_width,
233
+ angle=rest_angle,
234
+ incl_coeff=smoothing_coeff,
235
+ w_coeff=smoothing_coeff,
236
+ invert=not design['sleeveless']['v'],
237
+ bottom_angle_mix=design['opening_dir_mix']['v'],
238
+ verbose=self.verbose
239
+ )
240
+ back_project, back_opening = armhole(
241
+ back_w - sleeve_balance,
242
+ connecting_width,
243
+ angle=rest_angle,
244
+ incl_coeff=smoothing_coeff,
245
+ w_coeff=smoothing_coeff,
246
+ invert=not design['sleeveless']['v'],
247
+ bottom_angle_mix=design['opening_dir_mix']['v']
248
+ )
249
+
250
+ self.interfaces = {
251
+ 'in_front_shape': pyg.Interface(self, front_project),
252
+ 'in_back_shape': pyg.Interface(self, back_project)
253
+ }
254
+
255
+ if design['sleeveless']['v']:
256
+ # The rest is not needed!
257
+ return
258
+
259
+ if front_w != back_w:
260
+ front_opening, back_opening = pyg.ops.even_armhole_openings(
261
+ front_opening, back_opening,
262
+ tol=0.2 / front_opening.length(), # ~2mm tolerance as a fraction of length
263
+ verbose=self.verbose
264
+ )
265
+
266
+ # --- Eval length adjustment for cuffs (if any) ----
267
+ cuff_len_adj = self._cuff_len_adj()
268
+
269
+ # ----- Get sleeve panels -------
270
+ self.f_sleeve = SleevePanel(
271
+ f'{tag}_sleeve_f', body, design, front_opening,
272
+ length_shift=-cuff_len_adj
273
+ ).translate_by([0, 0, 15])
274
+ self.b_sleeve = SleevePanel(
275
+ f'{tag}_sleeve_b', body, design, back_opening,
276
+ length_shift=-cuff_len_adj
277
+ ).translate_by([0, 0, -15])
278
+
279
+ # Connect panels
280
+ self.stitching_rules = pyg.Stitches(
281
+ (self.f_sleeve.interfaces['top'],
282
+ self.b_sleeve.interfaces['top']),
283
+ (self.f_sleeve.interfaces['bottom'],
284
+ self.b_sleeve.interfaces['bottom']),
285
+ )
286
+
287
+ # Interfaces
288
+ self.interfaces.update({
289
+ 'in': pyg.Interface.from_multiple(
290
+ self.f_sleeve.interfaces['in'],
291
+ self.b_sleeve.interfaces['in'].reverse(with_edge_dir_reverse=True)
292
+ ),
293
+ 'out': pyg.Interface.from_multiple(
294
+ self.f_sleeve.interfaces['out'],
295
+ self.b_sleeve.interfaces['out']
296
+ ),
297
+ })
298
+
299
+ # Cuff
300
+ if design['cuff']['type']['v']:
301
+ # Class
302
+ # Copy to avoid editing original design dict
303
+ cdesign = deepcopy(design)
304
+ cuff_circ = self.interfaces['out'].edges.length() / design['cuff']['top_ruffle']['v']
305
+ # Ensure it fits regardless of parameters
306
+ cuff_circ = max(cuff_circ, body['wrist'])
307
+ cdesign['cuff']['b_width'] = dict(v=cuff_circ)
308
+ cdesign['cuff']['cuff_len']['v'] = cuff_len_adj
309
+
310
+ cuff_class = getattr(bands, cdesign['cuff']['type']['v'])
311
+ self.cuff = cuff_class(f'sl_{tag}', cdesign)
312
+
313
+ # Position
314
+ self.cuff.rotate_by(
315
+ R.from_euler(
316
+ 'XYZ',
317
+ [0, 0, -90], # from -Ox direction
318
+ degrees=True
319
+ )
320
+ )
321
+ self.cuff.place_by_interface(
322
+ self.cuff.interfaces['top'],
323
+ self.interfaces['out'],
324
+ gap=2,
325
+ alignment='top'
326
+ )
327
+
328
+ self.stitching_rules.append(
329
+ (
330
+ self.cuff.interfaces['top'],
331
+ self.interfaces['out']
332
+ )
333
+ )
334
+
335
+ # UPD out interface!
336
+ self.interfaces['out'] = self.cuff.interfaces['bottom']
337
+
338
+ # Final rotation of sleeve piece
339
+ self.rotate_by(R.from_euler(
340
+ 'XYZ', [0, 0, body['arm_pose_angle']], degrees=True))
341
+
342
+ # Set label
343
+ self.set_panel_label('arm')
344
+
345
+ def _cuff_len_adj(self):
346
+ """Eval sleeve length adjustment due to cuffs (if any)"""
347
+ if not self.design['cuff']['type']['v']:
348
+ return 0
349
+
350
+ cuff_len_adj = self.design['cuff']['cuff_len']['v'] * self.body['arm_length']
351
+ max_len = self.design['length']['v'] * self.body['arm_length']
352
+ if cuff_len_adj > max_len * 0.7:
353
+ cuff_len_adj = max_len * 0.7
354
+
355
+ return cuff_len_adj
356
+
357
+ def length(self):
358
+ if self.design['sleeveless']['v']:
359
+ return 0
360
+
361
+ if self.design['cuff']['type']['v']:
362
+ return self.f_sleeve.length() + self.cuff.length()
363
+
364
+ return self.f_sleeve.length()
GarmentCode/assets/garment_programs/stats_utils.py ADDED
@@ -0,0 +1,150 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Design analysis routines to supply intresting stats"""
2
+
3
+ import pygarment.pattern.core as pattern
4
+ import yaml
5
+
6
+ # panels
7
+ def count_panels(pattern:pattern.BasicPattern, props, verbose=False):
8
+
9
+ n_panels = len(pattern.pattern['panels'].keys())
10
+ if verbose:
11
+ print(pattern.name, ' Panel count ', n_panels)
12
+
13
+ props['generator']['stats']['panel_count'][pattern.name] = n_panels
14
+
15
+
16
+ # Type determination
17
+
18
+ def bottom_length(design):
19
+ meta = design['meta']
20
+ if meta['bottom']['v']:
21
+ bottom_section = None
22
+ if meta['bottom']['v'] in ['SkirtCircle', 'AsymmSkirtCircle', 'SkirtManyPanels']:
23
+ bottom_section = 'flare-skirt'
24
+ elif meta['bottom']['v'] == 'Pants':
25
+ bottom_section = 'pants'
26
+ elif meta['bottom']['v'] == 'Skirt2':
27
+ bottom_section = 'skirt'
28
+ elif meta['bottom']['v'] == 'PencilSkirt':
29
+ bottom_section = 'pencil-skirt'
30
+ elif meta['bottom']['v'] == 'SkirtLevels':
31
+ bottom_section = 'levels-skirt'
32
+ elif meta['bottom']['v'] == 'GodetSkirt':
33
+ base = design['godet-skirt']['base']['v']
34
+ if base == 'Skirt2':
35
+ bottom_section = 'skirt'
36
+ else: # One other option
37
+ bottom_section = 'pencil-skirt'
38
+ else:
39
+ raise(ValueError(f'Unknown bottoms type {meta["bottom"]["v"]}'))
40
+
41
+ return design[bottom_section]['length']['v']
42
+ else:
43
+ return 0
44
+
45
+ def sleeve_length(design):
46
+ # Sleeve length
47
+ sleeve_len_r = design['sleeve']['length']['v'] if not design['sleeve']['sleeveless']['v'] else 0
48
+ sleeve_len_l = design['left']['sleeve']['length']['v'] if design['left']['enable_asym']['v'] and not design['left']['sleeve']['sleeveless']['v'] else 0
49
+ return max(sleeve_len_r, sleeve_len_l)
50
+
51
+ def top_length(design):
52
+ if design['meta']['upper']['v'] == 'FittedShirt':
53
+ return 1.
54
+ elif design['meta']['upper']['v'] == 'Shirt':
55
+ return design['shirt']['length']['v']
56
+ else:
57
+ return 0.
58
+
59
+ def vertical_len(design):
60
+ # NOTE: this will give very approximate result since
61
+ # the units of mesurement are slightly different
62
+ wb_len = design['waistband']['width']['v'] if design['meta']['wb']['v'] else 0
63
+ return top_length(design) + wb_len + bottom_length(design)
64
+
65
+ def garment_type(el_name, design, props, verbose=False):
66
+ main_type = None
67
+ add_types = []
68
+ # Main:
69
+ # + upper garment (short skirt - top or dress?)
70
+ # + skirt
71
+ # + pants
72
+ # + dress
73
+ # + jumpsuit
74
+ # Additional labels:
75
+ # + asymmetrical top
76
+ # + Hoody?
77
+ # + maxi/midi/mini
78
+ # + sleeve/less
79
+ # + long sleeve / short sleeve?
80
+ meta = design['meta']
81
+ if meta['upper']['v']:
82
+ if meta['bottom']['v'] and 'Pants' in meta['bottom']['v']:
83
+ main_type = 'jumpsuit'
84
+ elif vertical_len(design) < 1.4: # NOTE: very approximate division
85
+ main_type = 'upper_garment'
86
+ else:
87
+ main_type = 'dress'
88
+ else:
89
+ if 'Pants' in meta['bottom']['v']:
90
+ main_type = 'pants'
91
+ else:
92
+ main_type = 'skirt'
93
+
94
+ # Additional types
95
+ if meta['upper']['v']:
96
+ if design['left']['enable_asym']['v']:
97
+ add_types.append('asymmetric_top')
98
+ if (not design['left']['enable_asym']['v']
99
+ and design['collar']['component']['style']['v']
100
+ and 'Hood' in design['collar']['component']['style']['v']):
101
+ add_types.append('hoodie')
102
+
103
+ if (design['sleeve']['sleeveless']['v']
104
+ and (design['left']['sleeve']['sleeveless']['v'] if design['left']['enable_asym']['v'] else True)):
105
+ add_types.append('sleeveless')
106
+ else:
107
+ add_types.append('with_sleeves')
108
+
109
+ sleeve_len = sleeve_length(design)
110
+ if sleeve_len < 0.5:
111
+ add_types.append('short_sleeve')
112
+ else:
113
+ add_types.append('long_sleeve')
114
+
115
+ # Mini/Midi/Maxi
116
+ if meta['bottom']['v']:
117
+ length = bottom_length(design)
118
+ if length < 0.3:
119
+ add_types.append('mini')
120
+ elif length < 0.5:
121
+ add_types.append('knee_len')
122
+ elif length < 0.65:
123
+ add_types.append('midi')
124
+ else:
125
+ add_types.append('maxi')
126
+
127
+
128
+ if verbose:
129
+ print(el_name, ' types ', main_type, add_types)
130
+
131
+ props['generator']['stats']['garment_types'][el_name] = {
132
+ 'main': main_type,
133
+ 'styles': add_types
134
+ }
135
+
136
+ # Summary
137
+ summary = props['generator']['stats']['garment_types_summary']
138
+ if main_type not in summary['main']:
139
+ summary['main'][main_type] = 1
140
+ else:
141
+ summary['main'][main_type] += 1
142
+ for style_t in add_types:
143
+ if style_t not in summary['style']:
144
+ summary['style'][style_t] = {'total': 0}
145
+ summary['style'][style_t]['total'] += 1
146
+ if main_type not in summary['style'][style_t]:
147
+ summary['style'][style_t][main_type] = 1
148
+ else:
149
+ summary['style'][style_t][main_type] += 1
150
+
GarmentCode/assets/garment_programs/tee.py ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """ Panels for a straight upper garment (T-shirt)
2
+ Note that the code is very similar to Bodice.
3
+ """
4
+ import numpy as np
5
+ import pygarment as pyg
6
+
7
+ from assets.garment_programs.base_classes import BaseBodicePanel
8
+
9
+
10
+ class TorsoFrontHalfPanel(BaseBodicePanel):
11
+ """Half of a simple non-fitted upper garment (e.g. T-Shirt)
12
+
13
+ Fits to the bust size
14
+ """
15
+ def __init__(self, name, body, design) -> None:
16
+ """ Front = True, provides the adjustments necessary for the front panel
17
+ """
18
+ super().__init__(name, body, design)
19
+
20
+ design = design['shirt']
21
+
22
+ # width
23
+ m_width = design['width']['v'] * body['bust']
24
+ b_width = design['flare']['v'] * m_width
25
+
26
+ # sizes
27
+ body_width = (body['bust'] - body['back_width']) / 2
28
+ frac = body_width / body['bust']
29
+ self.width = frac * m_width
30
+ b_width = frac * b_width
31
+
32
+ sh_tan = np.tan(np.deg2rad(body['_shoulder_incl']))
33
+ shoulder_incl = sh_tan * self.width
34
+ length = design['length']['v'] * body['waist_line']
35
+
36
+ # length in the front panel is adjusted due to shoulder inclination
37
+ # for the correct sleeve fitting
38
+ fb_diff = (frac - (0.5 - frac)) * body['bust']
39
+ length = length - sh_tan * fb_diff
40
+
41
+ self.edges = pyg.EdgeSeqFactory.from_verts(
42
+ [0, 0],
43
+ [-b_width, 0],
44
+ [-self.width, length],
45
+ [0, length + shoulder_incl],
46
+ loop=True
47
+ )
48
+
49
+ # Interfaces
50
+ self.interfaces = {
51
+ 'outside': pyg.Interface(self, self.edges[1]),
52
+ 'inside': pyg.Interface(self, self.edges[-1]),
53
+ 'shoulder': pyg.Interface(self, self.edges[-2]),
54
+ 'bottom': pyg.Interface(self, self.edges[0], ruffle=self.edges[0].length() / ((body['waist'] - body['waist_back_width']) / 2)),
55
+
56
+ # Reference to the corner for sleeve and collar projections
57
+ 'shoulder_corner': pyg.Interface(self, [self.edges[-3], self.edges[-2]]),
58
+ 'collar_corner': pyg.Interface(self, [self.edges[-2], self.edges[-1]])
59
+ }
60
+
61
+ # default placement
62
+ self.translate_by([0, body['height'] - body['head_l'] - length - shoulder_incl, 0])
63
+
64
+ def get_width(self, level):
65
+ return super().get_width(level) + self.width - self.body['shoulder_w'] / 2
66
+
67
+
68
+ class TorsoBackHalfPanel(BaseBodicePanel):
69
+ """Half of a simple non-fitted upper garment (e.g. T-Shirt)
70
+
71
+ Fits to the bust size
72
+ """
73
+ def __init__(self, name, body, design) -> None:
74
+ """ Front = True, provides the adjustments necessary for the front panel
75
+ """
76
+ super().__init__(name, body, design)
77
+
78
+ design = design['shirt']
79
+ # account for ease in basic measurements
80
+ m_width = design['width']['v'] * body['bust']
81
+ b_width = design['flare']['v'] * m_width
82
+
83
+ # sizes
84
+ body_width = body['back_width'] / 2
85
+ frac = body_width / body['bust']
86
+ self.width = frac * m_width
87
+ b_width = frac * b_width
88
+
89
+ shoulder_incl = (np.tan(np.deg2rad(body['_shoulder_incl']))) * self.width
90
+ length = design['length']['v'] * body['waist_line']
91
+
92
+ self.edges = pyg.EdgeSeqFactory.from_verts(
93
+ [0, 0],
94
+ [-b_width, 0],
95
+ [-self.width, length],
96
+ [0, length + shoulder_incl],
97
+ loop=True
98
+ )
99
+
100
+ # Interfaces
101
+ self.interfaces = {
102
+ 'outside': pyg.Interface(self, self.edges[1]),
103
+ 'inside': pyg.Interface(self, self.edges[-1]),
104
+ 'shoulder': pyg.Interface(self, self.edges[-2]),
105
+ 'bottom': pyg.Interface(self, self.edges[0], ruffle=self.edges[0].length() / (body['waist_back_width'] / 2)),
106
+
107
+ # Reference to the corner for sleeve and collar projections
108
+ 'shoulder_corner': pyg.Interface(self, [self.edges[-3], self.edges[-2]]),
109
+ 'collar_corner': pyg.Interface(self, [self.edges[-2], self.edges[-1]])
110
+ }
111
+
112
+ # default placement
113
+ self.translate_by([0, body['height'] - body['head_l'] - length - shoulder_incl, 0])
114
+
115
+ def get_width(self, level):
116
+ return super().get_width(level) + self.width - self.body['shoulder_w'] / 2
GarmentCode/assets/img/err_dress_20s.png ADDED

Git LFS Details

  • SHA256: 288f2acac09aeac698676e6e56b934caa8ace39ea077b526c41ccccabc75d2f8
  • Pointer size: 131 Bytes
  • Size of remote file: 885 kB