knit-graphs 0.0.6__py3-none-any.whl → 0.0.7__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. knit_graphs-0.0.6.dist-info/licenses/LICENSE → LICENSE +21 -21
  2. README.md +75 -0
  3. docs/Makefile +20 -0
  4. docs/make.bat +35 -0
  5. docs/source/api/knit_graphs.artin_wale_braids.rst +58 -0
  6. docs/source/api/knit_graphs.rst +74 -0
  7. docs/source/conf.py +335 -0
  8. docs/source/index.rst +71 -0
  9. docs/source/installation.rst +67 -0
  10. knit_graphs/Course.py +156 -104
  11. knit_graphs/Knit_Graph.py +249 -186
  12. knit_graphs/Knit_Graph_Visualizer.py +680 -0
  13. knit_graphs/Loop.py +141 -155
  14. knit_graphs/Pull_Direction.py +68 -23
  15. knit_graphs/Yarn.py +424 -267
  16. knit_graphs/__init__.py +3 -3
  17. knit_graphs/_base_classes.py +173 -0
  18. knit_graphs/artin_wale_braids/Crossing_Direction.py +74 -15
  19. knit_graphs/artin_wale_braids/Loop_Braid_Graph.py +95 -62
  20. knit_graphs/artin_wale_braids/Wale.py +169 -93
  21. knit_graphs/artin_wale_braids/Wale_Braid.py +50 -30
  22. knit_graphs/artin_wale_braids/Wale_Braid_Word.py +99 -54
  23. knit_graphs/artin_wale_braids/Wale_Group.py +136 -88
  24. knit_graphs/{knit_graph_generators/basic_knit_graph_generators.py → basic_knit_graph_generators.py} +302 -248
  25. knit_graphs-0.0.7.dist-info/LICENSE +21 -0
  26. {knit_graphs-0.0.6.dist-info → knit_graphs-0.0.7.dist-info}/METADATA +33 -24
  27. knit_graphs-0.0.7.dist-info/RECORD +29 -0
  28. {knit_graphs-0.0.6.dist-info → knit_graphs-0.0.7.dist-info}/WHEEL +1 -1
  29. knit_graphs/__about__.py +0 -4
  30. knit_graphs/knit_graph_generators/__init__.py +0 -0
  31. knit_graphs/knit_graph_visualizer/Stitch_Visualizer.py +0 -427
  32. knit_graphs/knit_graph_visualizer/__init__.py +0 -0
  33. knit_graphs-0.0.6.dist-info/RECORD +0 -22
@@ -1,23 +1,29 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.1
2
2
  Name: knit-graphs
3
- Version: 0.0.6
3
+ Version: 0.0.7
4
4
  Summary: A graph representation of knitted structures where each loop is a node and edges represent yarn and stitch relationships.
5
- Project-URL: Documentation, https://github.com/mhofmann-Khoury/knit_graph#readme
6
- Project-URL: Issues, https://github.com/mhofmann-Khoury/knit_graph/issues
7
- Project-URL: Source, https://github.com/mhofmann-Khoury/knit_graph
8
- Author-email: Megan Hofmann <m.hofmann@northeastern.edu>
9
- License-File: LICENSE
10
- Keywords: ACT Lab,Northeastern,fabrication,knit,machine knit,textile
11
- Classifier: Development Status :: 2 - Pre-Alpha
5
+ Home-page: https://mhofmann-Khoury.github.io/knit-graphs/
6
+ License: MIT
7
+ Keywords: ACT Lab,Northeastern University,knit,machine knit,fabrication,textile
8
+ Author: Megan Hofmann
9
+ Author-email: m.hofmann@northeastern.edu
10
+ Maintainer: Megan Hofmann
11
+ Maintainer-email: m.hofmann@northeastern.edu
12
+ Requires-Python: >=3.11,<3.14
13
+ Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
12
16
  Classifier: Natural Language :: English
13
- Classifier: Programming Language :: Python
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python :: 3
14
19
  Classifier: Programming Language :: Python :: 3.11
15
20
  Classifier: Programming Language :: Python :: 3.12
16
- Classifier: Programming Language :: Python :: Implementation :: PyPy
21
+ Classifier: Programming Language :: Python :: 3.13
17
22
  Classifier: Topic :: Scientific/Engineering
18
- Requires-Python: >=3.11
19
- Requires-Dist: networkx~=3.2.1
20
- Requires-Dist: plotly~=5.22.0
23
+ Requires-Dist: networkx (>=3.5)
24
+ Requires-Dist: plotly (>=6.3.0)
25
+ Project-URL: Documentation, https://mhofmann-Khoury.github.io/knit-graphs/
26
+ Project-URL: Repository, https://github.com/mhofmann-Khoury/knit-graphs
21
27
  Description-Content-Type: text/markdown
22
28
 
23
29
  # knit_graphs
@@ -27,9 +33,9 @@ Description-Content-Type: text/markdown
27
33
 
28
34
  -----
29
35
  ## Description
