knit-graphs 0.0.8__py3-none-any.whl → 0.0.9__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/Course.py +24 -5
- knit_graphs/Knit_Graph.py +37 -14
- knit_graphs/Loop.py +62 -12
- knit_graphs/Yarn.py +12 -9
- knit_graphs/artin_wale_braids/Wale.py +3 -4
- knit_graphs/artin_wale_braids/Wale_Group.py +7 -5
- {knit_graphs-0.0.8.dist-info → knit_graphs-0.0.9.dist-info}/METADATA +4 -4
- {knit_graphs-0.0.8.dist-info → knit_graphs-0.0.9.dist-info}/RECORD +10 -11
- knit_graphs/_base_classes.py +0 -173
- {knit_graphs-0.0.8.dist-info → knit_graphs-0.0.9.dist-info}/LICENSE +0 -0
- {knit_graphs-0.0.8.dist-info → knit_graphs-0.0.9.dist-info}/WHEEL +0 -0
knit_graphs/Course.py
CHANGED
|
@@ -4,11 +4,13 @@ This module contains the Course class which represents a horizontal row of loops
|
|
|
4
4
|
"""
|
|
5
5
|
from __future__ import annotations
|
|
6
6
|
|
|
7
|
-
from typing import Iterator, cast
|
|
7
|
+
from typing import TYPE_CHECKING, Iterator, cast
|
|
8
8
|
|
|
9
|
-
from knit_graphs._base_classes import _Base_Knit_Graph
|
|
10
9
|
from knit_graphs.Loop import Loop
|
|
11
10
|
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from knit_graphs.Knit_Graph import Knit_Graph
|
|
13
|
+
|
|
12
14
|
|
|
13
15
|
class Course:
|
|
14
16
|
"""Course object for organizing loops into knitting rows.
|
|
@@ -17,15 +19,32 @@ class Course:
|
|
|
17
19
|
It maintains an ordered list of loops and provides methods for analyzing the structure and relationships between courses in the knitted fabric.
|
|
18
20
|
"""
|
|
19
21
|
|
|
20
|
-
def __init__(self,
|
|
22
|
+
def __init__(self, knit_graph: Knit_Graph) -> None:
|
|
21
23
|
"""Initialize an empty course associated with a knit graph.
|
|
22
24
|
|
|
23
25
|
Args:
|
|
24
|
-
|
|
26
|
+
knit_graph (Knit_Graph): The knit graph that this course belongs to.
|
|
25
27
|
"""
|
|
26
|
-
self.
|
|
28
|
+
self._knit_graph: Knit_Graph = knit_graph
|
|
29
|
+
self._loops_in_order: list[Loop] = []
|
|
27
30
|
self._loop_set: set[Loop] = set()
|
|
28
31
|
|
|
32
|
+
@property
|
|
33
|
+
def loops_in_order(self) -> list[Loop]:
|
|
34
|
+
"""
|
|
35
|
+
Returns:
|
|
36
|
+
list[Loop]: The list of loops in this course.
|
|
37
|
+
"""
|
|
38
|
+
return self._loops_in_order
|
|
39
|
+
|
|
40
|
+
@property
|
|
41
|
+
def knit_graph(self) -> Knit_Graph:
|
|
42
|
+
"""
|
|
43
|
+
Returns:
|
|
44
|
+
Knit_Graph: The knit graph that this course belongs to.
|
|
45
|
+
"""
|
|
46
|
+
return self._knit_graph
|
|
47
|
+
|
|
29
48
|
def add_loop(self, loop: Loop, index: int | None = None) -> None:
|
|
30
49
|
"""Add a loop to the course at the specified index or at the end.
|
|
31
50
|
|
knit_graphs/Knit_Graph.py
CHANGED
|
@@ -5,9 +5,10 @@ It manages the relationships between loops, yarns, and structural elements like
|
|
|
5
5
|
"""
|
|
6
6
|
from __future__ import annotations
|
|
7
7
|
|
|
8
|
-
from typing import Any, cast
|
|
8
|
+
from typing import Any, Iterator, cast
|
|
9
|
+
|
|
10
|
+
from networkx import DiGraph
|
|
9
11
|
|
|
10
|
-
from knit_graphs._base_classes import _Base_Knit_Graph
|
|
11
12
|
from knit_graphs.artin_wale_braids.Crossing_Direction import Crossing_Direction
|
|
12
13
|
from knit_graphs.artin_wale_braids.Loop_Braid_Graph import Loop_Braid_Graph
|
|
13
14
|
from knit_graphs.artin_wale_braids.Wale import Wale
|
|
@@ -17,8 +18,11 @@ from knit_graphs.Loop import Loop
|
|
|
17
18
|
from knit_graphs.Pull_Direction import Pull_Direction
|
|
18
19
|
from knit_graphs.Yarn import Yarn
|
|
19
20
|
|
|
21
|
+
# from knit_graphs.artin_wale_braids.Wale import Wale
|
|
22
|
+
# from knit_graphs.artin_wale_braids.Wale_Group import Wale_Group
|
|
23
|
+
|
|
20
24
|
|
|
21
|
-
class Knit_Graph
|
|
25
|
+
class Knit_Graph:
|
|
22
26
|
"""A representation of knitted structures as connections between loops on yarns.
|
|
23
27
|
|
|
24
28
|
The Knit_Graph class is the main data structure for representing knitted fabrics.
|
|
@@ -28,7 +32,7 @@ class Knit_Graph(_Base_Knit_Graph):
|
|
|
28
32
|
|
|
29
33
|
def __init__(self) -> None:
|
|
30
34
|
"""Initialize an empty knit graph with no loops or yarns."""
|
|
31
|
-
|
|
35
|
+
self.stitch_graph: DiGraph = DiGraph()
|
|
32
36
|
self.braid_graph: Loop_Braid_Graph = Loop_Braid_Graph()
|
|
33
37
|
self._last_loop: None | Loop = None
|
|
34
38
|
self.yarns: set[Yarn] = set()
|
|
@@ -69,7 +73,7 @@ class Knit_Graph(_Base_Knit_Graph):
|
|
|
69
73
|
"""
|
|
70
74
|
self.stitch_graph.add_node(loop)
|
|
71
75
|
if loop.yarn not in self.yarns:
|
|
72
|
-
self.add_yarn(
|
|
76
|
+
self.add_yarn(loop.yarn)
|
|
73
77
|
if self._last_loop is None or loop > self._last_loop:
|
|
74
78
|
self._last_loop = loop
|
|
75
79
|
|
|
@@ -129,12 +133,14 @@ class Knit_Graph(_Base_Knit_Graph):
|
|
|
129
133
|
list[Wale]: The set of wales that end at this loop. Only returns multiple wales if this loop is a child of a decrease stitch.
|
|
130
134
|
"""
|
|
131
135
|
wales = []
|
|
132
|
-
|
|
136
|
+
if len(last_loop.parent_loops) == 0:
|
|
137
|
+
return [Wale(last_loop)]
|
|
138
|
+
for top_stitch_parent in last_loop.parent_loops:
|
|
133
139
|
wale = Wale(last_loop)
|
|
134
140
|
wale.add_loop_to_beginning(top_stitch_parent, cast(Pull_Direction, self.get_pull_direction(top_stitch_parent, last_loop)))
|
|
135
141
|
cur_loop = top_stitch_parent
|
|
136
142
|
while len(cur_loop.parent_loops) == 1: # stop at split for decrease or start of wale
|
|
137
|
-
cur_loop =
|
|
143
|
+
cur_loop = cur_loop.parent_loops[0]
|
|
138
144
|
wale.add_loop_to_beginning(cur_loop, cast(Pull_Direction, self.get_pull_direction(cur_loop, cast(Loop, wale.first_loop))))
|
|
139
145
|
wales.append(wale)
|
|
140
146
|
return wales
|
|
@@ -148,8 +154,8 @@ class Knit_Graph(_Base_Knit_Graph):
|
|
|
148
154
|
"""
|
|
149
155
|
courses = []
|
|
150
156
|
course = Course(self)
|
|
151
|
-
for loop in
|
|
152
|
-
for parent in
|
|
157
|
+
for loop in self.sorted_loops():
|
|
158
|
+
for parent in loop.parent_loops:
|
|
153
159
|
if parent in course: # start a new course
|
|
154
160
|
courses.append(course)
|
|
155
161
|
course = Course(self)
|
|
@@ -165,21 +171,38 @@ class Knit_Graph(_Base_Knit_Graph):
|
|
|
165
171
|
dict[Loop, Wale_Group]: Dictionary mapping terminal loops to the wale groups they terminate. Each wale group represents a collection of wales that end at the same terminal loop.
|
|
166
172
|
"""
|
|
167
173
|
wale_groups = {}
|
|
168
|
-
for loop in self
|
|
174
|
+
for loop in self:
|
|
169
175
|
if self.is_terminal_loop(loop):
|
|
170
176
|
wale_groups.update({loop: Wale_Group(wale, self) for wale in self.get_wales_ending_with_loop(loop)})
|
|
171
177
|
return wale_groups
|
|
172
178
|
|
|
173
|
-
def __contains__(self, item: Loop) -> bool:
|
|
179
|
+
def __contains__(self, item: Loop | tuple[Loop, Loop]) -> bool:
|
|
174
180
|
"""Check if a loop is contained in the knit graph.
|
|
175
181
|
|
|
176
182
|
Args:
|
|
177
|
-
item (Loop): The loop being checked for in the graph.
|
|
183
|
+
item (Loop | tuple[Loop, Loop]): The loop being checked for in the graph or the parent-child stitch edge to check for in the knit graph.
|
|
184
|
+
|
|
185
|
+
Returns:
|
|
186
|
+
bool: True if the given loop or stitch edge is in the graph, False otherwise.
|
|
187
|
+
"""
|
|
188
|
+
if isinstance(item, Loop):
|
|
189
|
+
return bool(self.stitch_graph.has_node(item))
|
|
190
|
+
else:
|
|
191
|
+
return bool(self.stitch_graph.has_edge(item[0], item[1]))
|
|
178
192
|
|
|
193
|
+
def __iter__(self) -> Iterator[Loop]:
|
|
194
|
+
"""
|
|
195
|
+
Returns:
|
|
196
|
+
Iterator[Loop]: An iterator over all loops in the knit graph.
|
|
197
|
+
"""
|
|
198
|
+
return cast(Iterator[Loop], iter(self.stitch_graph.nodes))
|
|
199
|
+
|
|
200
|
+
def sorted_loops(self) -> list[Loop]:
|
|
201
|
+
"""
|
|
179
202
|
Returns:
|
|
180
|
-
|
|
203
|
+
list[Loop]: The list of loops in the stitch graph sorted from the earliest formed loop to the latest formed loop.
|
|
181
204
|
"""
|
|
182
|
-
return
|
|
205
|
+
return sorted(list(self.stitch_graph.nodes))
|
|
183
206
|
|
|
184
207
|
def get_pull_direction(self, parent: Loop, child: Loop) -> Pull_Direction | None:
|
|
185
208
|
"""Get the pull direction of the stitch edge between parent and child loops.
|
knit_graphs/Loop.py
CHANGED
|
@@ -5,12 +5,13 @@ Loops are the fundamental building blocks of knitted structures and maintain rel
|
|
|
5
5
|
"""
|
|
6
6
|
from __future__ import annotations
|
|
7
7
|
|
|
8
|
-
from typing import cast
|
|
8
|
+
from typing import TYPE_CHECKING, cast
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from knit_graphs.Yarn import Yarn
|
|
11
12
|
|
|
12
13
|
|
|
13
|
-
class Loop
|
|
14
|
+
class Loop:
|
|
14
15
|
"""A class to represent a single loop structure for modeling a single loop in a knitting pattern.
|
|
15
16
|
|
|
16
17
|
The Loop class manages yarn relationships, parent-child connections for stitches, and float positioning for complex knitting structures.
|
|
@@ -23,15 +24,17 @@ class Loop(_Base_Loop):
|
|
|
23
24
|
back_floats (dict[Loop, set[Loop]]): A dictionary tracking loops that this loop floats behind.
|
|
24
25
|
"""
|
|
25
26
|
|
|
26
|
-
def __init__(self, loop_id: int, yarn:
|
|
27
|
+
def __init__(self, loop_id: int, yarn: Yarn) -> None:
|
|
27
28
|
"""Construct a Loop object with the specified identifier and yarn.
|
|
28
29
|
|
|
29
30
|
Args:
|
|
30
31
|
loop_id (int): A unique identifier for the loop, must be non-negative.
|
|
31
|
-
yarn (
|
|
32
|
+
yarn (Yarn): The yarn that creates and holds this loop.
|
|
32
33
|
"""
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
if loop_id < 0:
|
|
35
|
+
raise ValueError(f"Loop identifier must be non-negative but got {loop_id}")
|
|
36
|
+
self._loop_id: int = loop_id
|
|
37
|
+
self.yarn: Yarn = yarn
|
|
35
38
|
self.parent_loops: list[Loop] = []
|
|
36
39
|
self.front_floats: dict[Loop, set[Loop]] = {}
|
|
37
40
|
self.back_floats: dict[Loop, set[Loop]] = {}
|
|
@@ -102,7 +105,7 @@ class Loop(_Base_Loop):
|
|
|
102
105
|
if loop is None:
|
|
103
106
|
return None
|
|
104
107
|
else:
|
|
105
|
-
return
|
|
108
|
+
return loop
|
|
106
109
|
|
|
107
110
|
def next_loop_on_yarn(self) -> Loop:
|
|
108
111
|
"""Get the loop that follows this loop on the same yarn.
|
|
@@ -132,10 +135,57 @@ class Loop(_Base_Loop):
|
|
|
132
135
|
else:
|
|
133
136
|
self.parent_loops.append(parent)
|
|
134
137
|
|
|
135
|
-
|
|
136
|
-
|
|
138
|
+
@property
|
|
139
|
+
def loop_id(self) -> int:
|
|
140
|
+
"""Get the unique identifier of this loop.
|
|
137
141
|
|
|
138
142
|
Returns:
|
|
139
|
-
|
|
143
|
+
int: The id of the loop.
|
|
140
144
|
"""
|
|
141
|
-
return
|
|
145
|
+
return self._loop_id
|
|
146
|
+
|
|
147
|
+
def __hash__(self) -> int:
|
|
148
|
+
"""Return hash value based on loop_id for use in sets and dictionaries.
|
|
149
|
+
|
|
150
|
+
Returns:
|
|
151
|
+
int: Hash value of the loop_id.
|
|
152
|
+
"""
|
|
153
|
+
return self.loop_id
|
|
154
|
+
|
|
155
|
+
def __int__(self) -> int:
|
|
156
|
+
"""Convert loop to integer representation using loop_id.
|
|
157
|
+
|
|
158
|
+
Returns:
|
|
159
|
+
int: The loop_id as an integer.
|
|
160
|
+
"""
|
|
161
|
+
return self.loop_id
|
|
162
|
+
|
|
163
|
+
def __eq__(self, other: Loop) -> bool:
|
|
164
|
+
"""Check equality with another base loop based on loop_id and type.
|
|
165
|
+
|
|
166
|
+
Args:
|
|
167
|
+
other (Loop): The other loop to compare with.
|
|
168
|
+
|
|
169
|
+
Returns:
|
|
170
|
+
bool: True if both loops have the same class and loop_id, False otherwise.
|
|
171
|
+
"""
|
|
172
|
+
return isinstance(other, other.__class__) and self.loop_id == other.loop_id
|
|
173
|
+
|
|
174
|
+
def __lt__(self, other: Loop | int) -> bool:
|
|
175
|
+
"""Compare loop_id with another loop or integer for ordering.
|
|
176
|
+
|
|
177
|
+
Args:
|
|
178
|
+
other (Loop | int): The other loop or integer to compare with.
|
|
179
|
+
|
|
180
|
+
Returns:
|
|
181
|
+
bool: True if this loop's id is less than the other's id.
|
|
182
|
+
"""
|
|
183
|
+
return int(self.loop_id) < int(other)
|
|
184
|
+
|
|
185
|
+
def __repr__(self) -> str:
|
|
186
|
+
"""Return string representation of the loop.
|
|
187
|
+
|
|
188
|
+
Returns:
|
|
189
|
+
str: String representation showing "Loop {loop_id}".
|
|
190
|
+
"""
|
|
191
|
+
return f"Loop {self.loop_id}"
|
knit_graphs/Yarn.py
CHANGED
|
@@ -6,13 +6,15 @@ The Yarn class manages the sequence of loops along a yarn and their floating rel
|
|
|
6
6
|
from __future__ import annotations
|
|
7
7
|
|
|
8
8
|
from dataclasses import dataclass
|
|
9
|
-
from typing import Iterator, cast
|
|
9
|
+
from typing import TYPE_CHECKING, Iterator, cast
|
|
10
10
|
|
|
11
|
-
from networkx import dfs_edges, dfs_preorder_nodes
|
|
11
|
+
from networkx import DiGraph, dfs_edges, dfs_preorder_nodes
|
|
12
12
|
|
|
13
|
-
from knit_graphs._base_classes import _Base_Knit_Graph, _Base_Yarn
|
|
14
13
|
from knit_graphs.Loop import Loop
|
|
15
14
|
|
|
15
|
+
if TYPE_CHECKING:
|
|
16
|
+
from knit_graphs.Knit_Graph import Knit_Graph
|
|
17
|
+
|
|
16
18
|
|
|
17
19
|
@dataclass(frozen=True)
|
|
18
20
|
class Yarn_Properties:
|
|
@@ -70,33 +72,34 @@ class Yarn_Properties:
|
|
|
70
72
|
return hash((self.name, self.plies, self.weight, self.color))
|
|
71
73
|
|
|
72
74
|
|
|
73
|
-
class Yarn
|
|
75
|
+
class Yarn:
|
|
74
76
|
"""A class to represent a yarn structure as a sequence of connected loops.
|
|
75
77
|
|
|
76
78
|
The Yarn class manages a directed graph of loops representing the physical yarn path through a knitted structure.
|
|
77
79
|
It maintains the sequential order of loops and their floating relationships, providing methods for navigation and manipulation of the yarn structure.
|
|
78
80
|
|
|
79
81
|
Attributes:
|
|
82
|
+
loop_graph (DiGraph): The directed graph loops connected by yarn-wise float edges.
|
|
80
83
|
properties (Yarn_Properties): The physical and visual properties of this yarn.
|
|
81
84
|
"""
|
|
82
85
|
|
|
83
|
-
def __init__(self, yarn_properties: None | Yarn_Properties = None, knit_graph: None |
|
|
86
|
+
def __init__(self, yarn_properties: None | Yarn_Properties = None, knit_graph: None | Knit_Graph = None):
|
|
84
87
|
"""Initialize a yarn with the specified properties and optional knit graph association.
|
|
85
88
|
|
|
86
89
|
Args:
|
|
87
90
|
yarn_properties (None | Yarn_Properties, optional): The properties defining this yarn. If None, uses default properties. Defaults to standard properties.
|
|
88
91
|
knit_graph (None | Knit_Graph, optional): The knit graph that will own this yarn. Can be None for standalone yarns. Defaults to None.
|
|
89
92
|
"""
|
|
90
|
-
|
|
93
|
+
self.loop_graph: DiGraph = DiGraph()
|
|
91
94
|
if yarn_properties is None:
|
|
92
95
|
yarn_properties = Yarn_Properties.default_yarn()
|
|
93
96
|
self.properties: Yarn_Properties = yarn_properties
|
|
94
97
|
self._first_loop: Loop | None = None
|
|
95
98
|
self._last_loop: Loop | None = None
|
|
96
|
-
self._knit_graph: None |
|
|
99
|
+
self._knit_graph: None | Knit_Graph = knit_graph
|
|
97
100
|
|
|
98
101
|
@property
|
|
99
|
-
def knit_graph(self) -> None |
|
|
102
|
+
def knit_graph(self) -> None | Knit_Graph:
|
|
100
103
|
"""Get the knit graph that owns this yarn.
|
|
101
104
|
|
|
102
105
|
Returns:
|
|
@@ -105,7 +108,7 @@ class Yarn(_Base_Yarn):
|
|
|
105
108
|
return self._knit_graph
|
|
106
109
|
|
|
107
110
|
@knit_graph.setter
|
|
108
|
-
def knit_graph(self, knit_graph:
|
|
111
|
+
def knit_graph(self, knit_graph: Knit_Graph) -> None:
|
|
109
112
|
"""Set the knit graph that owns this yarn.
|
|
110
113
|
|
|
111
114
|
Args:
|
|
@@ -6,14 +6,13 @@ from __future__ import annotations
|
|
|
6
6
|
|
|
7
7
|
from typing import Iterator, cast
|
|
8
8
|
|
|
9
|
-
from networkx import dfs_preorder_nodes
|
|
9
|
+
from networkx import DiGraph, dfs_preorder_nodes
|
|
10
10
|
|
|
11
|
-
from knit_graphs._base_classes import _Base_Wale
|
|
12
11
|
from knit_graphs.Loop import Loop
|
|
13
12
|
from knit_graphs.Pull_Direction import Pull_Direction
|
|
14
13
|
|
|
15
14
|
|
|
16
|
-
class Wale
|
|
15
|
+
class Wale:
|
|
17
16
|
"""A data structure representing stitch relationships between loops in a vertical column of a knitted structure.
|
|
18
17
|
|
|
19
18
|
A wale represents a vertical sequence of loops connected by stitch edges, forming a column in the knitted fabric.
|
|
@@ -31,7 +30,7 @@ class Wale(_Base_Wale):
|
|
|
31
30
|
Args:
|
|
32
31
|
first_loop (Loop | None, optional): The initial loop to start the wale with. If provided, it will be added as both the first and last loop. Defaults to None.
|
|
33
32
|
"""
|
|
34
|
-
|
|
33
|
+
self.stitches: DiGraph = DiGraph()
|
|
35
34
|
self.first_loop: None | Loop = first_loop
|
|
36
35
|
self.last_loop: None | Loop = None
|
|
37
36
|
if isinstance(self.first_loop, Loop):
|
|
@@ -4,14 +4,16 @@ This module provides the Wale_Group class which represents a collection of inter
|
|
|
4
4
|
"""
|
|
5
5
|
from __future__ import annotations
|
|
6
6
|
|
|
7
|
-
from typing import cast
|
|
7
|
+
from typing import TYPE_CHECKING, cast
|
|
8
8
|
|
|
9
9
|
from networkx import DiGraph, dfs_preorder_nodes
|
|
10
10
|
|
|
11
|
-
from knit_graphs._base_classes import _Base_Knit_Graph
|
|
12
11
|
from knit_graphs.artin_wale_braids.Wale import Wale
|
|
13
12
|
from knit_graphs.Loop import Loop
|
|
14
13
|
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from knit_graphs.Knit_Graph import Knit_Graph
|
|
16
|
+
|
|
15
17
|
|
|
16
18
|
class Wale_Group:
|
|
17
19
|
"""A graph structure maintaining relationships between connected wales through decrease operations.
|
|
@@ -27,7 +29,7 @@ class Wale_Group:
|
|
|
27
29
|
bottom_loops (dict[Loop, Wale]): Mapping from the first (bottom) loop of each wale to the wale itself.
|
|
28
30
|
"""
|
|
29
31
|
|
|
30
|
-
def __init__(self, terminal_wale: Wale, knit_graph:
|
|
32
|
+
def __init__(self, terminal_wale: Wale, knit_graph: Knit_Graph):
|
|
31
33
|
"""Initialize a wale group starting from a terminal wale and building downward.
|
|
32
34
|
|
|
33
35
|
Args:
|
|
@@ -36,7 +38,7 @@ class Wale_Group:
|
|
|
36
38
|
"""
|
|
37
39
|
self.wale_graph: DiGraph = DiGraph()
|
|
38
40
|
self.stitch_graph: DiGraph = DiGraph()
|
|
39
|
-
self._knit_graph:
|
|
41
|
+
self._knit_graph: Knit_Graph = knit_graph
|
|
40
42
|
self.terminal_wale: Wale | None = terminal_wale
|
|
41
43
|
self.top_loops: dict[Loop, Wale] = {}
|
|
42
44
|
self.bottom_loops: dict[Loop, Wale] = {}
|
|
@@ -79,7 +81,7 @@ class Wale_Group:
|
|
|
79
81
|
"""
|
|
80
82
|
added_wales = []
|
|
81
83
|
for parent_loop in cast(Loop, wale.first_loop).parent_loops:
|
|
82
|
-
parent_wales =
|
|
84
|
+
parent_wales = self._knit_graph.get_wales_ending_with_loop(parent_loop)
|
|
83
85
|
for parent_wale in parent_wales:
|
|
84
86
|
self.add_wale(parent_wale)
|
|
85
87
|
added_wales.extend(parent_wales)
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: knit-graphs
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.9
|
|
4
4
|
Summary: A graph representation of knitted structures where each loop is a node and edges represent yarn and stitch relationships.
|
|
5
|
-
Home-page: https://mhofmann-
|
|
5
|
+
Home-page: https://mhofmann-khoury.github.io/knit_graph/
|
|
6
6
|
License: MIT
|
|
7
7
|
Keywords: ACT Lab,Northeastern University,knit,machine knit,fabrication,textile
|
|
8
8
|
Author: Megan Hofmann
|
|
@@ -22,8 +22,8 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
22
22
|
Classifier: Topic :: Scientific/Engineering
|
|
23
23
|
Requires-Dist: networkx (>=3.5)
|
|
24
24
|
Requires-Dist: plotly (>=6.3.0,<7.0.0)
|
|
25
|
-
Project-URL: Documentation, https://mhofmann-
|
|
26
|
-
Project-URL: Repository, https://github.com/mhofmann-Khoury/
|
|
25
|
+
Project-URL: Documentation, https://mhofmann-khoury.github.io/knit_graph/
|
|
26
|
+
Project-URL: Repository, https://github.com/mhofmann-Khoury/knit_graph/
|
|
27
27
|
Description-Content-Type: text/markdown
|
|
28
28
|
|
|
29
29
|
# knit_graphs
|
|
@@ -20,23 +20,22 @@ docs/source/api/knit_graphs.rst,sha256=w9HIhWI8P0_gG0H_efRUMHYBtWbgCprcS9moclgM_
|
|
|
20
20
|
docs/source/conf.py,sha256=TZK8Rz0JNgQs2J_cUhVX5_4tmMBvRdGtILJsnAnAFWo,13350
|
|
21
21
|
docs/source/index.rst,sha256=D4KmCX1_d2-WrPgxSeggHHsc9-TeQwSUGYOkehRQWrw,1462
|
|
22
22
|
docs/source/installation.rst,sha256=GyNRk_oXKVgOZ4KFLAgkXLwjHYzDYsx8gcokLRrS0ZI,1247
|
|
23
|
-
knit_graphs/Course.py,sha256=
|
|
24
|
-
knit_graphs/Knit_Graph.py,sha256=
|
|
23
|
+
knit_graphs/Course.py,sha256=hO768vPM0KFRsjCYsBTUgasqMzlvl0gsuSrsBX0UUSs,6280
|
|
24
|
+
knit_graphs/Knit_Graph.py,sha256=3NUeznjxAJPkvmwl_qxGpwxeN1LbsQBruAzLu551AZQ,11614
|
|
25
25
|
knit_graphs/Knit_Graph_Visualizer.py,sha256=s2zp6Z7-ZF_52x3zTx8oQr__tQScpkGthIoWck57ykE,40227
|
|
26
|
-
knit_graphs/Loop.py,sha256=
|
|
26
|
+
knit_graphs/Loop.py,sha256=WQh9ag1lv7_cJndZLGhhoGx1msdLEGixpahdXd2PhGk,7189
|
|
27
27
|
knit_graphs/Pull_Direction.py,sha256=8xRLN-j7V1mExgmt3YjcJcTDa5rLedA2bF4wI8gd-DE,2334
|
|
28
|
-
knit_graphs/Yarn.py,sha256=
|
|
28
|
+
knit_graphs/Yarn.py,sha256=Stm-_1SRJTdN1hFPjtuBPyY0Ln55zC15FKGu5vyqerA,16000
|
|
29
29
|
knit_graphs/__init__.py,sha256=qzZAOxTqjgLkhoGnKNZwOkuYbKEyzfWKkKpKkV6lVfk,111
|
|
30
|
-
knit_graphs/_base_classes.py,sha256=ZEv_jkUglHzkfg-0TD6oonBq7QQmA4G7jrC_A6OubpY,6401
|
|
31
30
|
knit_graphs/artin_wale_braids/Crossing_Direction.py,sha256=71ckmEFfL0s25NJb8lfYwH2zku0uM1C5X9gGM7PYC5A,2820
|
|
32
31
|
knit_graphs/artin_wale_braids/Loop_Braid_Graph.py,sha256=2tsE16IzcvgsIKij1JNHWah6hLOgrpXCcjb6eocbfFs,4575
|
|
33
|
-
knit_graphs/artin_wale_braids/Wale.py,sha256=
|
|
32
|
+
knit_graphs/artin_wale_braids/Wale.py,sha256=pdzGYdpy88UWPa1ePvu9YUsDkRAB2wGrqCnMA_vIwAA,7135
|
|
34
33
|
knit_graphs/artin_wale_braids/Wale_Braid.py,sha256=Ws0QmU7s63nrBKe69acDza-r-LozDyyaKVDNxQMy10Y,2662
|
|
35
34
|
knit_graphs/artin_wale_braids/Wale_Braid_Word.py,sha256=4YBlVMUZkqp85r46ETQSbFVS_WrT4PsWthHmFv5Ny9M,4587
|
|
36
|
-
knit_graphs/artin_wale_braids/Wale_Group.py,sha256=
|
|
35
|
+
knit_graphs/artin_wale_braids/Wale_Group.py,sha256=JJXR5TvLuoC2LXvNfmwbHhvBObn0MONUVE9ZsBcSmUc,6867
|
|
37
36
|
knit_graphs/artin_wale_braids/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
38
37
|
knit_graphs/basic_knit_graph_generators.py,sha256=doDH2MiXbMzGU9b3enEr3KdY8Fw90cssHi_lkts6VpY,11720
|
|
39
|
-
knit_graphs-0.0.
|
|
40
|
-
knit_graphs-0.0.
|
|
41
|
-
knit_graphs-0.0.
|
|
42
|
-
knit_graphs-0.0.
|
|
38
|
+
knit_graphs-0.0.9.dist-info/LICENSE,sha256=Oazk3oiRu5ZN7b-EdYNYh0vu-I3Av2uIPQ-9L_cZ6Oo,1070
|
|
39
|
+
knit_graphs-0.0.9.dist-info/METADATA,sha256=XzWrqXe9vJDLKHiA7a3wTNY4foVu6MemvqqWRyuDQ8s,5193
|
|
40
|
+
knit_graphs-0.0.9.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
|
|
41
|
+
knit_graphs-0.0.9.dist-info/RECORD,,
|
knit_graphs/_base_classes.py
DELETED
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
"""Private module containing base classes for Loops and Yarns. Used to resolve circular dependencies."""
|
|
2
|
-
from __future__ import annotations
|
|
3
|
-
|
|
4
|
-
from networkx import DiGraph
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class _Base_Loop:
|
|
8
|
-
"""Base class for Loop objects providing common functionality and interface.
|
|
9
|
-
|
|
10
|
-
This class serves as a foundation for Loop implementations and helps resolve circular dependencies between modules. It provides basic loop identification and comparison functionality.
|
|
11
|
-
"""
|
|
12
|
-
|
|
13
|
-
def __init__(self, loop_id: int):
|
|
14
|
-
"""Initialize a base loop with the given identifier.
|
|
15
|
-
|
|
16
|
-
Args:
|
|
17
|
-
loop_id (int): The unique identifier for this loop. Must be non-negative.
|
|
18
|
-
"""
|
|
19
|
-
assert loop_id >= 0, f"{loop_id}: Loop_id must be non-negative"
|
|
20
|
-
self._loop_id: int = loop_id
|
|
21
|
-
|
|
22
|
-
@property
|
|
23
|
-
def loop_id(self) -> int:
|
|
24
|
-
"""Get the unique identifier of this loop.
|
|
25
|
-
|
|
26
|
-
Returns:
|
|
27
|
-
int: The id of the loop.
|
|
28
|
-
"""
|
|
29
|
-
return self._loop_id
|
|
30
|
-
|
|
31
|
-
def __hash__(self) -> int:
|
|
32
|
-
"""Return hash value based on loop_id for use in sets and dictionaries.
|
|
33
|
-
|
|
34
|
-
Returns:
|
|
35
|
-
int: Hash value of the loop_id.
|
|
36
|
-
"""
|
|
37
|
-
return self.loop_id
|
|
38
|
-
|
|
39
|
-
def __int__(self) -> int:
|
|
40
|
-
"""Convert loop to integer representation using loop_id.
|
|
41
|
-
|
|
42
|
-
Returns:
|
|
43
|
-
int: The loop_id as an integer.
|
|
44
|
-
"""
|
|
45
|
-
return self.loop_id
|
|
46
|
-
|
|
47
|
-
def __eq__(self, other: _Base_Loop) -> bool:
|
|
48
|
-
"""Check equality with another base loop based on loop_id and type.
|
|
49
|
-
|
|
50
|
-
Args:
|
|
51
|
-
other (_Base_Loop): The other loop to compare with.
|
|
52
|
-
|
|
53
|
-
Returns:
|
|
54
|
-
bool: True if both loops have the same class and loop_id, False otherwise.
|
|
55
|
-
"""
|
|
56
|
-
return isinstance(other, other.__class__) and self.loop_id == other.loop_id
|
|
57
|
-
|
|
58
|
-
def __lt__(self, other: _Base_Loop | int) -> bool:
|
|
59
|
-
"""Compare loop_id with another loop or integer for ordering.
|
|
60
|
-
|
|
61
|
-
Args:
|
|
62
|
-
other (_Base_Loop | int): The other loop or integer to compare with.
|
|
63
|
-
|
|
64
|
-
Returns:
|
|
65
|
-
bool: True if this loop's id is less than the other's id.
|
|
66
|
-
"""
|
|
67
|
-
return int(self.loop_id) < int(other)
|
|
68
|
-
|
|
69
|
-
def __repr__(self) -> str:
|
|
70
|
-
"""Return string representation of the loop.
|
|
71
|
-
|
|
72
|
-
Returns:
|
|
73
|
-
str: String representation showing "Loop {loop_id}".
|
|
74
|
-
"""
|
|
75
|
-
return f"Loop {self.loop_id}"
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
class _Base_Yarn:
|
|
79
|
-
"""Base class for Yarn objects providing common functionality and interface.
|
|
80
|
-
|
|
81
|
-
This class serves as a foundation for Yarn implementations and helps resolve circular dependencies between modules. It maintains a directed graph structure for managing loop relationships.
|
|
82
|
-
"""
|
|
83
|
-
|
|
84
|
-
def __init__(self) -> None:
|
|
85
|
-
"""Initialize a base yarn with an empty directed graph for loop relationships."""
|
|
86
|
-
self.loop_graph: DiGraph = DiGraph()
|
|
87
|
-
|
|
88
|
-
def prior_loop(self, loop: _Base_Loop) -> _Base_Loop | None:
|
|
89
|
-
"""Find the loop that precedes the given loop on this yarn.
|
|
90
|
-
|
|
91
|
-
Args:
|
|
92
|
-
loop (_Base_Loop): The loop to find the preceding loop of.
|
|
93
|
-
|
|
94
|
-
Returns:
|
|
95
|
-
_Base_Loop | None: The loop that precedes the given loop on the yarn, or None if there is no prior loop.
|
|
96
|
-
|
|
97
|
-
Raises:
|
|
98
|
-
NotImplementedError: This is an abstract base class which must be extended with the correct implementation.
|
|
99
|
-
"""
|
|
100
|
-
raise NotImplementedError("Implemented by base class")
|
|
101
|
-
|
|
102
|
-
def next_loop(self, loop: _Base_Loop) -> _Base_Loop | None:
|
|
103
|
-
"""Find the loop that follows the given loop on this yarn.
|
|
104
|
-
|
|
105
|
-
Args:
|
|
106
|
-
loop (_Base_Loop): The loop to find the next loop of.
|
|
107
|
-
|
|
108
|
-
Returns:
|
|
109
|
-
_Base_Loop | None: The loop that follows the given loop on the yarn, or None if there is no next loop.
|
|
110
|
-
|
|
111
|
-
Raises:
|
|
112
|
-
NotImplementedError: This is an abstract base class which must be extended with the correct implementation.
|
|
113
|
-
"""
|
|
114
|
-
raise NotImplementedError("Implemented by base class")
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
class _Base_Wale:
|
|
118
|
-
"""Base class for Wale objects providing common functionality and interface.
|
|
119
|
-
|
|
120
|
-
This class serves as a foundation for Wale implementations and maintains a directed graph structure for managing stitch relationships within a wale (vertical column of stitches).
|
|
121
|
-
"""
|
|
122
|
-
|
|
123
|
-
def __init__(self) -> None:
|
|
124
|
-
"""Initialize a base wale with an empty directed graph for stitch relationships."""
|
|
125
|
-
self.stitches: DiGraph = DiGraph()
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
class _Base_Knit_Graph:
|
|
129
|
-
"""Base class for Knit Graph objects providing common functionality and interface.
|
|
130
|
-
|
|
131
|
-
This class serves as a foundation for Knit Graph implementations and maintains a directed graph structure for managing stitch relationships throughout the entire knitted structure.
|
|
132
|
-
"""
|
|
133
|
-
|
|
134
|
-
def __init__(self) -> None:
|
|
135
|
-
"""Initialize a base knit graph with an empty directed graph for stitch relationships."""
|
|
136
|
-
self.stitch_graph: DiGraph = DiGraph()
|
|
137
|
-
|
|
138
|
-
@property
|
|
139
|
-
def last_loop(self) -> None | _Base_Loop:
|
|
140
|
-
"""Get the most recently added loop in the graph.
|
|
141
|
-
|
|
142
|
-
Returns:
|
|
143
|
-
None | _Base_Loop: The last loop added to the graph, or None if the graph contains no loops.
|
|
144
|
-
|
|
145
|
-
Raises:
|
|
146
|
-
NotImplementedError: This is an abstract base class which must be extended with the correct implementation.
|
|
147
|
-
"""
|
|
148
|
-
raise NotImplementedError("Implemented by base class")
|
|
149
|
-
|
|
150
|
-
def add_loop(self, loop: _Base_Loop) -> None:
|
|
151
|
-
"""Add a loop to the knit graph structure.
|
|
152
|
-
|
|
153
|
-
Args:
|
|
154
|
-
loop (_Base_Loop): The loop to add to the graph.
|
|
155
|
-
|
|
156
|
-
Raises:
|
|
157
|
-
NotImplementedError: This is an abstract base class which must be extended with the correct implementation.
|
|
158
|
-
"""
|
|
159
|
-
raise NotImplementedError("Implemented by base class")
|
|
160
|
-
|
|
161
|
-
def get_wales_ending_with_loop(self, last_loop: _Base_Loop) -> list[_Base_Wale]:
|
|
162
|
-
"""Get all wales (vertical columns) that terminate at the specified loop.
|
|
163
|
-
|
|
164
|
-
Args:
|
|
165
|
-
last_loop (_Base_Loop): The loop terminating the list of wales to be returned.
|
|
166
|
-
|
|
167
|
-
Returns:
|
|
168
|
-
list[_Base_Wale]: The list of wales that end at the given loop. This will only be multiple wales if the loop is a child of a decrease stitch.
|
|
169
|
-
|
|
170
|
-
Raises:
|
|
171
|
-
NotImplementedError: This is an abstract base class which must be extended with the correct implementation.
|
|
172
|
-
"""
|
|
173
|
-
raise NotImplementedError
|
|
File without changes
|
|
File without changes
|