knit-graphs 0.0.6__py3-none-any.whl → 0.0.8__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.
- knit_graphs-0.0.6.dist-info/licenses/LICENSE → LICENSE +21 -21
- README.md +75 -0
- docs/Makefile +20 -0
- docs/make.bat +35 -0
- docs/source/api/knit_graphs.Course.rst +7 -0
- docs/source/api/knit_graphs.Knit_Graph.rst +7 -0
- docs/source/api/knit_graphs.Knit_Graph_Visualizer.rst +7 -0
- docs/source/api/knit_graphs.Loop.rst +7 -0
- docs/source/api/knit_graphs.Pull_Direction.rst +7 -0
- docs/source/api/knit_graphs.Yarn.rst +7 -0
- docs/source/api/knit_graphs.artin_wale_braids.Crossing_Direction.rst +7 -0
- docs/source/api/knit_graphs.artin_wale_braids.Loop_Braid_Graph.rst +7 -0
- docs/source/api/knit_graphs.artin_wale_braids.Wale.rst +7 -0
- docs/source/api/knit_graphs.artin_wale_braids.Wale_Braid.rst +7 -0
- docs/source/api/knit_graphs.artin_wale_braids.Wale_Braid_Word.rst +7 -0
- docs/source/api/knit_graphs.artin_wale_braids.Wale_Group.rst +7 -0
- docs/source/api/knit_graphs.artin_wale_braids.rst +23 -0
- docs/source/api/knit_graphs.basic_knit_graph_generators.rst +7 -0
- docs/source/api/knit_graphs.rst +32 -0
- docs/source/conf.py +335 -0
- docs/source/index.rst +71 -0
- docs/source/installation.rst +67 -0
- knit_graphs/Course.py +156 -104
- knit_graphs/Knit_Graph.py +249 -186
- knit_graphs/Knit_Graph_Visualizer.py +675 -0
- knit_graphs/Loop.py +141 -155
- knit_graphs/Pull_Direction.py +68 -23
- knit_graphs/Yarn.py +424 -267
- knit_graphs/__init__.py +3 -3
- knit_graphs/_base_classes.py +173 -0
- knit_graphs/artin_wale_braids/Crossing_Direction.py +74 -15
- knit_graphs/artin_wale_braids/Loop_Braid_Graph.py +95 -62
- knit_graphs/artin_wale_braids/Wale.py +169 -93
- knit_graphs/artin_wale_braids/Wale_Braid.py +50 -30
- knit_graphs/artin_wale_braids/Wale_Braid_Word.py +99 -54
- knit_graphs/artin_wale_braids/Wale_Group.py +136 -88
- knit_graphs/basic_knit_graph_generators.py +251 -0
- knit_graphs-0.0.8.dist-info/LICENSE +21 -0
- {knit_graphs-0.0.6.dist-info → knit_graphs-0.0.8.dist-info}/METADATA +33 -24
- knit_graphs-0.0.8.dist-info/RECORD +42 -0
- {knit_graphs-0.0.6.dist-info → knit_graphs-0.0.8.dist-info}/WHEEL +1 -1
- knit_graphs/__about__.py +0 -4
- knit_graphs/knit_graph_generators/__init__.py +0 -0
- knit_graphs/knit_graph_generators/basic_knit_graph_generators.py +0 -248
- knit_graphs/knit_graph_visualizer/Stitch_Visualizer.py +0 -427
- knit_graphs/knit_graph_visualizer/__init__.py +0 -0
- knit_graphs-0.0.6.dist-info/RECORD +0 -22
|
@@ -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,,
|