30
- The knit-graphs packaged provides a data structure for representing knitted structures formed of loops of yarn (nodes) connected by various edge structures. Loops are connected by: floats (yarn-edges) in a yarn graph structure, stitch edges (loops pulled through loops), and crossed over each other in a wale-braid structure.
36
+ The knit-graphs packaged provides a data structure for representing knitted structures formed of loops of yarn (nodes) connected by various edge structures. Loops are connected by: floats (yarn-edges) in a yarn graph structure, stitch edges (loops pulled through loops), and crossed over each other in a wale-braid structure.
31
37
 
32
- Knit graphs provide a powerful tool for representing knitted structures for digital fabrication systems such as knitting machine programming languages and design tools.
38
+ Knit graphs provide a powerful tool for representing knitted structures for digital fabrication systems such as knitting machine programming languages and design tools.
33
39
 
34
40
  Additional details about this knit-graph construction are available in the ACM publication:
35
41
  ["KnitPicking Texture: Programming and Modifying Complex Knitted Textures for Machine and Hand Knitting"](https://doi.org/10.1145/3332165.3347886)
@@ -54,25 +60,27 @@ pip install knit-graphs
54
60
  ## Usage
55
61
 
56
62
  ### Knit Graph Generators
57
- The [knit-graph-generators subpackage](https://github.com/mhofmann-Khoury/knit_graph/tree/main/src/knit_graphs/knit_graph_generators) provides a library of basic knit graphs to generate such as casting on loops of a knitted structure, creating Jersey (aka Stockinette) tubes and swatches, and other basic textures.
63
+ The [knit-graph-generators subpackage](https://github.com/mhofmann-Khoury/knit_graph/tree/main/src/knit_graphs/knit_graph_generators) provides a library of basic knit graphs to generate such as casting on loops of a knitted structure, creating Jersey (aka Stockinette) tubes and swatches, and other basic textures.
58
64
  For example, to generate a swatch of knit-purl ribbing use the following:
65
+
59
66
  ```python
60
- from knit_graphs.knit_graph_generators.basic_knit_graph_generators import kp_rib_swatch
67
+ from knit_graphs.basic_knit_graph_generators import kp_rib_swatch
68
+
61
69
  width = 10
62
70
  height = 10
63
71
  kp_rib_swatch = kp_rib_swatch(width, height)
64
72
  ```
65
73
  Additional examples of knitgraph generator usage can be found in the [Knit_Graph test module](https://github.com/mhofmann-Khoury/knit_graph/blob/main/tests/test_Knit_Graph.py).
66
74
 
67
- Knitgraphs can be created without generators. We encourage users to review the generators as simple examples on creating a knit graph programmatically.
75
+ Knitgraphs can be created without generators. We encourage users to review the generators as simple examples on creating a knit graph programmatically.
68
76
 
69
77
  ### Visualizing Knit Graphs
70
- We provide simple support for visualizing knit graphs. This is primarily used to debugging simple knit graph programs.
78
+ We provide simple support for visualizing knit graphs. This is primarily used to debugging simple knit graph programs.
71
79
 
72
80
  For example, we can visualize a swatch of seed stitch (checkered knit and purl stitches) with the following code.
73
81
 
74
82
  ```python
75
- from knit_graphs.knit_graph_generators.basic_knit_graph_generators import seed_swatch
83
+ from knit_graphs.basic_knit_graph_generators import seed_swatch
76
84
  from knit_graphs.knit_graph_visualizer.Stitch_Visualizer import visualize_stitches
77
85
 
78
86
  width = 4
@@ -80,16 +88,17 @@ height = 4
80
88
  swatch = seed_swatch(width, height)
81
89
  visualize_stitches(swatch)
82
90
  ```
83
- The visualizer shows knit stitches (loops pulled from the back of the fabric to the front) as blue edges and purl stitches (loops pulled from the front to back) (aka back-knits) as red edges. Loop nodes are circles labeled with their time-ordered index and colored to match their yarn (defaults to dark green). The yarn edges (aka floats) connecting them are made of thin edges the same color as the loop nodes.
91
+ The visualizer shows knit stitches (loops pulled from the back of the fabric to the front) as blue edges and purl stitches (loops pulled from the front to back) (aka back-knits) as red edges. Loop nodes are circles labeled with their time-ordered index and colored to match their yarn (defaults to dark green). The yarn edges (aka floats) connecting them are made of thin edges the same color as the loop nodes.
84
92
 
85
93
  Additional examples of using the visualizer are available in the [Stitch Visualizer Tests Module](https://github.com/mhofmann-Khoury/knit_graph/blob/main/tests/test_Stitch_Visualizer.py)
86
94
 
87
95
  ## Credits
88
- The design of this data scructure was completed by the authors of
96
+ The design of this data scructure was completed by the authors of
89
97
  ["KnitPicking Texture: Programming and Modifying Complex Knitted Textures for Machine and Hand Knitting"](https://doi.org/10.1145/3332165.3347886).
90
98
 
91
99
  The inclusion of the Artin-Braide wale crossing construction was inspired by ["An Artin Braid Group Representation of Knitting Machine State with Applications to Validation and Optimization of Fabrication Plans"](https://doi.org/10.1109/ICRA48506.2021.9562113) by Jenny Lin and James McCann.
92
100
 
93
101
  ## License
94
102
 
95
- `knit-graphs` is distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license.
103
+ `knit-graphs` is distributed under the terms of the [MIT](https://spdx.org/licenses/MIT.html) license.
104
+
@@ -0,0 +1,29 @@
1
+ LICENSE,sha256=Oazk3oiRu5ZN7b-EdYNYh0vu-I3Av2uIPQ-9L_cZ6Oo,1070
2
+ README.md,sha256=Hrs3kN8A7hxyel-WhEkzZYY89456vAh3KWbupcOAHsI,3963
3
+ docs/Makefile,sha256=4zv3TVkTACm6JBaKgTES3ZI9cETXgM6ULbZkXZP1as8,638
4
+ docs/make.bat,sha256=0qjrzODegavKd7LLwmr9ADhaYftiTnBgqOVAL9kApyo,769
5
+ docs/source/api/knit_graphs.artin_wale_braids.rst,sha256=_KUBZld6fAS5OP0k4gd5yKamNGXEqH12XjakmWeJIII,1549
6
+ docs/source/api/knit_graphs.rst,sha256=zdmnXipviweW0ZGQsQCZtfOOc_6Fj0yWdg_TwOMafLI,1398
7
+ docs/source/conf.py,sha256=TZK8Rz0JNgQs2J_cUhVX5_4tmMBvRdGtILJsnAnAFWo,13350
8
+ docs/source/index.rst,sha256=D4KmCX1_d2-WrPgxSeggHHsc9-TeQwSUGYOkehRQWrw,1462
9
+ docs/source/installation.rst,sha256=GyNRk_oXKVgOZ4KFLAgkXLwjHYzDYsx8gcokLRrS0ZI,1247
10
+ knit_graphs/Course.py,sha256=oT-YghPdAg7A51GI_StdfF8oxYGWGkoad72woEkRKeY,5818
11
+ knit_graphs/Knit_Graph.py,sha256=KgcWQPzZJ-Iif7g3zWq6hBy4fdJXkJXnFxGOSMYOn-g,10795
12
+ knit_graphs/Knit_Graph_Visualizer.py,sha256=bbWl9iPQR93MtpWMPji4RTFR3Rgon0vzBlS11e2R8Zg,37925
13
+ knit_graphs/Loop.py,sha256=zp1ZiVRFSCPL2CnXNxgwNPv7WrcuqFRe3S_ZATxEBAo,5781
14
+ knit_graphs/Pull_Direction.py,sha256=8xRLN-j7V1mExgmt3YjcJcTDa5rLedA2bF4wI8gd-DE,2334
15
+ knit_graphs/Yarn.py,sha256=wNOmj15dnSA56Qw2D5ksgbmQqug-u5kPPxKGuitQ_qI,15901
16
+ knit_graphs/__init__.py,sha256=qzZAOxTqjgLkhoGnKNZwOkuYbKEyzfWKkKpKkV6lVfk,111
17
+ knit_graphs/_base_classes.py,sha256=ZEv_jkUglHzkfg-0TD6oonBq7QQmA4G7jrC_A6OubpY,6401
18
+ knit_graphs/artin_wale_braids/Crossing_Direction.py,sha256=71ckmEFfL0s25NJb8lfYwH2zku0uM1C5X9gGM7PYC5A,2820
19
+ knit_graphs/artin_wale_braids/Loop_Braid_Graph.py,sha256=2tsE16IzcvgsIKij1JNHWah6hLOgrpXCcjb6eocbfFs,4575
20
+ knit_graphs/artin_wale_braids/Wale.py,sha256=PK8IQDnTFXk5924QZYiGCqfckS62laG9_XhK7xH2zAo,7171
21
+ knit_graphs/artin_wale_braids/Wale_Braid.py,sha256=Ws0QmU7s63nrBKe69acDza-r-LozDyyaKVDNxQMy10Y,2662
22
+ knit_graphs/artin_wale_braids/Wale_Braid_Word.py,sha256=4YBlVMUZkqp85r46ETQSbFVS_WrT4PsWthHmFv5Ny9M,4587
23
+ knit_graphs/artin_wale_braids/Wale_Group.py,sha256=HTl01PHzFhInhFJuB30OScWx7pIejmo3-HwHN4RB4V4,6868
24
+ knit_graphs/artin_wale_braids/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
+ knit_graphs/basic_knit_graph_generators.py,sha256=_8CbtZ4M5NRp0mXXNdCNDPtIaCKEzmpAJQVNlmV5l8c,13893
26
+ knit_graphs-0.0.7.dist-info/LICENSE,sha256=Oazk3oiRu5ZN7b-EdYNYh0vu-I3Av2uIPQ-9L_cZ6Oo,1070
27
+ knit_graphs-0.0.7.dist-info/METADATA,sha256=YuT2TGLdupJYXAKbbC-pXi-z0fKbOelNz31STuy7tks,5188
28
+ knit_graphs-0.0.7.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
29
+ knit_graphs-0.0.7.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.24.2
2
+ Generator: poetry-core 1.8.1
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
knit_graphs/__about__.py DELETED
@@ -1,4 +0,0 @@
1
- # SPDX-FileCopyrightText: 2024-present m.hofmann <m.hofmann@northeastern.edu>
2
- #
3
- # SPDX-License-Identifier: MIT
4
- __version__ = "0.0.6"
File without changes
@@ -1,427 +0,0 @@
1
- import networkx
2
- import plotly.graph_objects as go
3
-
4
- from knit_graphs.Course import Course
5
- from knit_graphs.Knit_Graph import Knit_Graph
6
- from knit_graphs.Loop import Loop
7
- from knit_graphs.Pull_Direction import Pull_Direction
8
- from knit_graphs.artin_wale_braids.Crossing_Direction import Crossing_Direction
9
-
10
-
11
- def get_base_row_course_positions(course: Course, start_on_left: bool, loop_space: float = 1.0) -> tuple[dict[Loop, float], float, float]:
12
- """
13
- :param course: course assumed to be base of knit graph for visualization
14
- :param start_on_left: If True, loops will start on left side of plot
15
- :param loop_space: spacing between loops
16
- :return: dictionary of loops in course keyed to x position. The minimum loop position. The maximum loop position.
17
- """
18
- loops = course
19
- if not start_on_left:
20
- loops = reversed(course)
21
- positions = {l: x * loop_space for x, l in enumerate(loops)}
22
- return positions, min(positions.values()), max(positions.values())
23
-
24
-
25
- def get_base_round_course_positions(course: Course, start_on_left: bool,
26
- loop_space: float = 1.0, back_shift: float = 0.5) -> tuple[dict[Loop, float], dict[Loop, float], float, float]:
27
- """
28
- :param back_shift: Shift in x position for back bed loop s that can't be placed by float inference.
29
- :param course: Course assumed to be base of knit graph for visualization.
30
- :param start_on_left: If True, loops will start on the left side of plot.
31
- :param loop_space: Spacing between loops.
32
- :return: Dictionary of loops in front of the course keyed to x position.
33
- Dictionary of loops in the back of the course keyed to x position.
34
- Min loop position. Max loop position
35
- """
36
- split_index = int(len(course) / 2)
37
- front_loops = course[:split_index]
38
- back_loops = course[split_index:]
39
- if start_on_left:
40
- back_loops = reversed(back_loops)
41
- else:
42
- front_loops = reversed(back_loops)
43
- front_positions = {l: x * loop_space for x, l in enumerate(front_loops)}
44
- back_positions = {l: x * loop_space + back_shift for x, l in enumerate(back_loops)}
45
- for back_loop in back_loops:
46
- float_positions = [front_positions[fl] for fl in back_loop.front_floats if fl in front_positions]
47
- if len(float_positions) > 0:
48
- back_positions[back_loop] = sum(float_positions) / len(float_positions)
49
- min_front = min(front_positions.values())
50
- max_front = max(front_positions.values())
51
- min_back = min(back_positions.values())
52
- max_back = max(back_positions.values())
53
- return front_positions, back_positions, min(min_front, min_back), max(max_front, max_back)
54
-
55
-
56
- def get_loop_x_by_parent_average(data_graph: networkx.DiGraph, loop: Loop) -> float | None:
57
- """
58
- :param data_graph: Collection of loop nodes to assigned locations.
59
- :param loop: Loop to derive location for.
60
- :return: X position derived from parent_loop locations for loop.
61
- """
62
-
63
- def _parent_weight(stack_position):
64
- return len(loop.parent_loops) - stack_position
65
-
66
- parent_positions = {data_graph.nodes[p]['x'] * _parent_weight(sp): _parent_weight(sp)
67
- for sp, p in enumerate(loop.parent_loops)
68
- if p in data_graph.nodes}
69
- if len(parent_positions) == 0:
70
- return None
71
- return sum(parent_positions.keys()) / sum(parent_positions.values())
72
-
73
-
74
- def get_loop_x_by_yarn_neighbor_average(data_graph: networkx.DiGraph, loop: Loop, prior_space=1, next_space=-1) -> float | None:
75
- """
76
- :param data_graph: Collection of loop nodes to assigned locations.
77
- :param loop: Loop to place.
78
- :param prior_space: Spacing from this loop to prior on yarn.
79
- :param next_space: Spacing from this loop to next on yarn.
80
- :return: None if no neighbors are placed or assign x position by neighbors on yarn.
81
- """
82
- x_neighbors = []
83
- prior_loop = loop.prior_loop_on_yarn()
84
- next_loop = loop.next_loop_on_yarn()
85
- if prior_loop is not None and prior_loop in data_graph.nodes:
86
- x_neighbors.append(data_graph.nodes[prior_loop]['x'] + prior_space)
87
- if next_loop is not None and next_loop in data_graph.nodes:
88
- x_neighbors.append(data_graph.nodes[next_loop]['x'] + next_space)
89
- return sum(x_neighbors) / len(x_neighbors)
90
-
91
-
92
- def re_balance_course(data_graph: networkx.DiGraph, course: Course, target_width: float | None,
93
- left_side: float = 0, right_side: float | None = None) -> dict[Loop, float]:
94
- """
95
- :param target_width: Width to retarget to. Defaults to definition from right side value.
96
- :param data_graph: Collection of loop nodes to assign locations.
97
- :param course: The course to re-balance.
98
- :param left_side: The minimum left position of the course.
99
- :param right_side: The maximum right position of the course. Defaults to right most loop position.
100
- :return: Dictionary of loops to rebalanced positions.
101
- Maintains original float proportions of each loop but assigns positions between left and right side values.
102
- """
103
- min_x, min_loop = min_x_in_course(course, data_graph)
104
- max_x, max_loop = max_x_in_course(course, data_graph)
105
- course_width = max_x - min_x
106
- if target_width is None:
107
- if right_side is None:
108
- right_side = max_x
109
- target_width = right_side - left_side
110
-
111
- def _target_float_size(u, v) -> float:
112
- current_size = abs(data_graph.nodes[u]['x'] - data_graph.nodes[v]['x'])
113
- return (current_size * target_width) / course_width
114
-
115
- return {l: _target_float_size(min_loop, l) + left_side for l in course}
116
-
117
-
118
- def max_x_in_course(course, data_graph) -> tuple[float, Loop]:
119
- """
120
- :param course:
121
- :param data_graph:
122
- :return: right most x position in course, loop with right most x position
123
- """
124
- return max([(data_graph.nodes[l]['x'], l) for l in course], key=lambda tup: tup[0])
125
-
126
-
127
- def min_x_in_course(course, data_graph) -> tuple[float, Loop]:
128
- """
129
- :param course:
130
- :param data_graph:
131
- :return: left most x position in course, loop with left most x position
132
- """
133
- return min([(data_graph.nodes[l]['x'], l) for l in course], key=lambda tup: tup[0])
134
-
135
-
136
- def get_loop_y_by_neighbor_floats(data_graph: networkx.DiGraph, loop: Loop, float_buffer: float = 0.25) -> float | None:
137
- """
138
- :param data_graph: Collection of loop nodes to assign locations.
139
- :param loop: Loop to assign y location by neighboring floats.
140
- :param float_buffer: Spacing between loop and its neighboring floats.
141
- :return: Y position of loop or None if loop has no neighboring floats.
142
- """
143
- positions = [data_graph.nodes[fl]['y'] + float_buffer for fl in loop.front_floats if fl in data_graph.nodes]
144
- positions.extend([data_graph.nodes[bl]['y'] - float_buffer for bl in loop.back_floats if bl in data_graph.nodes])
145
- if len(positions) == 0:
146
- return None
147
- return sum(positions) / len(positions)
148
-
149
-
150
- def shift_purls(knit_graph: Knit_Graph, data_graph: networkx.DiGraph, purl_shift: float = 0.25):
151
- shifted = set()
152
- for u, v in knit_graph.stitch_graph.edges:
153
- if v not in shifted:
154
- pull_direction = knit_graph.stitch_graph[u][v]['pull_direction']
155
- if pull_direction is Pull_Direction.FtB:
156
- data_graph.nodes[v]['x'] += purl_shift
157
- shifted.add(v)
158
- if len(u.parent_loops) == 0: # purl coming from yarn over
159
- data_graph.nodes[u]['x'] += purl_shift
160
- shifted.add(u)
161
-
162
-
163
- def visualize_stitches(knit_graph: Knit_Graph,
164
- first_course_index: int = 0, top_course_index: int | None = None,
165
- start_on_left: bool = True,
166
- re_balance_to_course_width=False,
167
- re_balance_to_base_width=False,
168
- left_zero_align=True,
169
- graph_title: str = "knit_graph"):
170
- data_graph = position_loops(first_course_index, knit_graph, left_zero_align, re_balance_to_base_width, re_balance_to_course_width, start_on_left, top_course_index)
171
-
172
- yarn_loop_traces = collect_yarn_loop_traces(data_graph, knit_graph)
173
-
174
- yarn_float_traces = collect_yarn_float_traces(data_graph, knit_graph)
175
-
176
- def _new_edge_data():
177
- return {'x': [], 'y': [], 'edge': [], 'is_start': []}
178
-
179
- def _add_edge_data(edge_data: dict[str, list], u_loop: Loop, v_loop: Loop):
180
- data_graph.add_edge(u_loop, v_loop, pull_direction=pull_direction)
181
- edge_data['x'].append(data_graph.nodes[u_loop]['x'])
182
- edge_data['y'].append(data_graph.nodes[u_loop]['y'])
183
- edge_data['edge'].append((u_loop, v_loop))
184
- edge_data['is_start'].append(True)
185
- edge_data['x'].append(data_graph.nodes[v_loop]['x'])
186
- edge_data['y'].append(data_graph.nodes[v_loop]['y'])
187
- edge_data['edge'].append((u_loop, v_loop))
188
- edge_data['is_start'].append(False)
189
- edge_data['x'].append(None)
190
- edge_data['y'].append(None)
191
-
192
- top_knit_data = _new_edge_data()
193
- bot_knit_data = _new_edge_data()
194
- top_purl_data = _new_edge_data()
195
- bot_purl_data = _new_edge_data()
196
- no_cross_knit_data = _new_edge_data()
197
- no_cross_purl_data = _new_edge_data()
198
-
199
- for left_loop, right_loop in knit_graph.braid_graph.loop_crossing_graph.edges:
200
- crossing_direction = knit_graph.braid_graph.get_crossing(left_loop, right_loop)
201
- for left_parent in left_loop.parent_loops:
202
- pull_direction: Pull_Direction = knit_graph.stitch_graph[left_parent][left_loop]['pull_direction']
203
- data_graph.add_edge(left_parent, left_loop, pull_direction=pull_direction)
204
- if pull_direction is Pull_Direction.BtF: # knit
205
- if crossing_direction is Crossing_Direction.Over_Right:
206
- data = top_knit_data
207
- elif crossing_direction is Crossing_Direction.Under_Right:
208
- data = bot_knit_data
209
- else:
210
- data = no_cross_knit_data
211
- else:
212
- if crossing_direction is Crossing_Direction.Over_Right:
213
- data = top_purl_data
214
- elif crossing_direction is Crossing_Direction.Under_Right:
215
- data = bot_purl_data
216
- else:
217
- data = no_cross_knit_data
218
- _add_edge_data(data, left_parent, left_loop)
219
- for right_parent in right_loop.parent_loops:
220
- pull_direction: Pull_Direction = knit_graph.stitch_graph[right_parent][right_loop]['pull_direction']
221
- data_graph.add_edge(right_parent, right_loop, pull_direction=pull_direction)
222
- if pull_direction is Pull_Direction.BtF: # knit
223
- if crossing_direction is Crossing_Direction.Under_Right:
224
- data = top_knit_data
225
- elif crossing_direction is Crossing_Direction.Over_Right:
226
- data = bot_knit_data
227
- else:
228
- data = no_cross_knit_data
229
- else:
230
- if crossing_direction is Crossing_Direction.Under_Right:
231
- data = top_purl_data
232
- elif crossing_direction is Crossing_Direction.Over_Right:
233
- data = bot_purl_data
234
- else:
235
- data = no_cross_purl_data
236
- _add_edge_data(data, right_parent, right_loop)
237
-
238
- for u, v in knit_graph.stitch_graph.edges:
239
- if not data_graph.has_edge(u, v):
240
- pull_direction: Pull_Direction = knit_graph.stitch_graph[u][v]['pull_direction']
241
- if pull_direction is Pull_Direction.BtF: # knit
242
- _add_edge_data(no_cross_knit_data, u, v)
243
- else:
244
- _add_edge_data(no_cross_purl_data, u, v)
245
-
246
- no_cross_knit_trace = go.Scatter(name="Knit Stitches (No Crossing)",
247
- x=no_cross_knit_data['x'], y=no_cross_knit_data['y'],
248
- line=dict(width=4, color='blue', dash='solid'),
249
- opacity=0.8,
250
- mode='lines')
251
- top_knit_trace = go.Scatter(name="Knit Stitches (Crossing Over)",
252
- x=top_knit_data['x'], y=top_knit_data['y'],
253
- line=dict(width=5, color='blue', dash='solid'),
254
- opacity=1,
255
- mode='lines')
256
- bot_knit_trace = go.Scatter(name="Knit Stitches (Crossing Under)",
257
- x=bot_knit_data['x'], y=bot_knit_data['y'],
258
- line=dict(width=3, color='blue', dash='dash'),
259
- opacity=.5,
260
- mode='lines')
261
- no_cross_purl_trace = go.Scatter(name="Purl Stitches",
262
- x=no_cross_purl_data['x'], y=no_cross_purl_data['y'],
263
- line=dict(width=4, color='red', dash='solid'),
264
- opacity=0.8,
265
- mode='lines')
266
- top_purl_trace = go.Scatter(name="Purl Stitches (Crossing Over)",
267
- x=top_purl_data['x'], y=top_knit_data['y'],
268
- line=dict(width=5, color='red', dash='solid'),
269
- opacity=1,
270
- mode='lines')
271
- bot_purl_trace = go.Scatter(name="Purl Stitches (Crossing Under)",
272
- x=bot_purl_data['x'], y=bot_purl_data['y'],
273
- line=dict(width=3, color='red', dash='dash'),
274
- opacity=.5,
275
- mode='lines')
276
-
277
- go_layout = go.Layout(title=graph_title,
278
- showlegend=True,
279
- hovermode='closest',
280
- margin=dict(b=20, l=5, r=5, t=40)
281
- )
282
- figure_data = [top_knit_trace, top_purl_trace,
283
- no_cross_knit_trace, no_cross_purl_trace,
284
- bot_knit_trace, bot_purl_trace]
285
- figure_data.extend(yarn_float_traces)
286
- figure_data.extend(yarn_loop_traces)
287
- fig = go.Figure(data=figure_data,
288
- layout=go_layout
289
- )
290
- fig.show()
291
-
292
-
293
- def position_loops(first_course_index, knit_graph, left_zero_align, re_balance_to_base_width, re_balance_to_course_width,
294
- start_on_left, top_course_index):
295
- data_graph = networkx.DiGraph()
296
- courses = knit_graph.get_courses()
297
- loops_to_course = {}
298
- if top_course_index is not None:
299
- courses = courses[:top_course_index]
300
- base_course = courses[first_course_index]
301
- for loop in base_course:
302
- loops_to_course[loop] = base_course
303
- if len(courses) > first_course_index + 1 and base_course.in_round_with(courses[first_course_index + 1]):
304
- front_positions, back_positions, min_x, max_x = get_base_round_course_positions(base_course, start_on_left)
305
- for loop, x in front_positions.items():
306
- data_graph.add_node(loop, x=x, y=0)
307
- for loop, x in back_positions.items():
308
- # y = get_loop_y_by_neighbor_floats(data_graph, loop)
309
- # if y is None:
310
- # y = .25
311
- data_graph.add_node(loop, x=x, y=0)
312
- else:
313
- positions, min_x, max_x = get_base_row_course_positions(base_course, start_on_left)
314
- for loop, x in positions.items():
315
- data_graph.add_node(loop, x=x, y=0)
316
- base_width = max_x - min_x
317
- y = 1
318
- for course in courses[first_course_index + 1:]:
319
- need_x_placement = {}
320
- for x, loop in enumerate(course):
321
- loops_to_course[loop] = course
322
- parent_average_x = get_loop_x_by_parent_average(data_graph, loop)
323
- if parent_average_x is None:
324
- need_x_placement[loop] = x
325
- else:
326
- x = parent_average_x
327
- # float_placed_y = get_loop_y_by_neighbor_floats(data_graph, loop)
328
- # if float_placed_y is not None:
329
- # y = float_placed_y
330
- data_graph.add_node(loop, x=x, y=y)
331
- for loop in need_x_placement.keys():
332
- neighbor_based_x = get_loop_x_by_yarn_neighbor_average(data_graph, loop)
333
- if neighbor_based_x is not None:
334
- data_graph.nodes[loop]['x'] = neighbor_based_x
335
- # swap x positions based on cable crossings
336
- for left_loop in course:
337
- for right_loop in knit_graph.braid_graph.left_crossing_loops(left_loop):
338
- crossing_direction = knit_graph.braid_graph.get_crossing(left_loop, right_loop)
339
- if crossing_direction is not Crossing_Direction.No_Cross:
340
- left_x = data_graph.nodes[left_loop]['x']
341
- data_graph.nodes[left_loop]['x'] = data_graph.nodes[right_loop]['x']
342
- data_graph.nodes[right_loop]['x'] = left_x
343
- new_positions = {}
344
- left_side = 0
345
- if not left_zero_align:
346
- left_side, left_loop = min_x_in_course(course, data_graph)
347
- if re_balance_to_course_width:
348
- new_positions = re_balance_course(data_graph, course, len(course) - 1, left_side)
349
- elif re_balance_to_base_width:
350
- new_positions = re_balance_course(data_graph, course, base_width, left_side)
351
- for l, x in new_positions.items():
352
- data_graph.nodes[l]['x'] = x
353
- y += 1
354
- adjust_y_positions_by_float_alignment(data_graph, knit_graph, loops_to_course)
355
- shift_purls(knit_graph, data_graph)
356
- return data_graph
357
-
358
-
359
- def adjust_y_positions_by_float_alignment(data_graph, knit_graph, loops_to_course, float_increment: float = 0.25):
360
- for yarn in knit_graph.yarns:
361
- for u, v, front_loops in yarn.loops_in_front_of_floats():
362
- for fl in front_loops:
363
- fl_course = loops_to_course[fl]
364
- if u in fl_course and v in fl_course: # same course, adjust float position
365
- data_graph.nodes[fl]['y'] -= float_increment
366
- for u, v, back_loops in yarn.loops_behind_floats():
367
- for bl in back_loops:
368
- bl_course = loops_to_course[bl]
369
- if u in bl_course and v in bl_course: # same course, adjust float position
370
- data_graph.nodes[bl]['y'] += float_increment
371
-
372
-
373
- def collect_yarn_float_traces(data_graph, knit_graph):
374
- """
375
- :param data_graph: Collection of loop nodes to assign locations.
376
- :param knit_graph: The knit graph to derive loop data from.
377
- :return: The traces of the yarns-loop nodes for the graph
378
- """
379
- yarns_to_float_data = {}
380
- for y in knit_graph.yarns.values():
381
- float_data = {'x': [], 'y': []}
382
- for u, v in y.loop_graph.edges:
383
- float_data['x'].append(data_graph.nodes[u]['x'])
384
- float_data['y'].append(data_graph.nodes[u]['y'])
385
- float_data['x'].append(data_graph.nodes[v]['x'])
386
- float_data['y'].append(data_graph.nodes[v]['y'])
387
- yarns_to_float_data[y] = float_data
388
- for y in knit_graph.yarns.values():
389
- float_data = {'x': [], 'y': []}
390
- for u in y.loop_graph.nodes:
391
- float_data['x'].append(data_graph.nodes[u]['x'])
392
- float_data['y'].append(data_graph.nodes[u]['y'])
393
- yarns_to_float_data[y] = float_data
394
- yarn_float_traces = [go.Scatter(name=y.yarn_id,
395
- x=fd['x'], y=fd['y'],
396
- line=dict(width=1,
397
- color=y.properties.color,
398
- shape='spline',
399
- smoothing=1.3),
400
- mode='lines')
401
- for y, fd in yarns_to_float_data.items()]
402
- return yarn_float_traces
403
-
404
-
405
- def collect_yarn_loop_traces(data_graph, knit_graph):
406
- """
407
- :param data_graph: Collection of loop nodes to assign locations.
408
- :param knit_graph: The knit graph to derive loop data from.
409
- :return: The traces of the yarns-float edges for the graph
410
- """
411
- yarns_to_loop_data = {y: {'x': [data_graph.nodes[l]['x'] for l in y],
412
- 'y': [data_graph.nodes[l]['y'] for l in y],
413
- 'loop_id': [l.loop_id for l in y]
414
- }
415
- for y in knit_graph.yarns
416
- }
417
- yarn_loop_traces = [go.Scatter(name=f"Loops on {y.yarn_id}", x=yd['x'], y=yd['y'], text=yd['loop_id'],
418
- textposition='middle center',
419
- mode='markers+text',
420
- marker=dict(
421
- reversescale=True,
422
- color=y.properties.color,
423
- size=30,
424
- line_width=2, ))
425
- for y, yd in yarns_to_loop_data.items()
426
- ]
427
- return yarn_loop_traces
File without changes
@@ -1,22 +0,0 @@
1
- knit_graphs/Course.py,sha256=gEIl9EXXCx3NfEQclhK_7WGVOK_rxF5hB0jqGeAyH_w,3437
2
- knit_graphs/Knit_Graph.py,sha256=arRNaxUaV3uwgNJ_UKxS7zViHl46y5QErPM_vTA_q8Y,7753
3
- knit_graphs/Loop.py,sha256=S2YGS8f_CtbFzy-OJsY6_JzGaHiiVMXrROO6P-wByTo,5236
4
- knit_graphs/Pull_Direction.py,sha256=G2JLbUT8x-ZfLNX3yjslv61FaoZiODUOPyYeDqj3pqQ,596
5
- knit_graphs/Yarn.py,sha256=9FOEBnWbtI8VJ-b1-NL0e8bsXuT0Jg0HG90jWEflUxw,9230
6
- knit_graphs/__about__.py,sha256=f6QbNB-h7iIziTm9pqa987kBoY_CelBN7KwRBZHwZck,137
7
- knit_graphs/__init__.py,sha256=bPQ_U3Sf5VvF36ywW6v79_J51b7DdZPvXuaHAtlbmg4,114
8
- knit_graphs/artin_wale_braids/Crossing_Direction.py,sha256=YVYfv11V-mB9WmQzNuOjbEQQI-b07gl9KF31vwujb1g,430
9
- knit_graphs/artin_wale_braids/Loop_Braid_Graph.py,sha256=z9_VyQA5U9y-XjyaZ67kSmOr0Bg_N1932ghV3YzNrP0,2742
10
- knit_graphs/artin_wale_braids/Wale.py,sha256=ldXVbb8cAe5QSoZNRxmdyrncnMYp6S0NnRpdJU6QQM4,3597
11
- knit_graphs/artin_wale_braids/Wale_Braid.py,sha256=9xCE0i0FoHN9J4CA_PZOoVIeLDHhIY3vC7LyK8OVkfk,1348
12
- knit_graphs/artin_wale_braids/Wale_Braid_Word.py,sha256=K17E-oRRsKYDrSWqwP1WMqR2MnK8nTNoSqaD73gtX6Y,1844
13
- knit_graphs/artin_wale_braids/Wale_Group.py,sha256=e5YTNiHditg4sSq-1lMAdmeIwIEHX4JKEiEx5X4nwZg,3718
14
- knit_graphs/artin_wale_braids/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
- knit_graphs/knit_graph_generators/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
- knit_graphs/knit_graph_generators/basic_knit_graph_generators.py,sha256=eRmoqIhjymKERJhjnwuQll3psAf9HHwnHWDkTcZX6Uk,11330
17
- knit_graphs/knit_graph_visualizer/Stitch_Visualizer.py,sha256=l90bdaucCDzSmua7iILoNmpVQuQsuMKHq5r0DkakoL0,21411
18
- knit_graphs/knit_graph_visualizer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
- knit_graphs-0.0.6.dist-info/METADATA,sha256=Mn0jZgvr2WWltpSizNu3mJS-7SPTehGQ6vlXM3I9UNY,5039
20
- knit_graphs-0.0.6.dist-info/WHEEL,sha256=zEMcRr9Kr03x1ozGwg5v9NQBKn3kndp6LSoSlVg-jhU,87
21
- knit_graphs-0.0.6.dist-info/licenses/LICENSE,sha256=M4U6L5axKj_93OoQXCm4RUIsUwHqEVzf7hsOVmyFPp0,1091
22
- knit_graphs-0.0.6.dist-info/RECORD,,