├── README.md ├── examples ├── README.md ├── decrease-hinted.smobj ├── decrease.smobj ├── decrease.yarns ├── k.knitout ├── k.smobj ├── k.yarns ├── short-row-hinted-2.smobj ├── short-row-hinted.smobj ├── short-row.smobj ├── short-row.txt ├── spacer.smobj ├── tube-decrease.smobj ├── twill.smobj ├── twill.yarns └── two-sheets.smobj ├── faces ├── README.md ├── illustration.code ├── illustration.sf ├── knitout.sf └── weave.sf ├── utilities ├── .gitignore ├── Makefile ├── NOTES.txt ├── hinters.cpp ├── hinters.hpp ├── knitout-to-smobj.cpp ├── merge-faces.cpp ├── simplify-yarns.cpp ├── sm.cpp ├── sm.hpp ├── smobj-to-yarns.cpp ├── test-code.cpp ├── text-to-smobj.cpp ├── yarn-units.cpp └── yarns-to-bccx.cpp └── web ├── renderers.lines.js ├── renderers.strips.js ├── renderers.tubes.js ├── sm.js └── view-yarns.html /README.md: -------------------------------------------------------------------------------- 1 | The formats and utilities documented here were developed at the [Carnegie Mellon Textiles Lab](https://textiles-lab.github.io/) as part of the [Visual Knit Programming](http://visual.knit.zone) project and further enhanced for use in [KnitDB](http://db.knit.zone) and ongoing research. 2 | For bugs, file a github issue. 3 | For other inquires, please contact [Jim McCann](http://www.cs.cmu.edu/~jmccann/). 4 | 5 | # `.smobj`: a format for augmented-stitch-mesh-like things 6 | 7 | Augmented Stitch Meshes represent knit structures and their dependencies by embedding yarns in the faces of a (tri/quad/pentagon/etc) mesh, and associating types and directions with each edge. 8 | 9 | The `.smobj` format stores an augmented stitch mesh as follows: 10 | 11 | ``` 12 | #text format, like .obj with... 13 | #library of face types as name followed by edge types (+/- indicate [optional] edge direction; edge labels are arbitrary strings) 14 | L knit-to-right -l +y +l -y 15 | L knit-to-right -l2 +y +l2 -y #face names include the edge types, so this is different than the previous face 16 | #vertices as X Y Z: 17 | v 1.0 2.2 1.0 18 | v 1.0 1.0 1.0 19 | v 3.0 2.2 1.0 20 | v 3.0 1.0 1.0 21 | #faces as 1-based vertex index lists (and, possibly, texture coordinates): 22 | f 2 4 3 1 23 | #and, for each face, a type from the library (1-based index into library): 24 | T 1 25 | #(optional) 1-based source line number of knitout file that made this face (use 0 if line not known): 26 | N 15 27 | #list of connections between faces: 28 | # face#/edge#, both 1-based; negative edges imply *reversing* the edge 29 | # this allows non-orientable connections, needed for knitout 30 | # (NOTE: on a nicely oriented mesh, all 'e' commands will have one negative edge) 31 | e 1/1 2/-4 32 | # (optional) list of scheduler hints can be provided for edges using hint lines starting with: 33 | # 'h' for resource hints, 'o' for order hints, 't' for variant type hints 34 | # face/edge inidcates the edge (indices are one-based as above, edges are always positive) 35 | # hints can indicate bed(char) and needle(float) 36 | # 'u' indicates hint is from user, 'i' indicates hint was inferred from user hints, 'h' indicates hint was heuristic/arbitrary 37 | h 1/1 f20 u 38 | # order hints that indicate order between instructions face/instruction 39 | # (instructions are indexed ignoring comments) 40 | o 1/1 2/1 u 41 | # type hints that indicate variant name for face index, indices are 1-based 42 | t 1 variant-name u 43 | # total order of instructions is saved as a sequence of face/instruction index, 1-based 44 | I 1/1 45 | I 1/2 46 | #(optional) list of checkpoints on yarns and desired length between them: 47 | # checkpoint list starts with unit library: 48 | U 1 1.0 #unit definition -- there is a length unit called '1' with [default] length '1.0' 49 | #By convention, the first unit will always be called '1' and will always have length '1.0' 50 | U n 0.4 #unit definition -- there is a length unit called 'n' with [default] length '0.4' 51 | U s65 0.2 #unit definition -- there is a length unit called 's65' with [default] length '0.2' 52 | #checkpoints are listed *in order* along yarns 53 | # any yarn with checkpoints *MUST* be covered from start-to-end 54 | c 1/1/1 0.1 1 1.0 2 2.0 3 #checkpoint at face/edge/yarn crossing with 0.1 + 1.0*n + 2.0*s65 length following 55 | c 1/3/1 #last checkpoint on a yarn will always have zero following length 56 | #NOTE: checkpoints define yarn orientation; yarns without checkpoints will be arbitrarially oriented by smobj-to-yarns 57 | 58 | ``` 59 | 60 | # `.yarns`: a format for yarn curves 61 | 62 | The yarn format stores one or more yarns as polylines. 63 | Typically, these polylines are interpreted for viewing by connecting subsequent midpoints with quadratic bezier curves in order to create a smooth path. 64 | 65 | A `.yarns` file consists of several chunks, where each chunk contains a 4-byte header, a 4-byte size (length of chunk data in bytes), and a flat array of uniform data elements. 66 | 67 | In other words, each chunk corresponds to a `vector< T >` for some `T`. 68 | 69 | The specific chunks and their order: 70 | ``` 71 | (1) Points 72 | Header: 'f3..' 73 | Size: 12* 74 | Contents: N point locations stored as floating point numbers: 75 | struct { 76 | float x; 77 | float y; 78 | float z; 79 | } 80 | 81 | (2) Source Line Numbers: 82 | Header: 'src.' 83 | Size: 4*N 84 | Contents: N source line numbers (same length as points) stored as 32-bit unsigned integers 85 | NOTE: line numbers correspond to the line number for the smobj face that created the next segment. Line numbers for the last point in a yarn are set to the same value as the second-to-last by convention. 86 | 87 | (3) Yarn Information 88 | Header: 'yarn' 89 | Size: 16*N 90 | Contents: N yarn descriptors stored as: 91 | struct { 92 | uint32_t point_begin; //index of first point in yarn 93 | uint32_t point_end; //index of last+1 point in yarn 94 | //Note that yarns will *not* overlap in the points list 95 | float radius; //radius of yarn 96 | uint8_t r,g,b,a; //color for yarn 97 | } 98 | [remaining sections are work-in-progress] 99 | (4) Strings 100 | Header: 'strs' 101 | Size: N 102 | Contents: N bytes of string data 103 | (5) Units 104 | Header: 'unit' 105 | Size: 12*N 106 | Contents: N unit descriptors stored as: 107 | struct { 108 | uint32_t name_begin; //index of first character of unit name 109 | uint32_t name_end; //index of last character of unit name 110 | float length; //default/reccomended length of given unit <-- might remove this 111 | } 112 | NOTE: the first unit will always be named '1' and will always represent absolute lengths. 113 | (6) Checkpoints: 114 | Header: 'chk.' 115 | Size: 12*N 116 | Contents: N checkpoints stored as: 117 | struct { 118 | uint32_t point; //point to add slack after 119 | float length; //amount of length to add 120 | uint32_t unit; //unit of length 121 | } 122 | NOTE: checkpoints must be stored sorted by (point, unit) 123 | ``` 124 | 125 | Note that each "Checkpoint" structure adds yarn length between that checkpoint and the next *checkpoint* (or the end of the yarn) -- this is different than adding length between checkpoints and their next yarn point. 126 | This ambiguity is required because the allocation of length to yarn segments is generally not known. 127 | 128 | 129 | # `.sf`: a format for stitch mesh face libraries 130 | 131 | The `.sf` format contains a stitch mesh face library (that is, a collection of "template" face shapes containing yarn shapes). 132 | This format was originally developed to be edited by hand -- and this shows -- though we have subsequently developed some internal tooling for face creation. 133 | 134 | A stitch-faces (`.sf`) file consists of a series of lines. Each line starts with a token and is followed by text in a token-specific format. 135 | The types of lines and their formats are documented in comments (words after `#`) in the following example: 136 | ``` 137 | #This is an example face based on the illustraion.sf file included in this repository 138 | 139 | #The face line is followed by a space and a face name (a non-space-containing token) 140 | face make-left-tuck+ 141 | # edge lines that define the shape and edge types of the face 142 | # edges appear -- by convention -- CCW from the lower left vertex 143 | # an edge line gives the point at which the edge starts and an edge label 144 | # the label starts with '+' (for 'out' edges), '-' (for 'in' adges), or nothing (for undirected edges) followed by a string for the edge type 145 | # by covention, edge types in knitting faces are 'l' (loop) and 'y' (yarn) and often suffixed by a number of yarns 146 | edge (-1.0,-1.062) -l1 147 | edge ( 1.0,-1.062) +y1 148 | edge ( 1.6, 0.0) +l1 149 | edge ( 0.0, 1.2) +l1 150 | edge (-1.6, 0.0) -y1 151 | #yarn lines specify yarns inside the face, and are given by a boundary point, a list of internal points, and another boundarty point 152 | # boundary points are writen [e:amt,z] and consist of a zero-based edge index, e; an amount along the edge, 0 < amt < 1; and a depth, z. 153 | # interal points are regular (x,y,z) tuples. 154 | yarn [1:0.25,0] (0.321847,-0.211278,-0.19533) (0.390594,0.0406245,0.196892) [2:0.275,0] 155 | yarn [2:0.725,0] (0.257785,0.276222,0.206233) (-0.0984679,0.224999,-0.276545) [3:0.275,0] 156 | yarn [3:0.725,0] (-0.917159,-0.201903,0) [4:0.75,0] 157 | yarn [0:0.275,0] (-0.28123,-0.0375,0.0968753) (0.0125145,0.592189,-0.0593829) (0.529687,0.375012,-0.0609375) (0.648423,-0.064061,-0.034383) (0.389042,-0.473437,0.0968753) [0:0.725,0] 158 | 159 | #the full "key" of a face consists of its name followed by space-separated edge labels. 160 | #the "key" of the face above is "make-left-tuck+ -l1 +y1 +l1 +l1 -y1" 161 | #face keys must be unique 162 | 163 | #As a matter of convenience, a derive line may be used to create a new face by flipping/permuting an existing face 164 | #derive lines give the key (name and edge labels) of the new face followed by 'by' followed by a list of operations follwed by 'from' followed by a face key 165 | derive make-right-tuck+ -l1 +y1 +l1 +l1 -y1 by mirror-x reverse-yarn from make-left-tuck+ -l1 +y1 +l1 +l1 -y1 166 | 167 | #the operations that may be used: (see Library::Face::Derive::ByBit in sm.hpp) 168 | # mirror-x -- reflect over the x-axis; move the starting edge to the other end of any chain of same-type edges along the bottom 169 | # mirror-z -- reflect z-coordinate of yarns 170 | # reverse-yarn -- reverse direction of yarns; swap '+y' and '-y' edges 171 | ``` 172 | 173 | # Utilities 174 | 175 | This repository contains a few utilities that make it easy to work with .smobj files. 176 | 177 | Build on OSX or Linux using `make` in the `utilities` directory. 178 | You will need glm installed in a system-wide path (or to modify the Makefile as is proper). 179 | 180 | Build on Windows using `nmake -f Makefile.windows` from the Visual Studio Command Prompt in the `utilities` directory. 181 | You will need a checkout of glm in the `utilities\glm` directory. 182 | Windows builds are tested less frequently than OSX or Linux builds so you may need to fix a few warnings. 183 | 184 | ## .knitout to .smobj (Work in Progress) 185 | 186 | The `knitout-to-smobj` utility converts knitout instructions to an smobj description. 187 | ``` 188 | ./knitout-to-smobj 189 | ``` 190 | 191 | Given the nature of the conversion, the output file often contains elongated yarns, though the yarn length checkpoints it produces should provide a more reasonable notion of how much they need to be shrunk. 192 | 193 | ### TODO 194 | - Testing required, especially of distance checkpoints during plating. 195 | - Yarn bring-in faces should probably be hoisted. 196 | - Handling of distance checkpoints around splits is not ideal. 197 | 198 | ## .smobj to .yarns (Work in Progress) 199 | 200 | The `smobj-to-yarns` utility loads a face library and smobj file and exports a `.yarns` file which describes the yarn paths described by the file. 201 | ``` 202 | ./smobj-to-yarns 203 | ``` 204 | 205 | It uses the notion of generalized barycentric coordinates to warp the face from the library. 206 | 207 | ### TODO 208 | - Testing required, especially of new features. 209 | 210 | # Viewers 211 | 212 | ## web/view-yarns.html (Work in Progress) 213 | 214 | Viewer for yarns files built with javascript and WebGL. 215 | To use, open the file in a browser and drag in (or click to open) a ```.yarns``` file. 216 | 217 | ### TODO 218 | - Units panel should update unit lengths. 219 | - Toggle viewing mode between yarn color and stretch color. 220 | - Some way to read back line numbers (mouse-over?) 221 | 222 | 223 | # Standard Face and Edge Types (Knitout) 224 | 225 | This section describes the face library our knitout-to-smobj code uses to represent the result of machine knitting. 226 | This library is stored in the `faces/knitout.sf` file. 227 | 228 | The library includes `yN` (N yarn), `lN` (N loop), and 'x' (empty) edges. 229 | 230 | Here are the face types; edges are named in CCW order from the bottom left: 231 | ``` 232 | #Basic machine operations: 233 | #front/back knit: 234 | L knit-to-left -l1 -y1 +l1 +y1 235 | L knit-to-right -l1 +y1 +l1 -y1 236 | L purl-to-left -l1 -y1 +l1 +y1 237 | L purl-to-right -l1 +y1 +l1 -y1 238 | #(and versions that take lN -> lM via yM) 239 | 240 | #Tuck 241 | L tuck-behind-to-left -l0 -y1 +l1 +y1 242 | L tuck-behind-to-right -l0 +y1 +l1 -y1 243 | L tuck-infront-to-left -l0 -y1 +l1 +y1 244 | L tuck-infront-to-right -l0 +y1 +l1 -y1 245 | #(and versions that take lN -> l(N+M) via yM) 246 | 247 | #Split 248 | # top and bottom edge have two loop segments, connected to needle pair being split between 249 | # by convention, the left segment is the front loop and the right is the back loop 250 | L split-front-to-right -l1 -l1 +y1 +l1 +l2 -y1 251 | L split-front-to-left -l1 -l1 -y1 +l1 +l2 +y1 252 | #(and versions that take -lX -lY to +lZ +l(X+Y) via yZ) 253 | L split-back-to-right -l1 -l1 +y1 +l2 +l1 -y1 254 | L split-back-to-left -l1 -l1 -y1 +l2 +l1 +y1 255 | #(and versions that take -lX -lY to +l(X+Y) +lZ via yZ) 256 | 257 | #loop / yarn routing: 258 | L loop -l1 x +l1 x 259 | L yarn-to-right x +y1 x -y1 260 | L yarn-to-left x -y1 x +y1 261 | #yarn enters going left/right into diagonal bottom face, leaves going left/right from diagonal top face: 262 | L yarn-left-up-right -y1 x +y1 x 263 | L yarn-left-up-left -y1 x +y1 x 264 | L yarn-right-up-right -y1 x +y1 x 265 | L yarn-right-up-left -y1 x +y1 x 266 | #yarn plating (lower edge connects to bottom of stack so stack [1 2] splits to lower edge [1] and upper edge [2]): 267 | L yarn-plate-to-right x +y2 x -y1 -y1 268 | L yarn-plate-to-left x -y1 -y1 x +y2 269 | #also +y(N+M) from -yN, -yM 270 | L yarn-unplate-to-right x +y1 +y1 x -y2 271 | L yarn-unplate-to-left x -y2 x +y1 +y1 272 | #also +yN +yM from -y(N+M) 273 | 274 | ``` 275 | 276 | 277 | 278 | 279 | # Notes and Work-In-Progress Stuff 280 | 281 | ## Deprecated Things 282 | 283 | Our format used to also contain the following, but they have been replaced: 284 | 285 | ``` 286 | # ---- old data ---- 287 | #or (2) one of 'tk', 'te', 'ts' to label edges where 0 = loopwise and 1= yarnwise 288 | tk 1 0 1 0 289 | # and st to mark short-row faces, unused mostly 290 | st 14 291 | # 's' specifies starting face(s) 292 | s f# 293 | ``` 294 | 295 | ## Extension: Texture Coordinates 296 | 297 | One may add texture coordinates to smobj files as follows: 298 | ``` 299 | #(optional) texture coorinates as vt commands: 300 | vt 0.0 0.0 301 | vt 1.0 0.0 302 | vt 1.0 1.0 303 | vt 0.0 1.0 304 | #(optional) extra layers of texture coordinates (same length as first list): 305 | vt2 0.5 0.5 306 | vt2 1.0 0.5 307 | vt2 1.0 1.0 308 | vt2 0.5 1.0 309 | #faces include texture coordinates [as per .obj]: 310 | f 2/1 4/2 3/3 1/4 311 | #(optional) indicate which image corresponds to which texture coordinate: 312 | tex foo.jpg 313 | tex2 bar.jpg 314 | ``` 315 | 316 | 317 | 318 | ## What /Should/ Be In The File 319 | 320 | - A collection of faces. 321 | - For each face, a type (which also implies a type for all edges) 322 | - Edge-to-edge connection information. 323 | - Position information for each face (sufficient for unambiguous and continuous display; that is, shouldn't require optimization to get consistent connection positions) 324 | - Maybe: embedding info on another mesh? 325 | - Maybe: yarn ID info for knitting? 326 | 327 | 328 | ## Problems To Resolve 329 | 330 | vertices represent corner-to-corner connections between faces that, in general, aren't represented by yarn. 331 | (They also make it hard to translate `.knitout` directly to `.smobj`, since stacking stitches with xfer operations can lead to cases which don't make sense in the vertices-imply-connections case.) 332 | 333 | Example: 334 | 335 | ``` 336 | >d>e>f> 337 | ^ ^ 338 | >a>b>c> 339 | ``` 340 | Stitches a,b,c sit in the course below stitches d,e,f; but stitch b is dropped before e was knit. 341 | Unfortunately, the a^d and c^f connections imply that b's upper vertices correspond with e's lower vertices. 342 | 343 | Face types often require yarn-reflected versions, which is an additional modeling burden; this could be made explicit in the format, at the price of additional loader complexity. 344 | Knowledge of which faces are yarn-reflected versions is very useful when editing. 345 | 346 | Faces might be parameterized by (e.g.) loop size, but this also makes corner-to-corner connection over-constrained. 347 | 348 | Faces might also have different desired shapes depending on their neighbors, which implies a fair bit of modeling (or simulation?) burden. 349 | 350 | (Low priority) As a text format, smobj may be slower to load/save than it could be, and may lose precision. 351 | If there is a fast way to do better, it would be worth pursuing. 352 | 353 | We want to make it easy to add extra data layers to the smobj (e.g., for correlation with photographs). 354 | We could store these in separate files, or extra chunks, but certainly the text format helps with the extra-layers problem. 355 | 356 | Proposed chunked format (variable-length faces are awkward!), edge-name format: 357 | ``` 358 | #basic geometry: 359 | vXYZ NNNN 360 | (NNNN/12 vertices as little-endian f32 xyz tuples) 361 | fSiz NNNN 362 | (NNNN face sizes, as u8) 363 | fIdx NNNN 364 | (NNNN/4 indices into vertices as little-endian u32) 365 | #edge type table: 366 | etSt NNNN 367 | (NNNN bytes of utf8 edge type string data for edge type names) 368 | etNm NNNN 369 | (NNNN/8 bytes of begin/end index pairs as little-endian u32 for edge type names) 370 | #face type table: 371 | ftSt NNNN 372 | (NNNN bytes of utf8 string data for face types) 373 | ftNm NNNN 374 | (NNNN/8 bytes of begin/end index pairs as little-endian u32 for face type names) 375 | #need convention for edge directions; separate in/out types? seems odd to store per-exemplar. 376 | ftSz NNNN 377 | (NNNN face type sizes, as u8) 378 | ftEt NNNN 379 | (NNNN edge types per face, as u8 indicies into edge type table) 380 | ftEd NNNN 381 | (NNNN edge directions per face, as i8 +1 / -1 / 0 for out, in, directionless) 382 | #face types: 383 | fTyp NNNN 384 | (NNNN face types, as u8 indices into face types table) 385 | #might handle positions in images this way: 386 | fUV0 NNNN 387 | (NNNN/8 uv coords per face as little-endian f32; NaN for no coordinates) 388 | #though it might be better to go full 3D coordinates. 389 | ``` 390 | 391 | 392 | ## Some alternative ideas 393 | 394 | Represent stitches by their frames and connection points; rendering done by warping based on connection points (instead of whole edges). 395 | More awkward to display (or texture map) for sure. 396 | Might generally be better for layout(?). 397 | 398 | Keep faces but cut corners, giving each [e.g.] quad face four additional empty edges. 399 | 400 | Keep faces but represent edge-edge connections explicitly; this means that code could at some point substitute in the cut-corners version. 401 | 402 | Empty edges, in general, would complete the data structure nicely, in terms of consistency. 403 | Do empty edges need special notation? (Probably yes -- empty edges either have no direction or perhaps can't be connected at all? Though allowing connections might be useful for visualization.) 404 | -------------------------------------------------------------------------------- /examples/README.md: -------------------------------------------------------------------------------- 1 | # Examples 2 | 3 | ## short-row.smobj 4 | Created from `short-row.txt` by `utilities/text-to-smobj`. Uses the face set `faces/illustration.sf`. 5 | 6 | ## k.smobj 7 | Created from `k.knitout` by `utilities/knitout-to-smobj`. Uses the face set `faces/knitout.sf`. 8 | 9 | ## twill.smobj 10 | Basic weaving pattern built by hand using an unreleased tool. Uses the face set `faces/weave.sf`. 11 | -------------------------------------------------------------------------------- /examples/decrease-hinted.smobj: -------------------------------------------------------------------------------- 1 | L knit+ -lX +yX +lX -yX 2 | L make-left-split+ -lX +yX +lX +lX -yX 3 | L make-left-tuck+ -lX +yX +lX +lX -yX 4 | L make-left-tuck-twist+ -lX +yX +lX +lX -yX 5 | L make-left-tuck-twist- -lX -yX +lX +lX +yX 6 | L make-right-split+ -lX +yX +lX +lX -yX 7 | L make-right-tuck+ -lX +yX +lX +lX -yX 8 | L make-right-tuck-twist+ -lX +yX +lX +lX -yX 9 | L make-right-tuck-twist- -lX -yX +lX +lX +yX 10 | L purl+ -lX +yX +lX -yX 11 | L purl- -lX -yX +lX +yX 12 | L tuck-twist+ -lX +yX +lX -yX 13 | L tuck-twist- -lX -yX +lX +yX 14 | L turn)(( -lX +lX +yX -yX 15 | L turn))( -lX -yX +yX +lX 16 | L knit-plating-2+ -lX +yX +lX -yX 17 | L knit-plating-1+ -lX +yX +lX -yX 18 | L knit-fair-isle-2+ -lX +yX +lX -yX 19 | L knit-fair-isle-1+ -lX +yX +lX -yX 20 | L knit- -lX -yX +lX +yX 21 | L knit+.2111 -lX +yX +lX -yX 22 | L drop- -l1 -y0 +l0 +y0 23 | L drop+ -l1 +y0 +l0 -y0 24 | L turn-tuck)(( -lX +lX +yX -yX 25 | L turn-tuck))( -lX -yX +yX +lX 26 | L edge) x x x +y1 -y1 27 | L edge( x -y1 +y1 x x 28 | L decrease-right- -lX -lX -yX +lX +yX 29 | L decrease-right+ -lX -lX +yX +lX -yX 30 | L decrease-left+ -lX -lX +yX +lX -yX 31 | v -1 -0.61 0 32 | v 1 -0.61 0 33 | v 1 0.61 0 34 | v -1 0.61 0 35 | v 1.32645 -0.61 0 36 | v 3.32645 -0.61 0 37 | v 3.32645 0.61 0 38 | v 1.32645 0.61 0 39 | v -3.34377 -0.61 0 40 | v -1.34377 -0.61 0 41 | v -1.34377 0.61 0 42 | v -3.34377 0.61 0 43 | v -3.34377 0.73874 0 44 | v -1.34377 0.73874 0 45 | v -1.34377 1.95874 0 46 | v -3.34377 1.95874 0 47 | v -1 0.738914 0 48 | v 1 0.738914 0 49 | v 1 1.95891 0 50 | v -1 1.95891 0 51 | v 1.32645 0.757035 0 52 | v 3.32645 0.757035 0 53 | v 3.32645 1.97704 0 54 | v 1.32645 1.97704 0 55 | v 3.55678 -0.590246 0 56 | v 5.02314 -0.592082 0 57 | v 3.55678 1.97704 0 58 | v 3.55678 0.693394 0 59 | v 4.55678 1.89889 0.559697 60 | v -5.56997 0.73874 0 61 | v -3.56997 0.73874 0 62 | v -3.56997 3.41089 0 63 | v -5.56997 3.41089 0 64 | v -3.56997 2.07482 0 65 | v -3.325 2.18319 0 66 | v -1.325 2.18319 0 67 | v -1.325 3.40319 0 68 | v -3.325 3.40319 0 69 | v -1 2.17178 0 70 | v 3.2387 2.17178 0 71 | v 3.2387 3.39178 0 72 | v -1 3.39178 0 73 | v 1.11935 2.17178 0 74 | v 0.119349 3.51233 0 75 | v 2.11935 3.51233 0 76 | v 2.11935 4.73233 0 77 | v 0.119349 4.73233 0 78 | v -3.325 3.48126 0 79 | v -1.325 3.48126 0 80 | v -1.325 4.70126 0 81 | v -3.325 4.70126 0 82 | f 1 2 3 4 83 | T 12 84 | N 0 85 | f 5 6 7 8 86 | T 12 87 | N 0 88 | f 9 10 11 12 89 | T 12 90 | N 0 91 | f 13 14 15 16 92 | T 20 93 | N 0 94 | f 17 18 19 20 95 | T 20 96 | N 0 97 | f 21 22 23 24 98 | T 20 99 | N 0 100 | f 25 26 29 27 28 101 | T 26 102 | N 0 103 | f 30 31 34 32 33 104 | T 27 105 | N 0 106 | f 35 36 37 38 107 | T 1 108 | N 0 109 | f 39 43 40 41 42 110 | T 29 111 | N 0 112 | f 44 45 46 47 113 | T 22 114 | N 0 115 | f 48 49 50 51 116 | T 22 117 | N 0 118 | e 1/4 3/-2 119 | e 1/2 2/-4 120 | e 2/3 6/-1 121 | e 1/3 5/-1 122 | e 3/3 4/-1 123 | e 4/2 5/-4 124 | e 5/2 6/-4 125 | e 2/2 7/-5 126 | e 6/2 7/-4 127 | e 6/3 10/-2 128 | e 5/3 10/-1 129 | e 9/2 10/-5 130 | e 4/4 8/-2 131 | e 8/3 9/-4 132 | e 10/4 11/-1 133 | e 9/3 12/-1 134 | e 4/3 9/-1 135 | o 9/1 0/1 u 136 | o 0/1 0/2 u 137 | o 10/1 0/2 u 138 | o 0/1 10/1 u 139 | o 10/2 0/2 u 140 | o 0/2 10/3 u 141 | h 3/1 f0 u 142 | h 1/1 f1 u 143 | h 2/1 f2 u 144 | t 1 front h 145 | t 2 front h 146 | t 3 front h 147 | h 1/2 f1.5 i 148 | h 1/3 f1 i 149 | h 1/4 f0.5 i 150 | h 2/2 f2.5 i 151 | h 2/3 f2 i 152 | h 2/4 f1.5 i 153 | h 3/2 f0.5 i 154 | h 3/3 f0 i 155 | h 3/4 f-0.5 i 156 | h 4/1 f0 i 157 | h 5/1 f1 i 158 | h 6/1 f2 i 159 | t 4 front h 160 | t 5 front h 161 | t 6 front h 162 | h 4/2 f0.5 i 163 | h 4/3 f0 i 164 | h 4/4 f-0.5 i 165 | h 5/2 f1.5 i 166 | h 5/3 f1 i 167 | h 5/4 f0.5 i 168 | h 6/2 f2.5 i 169 | h 6/3 f2 i 170 | h 6/4 f1.5 i 171 | h 9/1 f0 i 172 | h 10/1 f1 i 173 | h 10/2 f2 i 174 | o 6/1 5/1 i 175 | o 5/1 4/1 i 176 | t 9 front h 177 | t 10 front h 178 | h 9/2 f0.5 i 179 | h 9/3 f0 i 180 | h 9/4 f-0.5 i 181 | h 10/3 f2.5 i 182 | h 10/4 f2 i 183 | h 10/5 f1.5 i 184 | h 11/1 f2 i 185 | h 12/1 f1 u 186 | o 10/1 10/2 h 187 | o 10/2 10/3 h 188 | o 4/1 9/1 i 189 | o 9/1 10/1 i 190 | t 11 front h 191 | t 12 front h 192 | h 11/2 f2.5 i 193 | h 11/3 x2 i 194 | h 11/4 f1.5 i 195 | h 12/2 f1.5 u 196 | h 12/3 f1 u 197 | h 12/4 f0.5 u 198 | o 10/3 11/1 i 199 | o 11/1 12/1 i 200 | t 7 front u 201 | t 8 front u 202 | o 3/1 3/2 u 203 | o 3/2 1/1 u 204 | o 1/1 1/2 u 205 | o 1/2 2/1 u 206 | o 2/1 2/2 u 207 | o 2/2 6/1 u 208 | xfer f0 b0 209 | xfer b0 f1 210 | ci 12/1 211 | ci 12/2 212 | ci 16/1 213 | ci 16/2 214 | -------------------------------------------------------------------------------- /examples/decrease.smobj: -------------------------------------------------------------------------------- 1 | L knit+ -lX +yX +lX -yX 2 | L make-left-split+ -lX +yX +lX +lX -yX 3 | L make-left-tuck+ -lX +yX +lX +lX -yX 4 | L make-left-tuck-twist+ -lX +yX +lX +lX -yX 5 | L make-left-tuck-twist- -lX -yX +lX +lX +yX 6 | L make-right-split+ -lX +yX +lX +lX -yX 7 | L make-right-tuck+ -lX +yX +lX +lX -yX 8 | L make-right-tuck-twist+ -lX +yX +lX +lX -yX 9 | L make-right-tuck-twist- -lX -yX +lX +lX +yX 10 | L purl+ -lX +yX +lX -yX 11 | L purl- -lX -yX +lX +yX 12 | L tuck-twist+ -lX +yX +lX -yX 13 | L tuck-twist- -lX -yX +lX +yX 14 | L turn)(( -lX +lX +yX -yX 15 | L turn))( -lX -yX +yX +lX 16 | L knit-plating-2+ -lX +yX +lX -yX 17 | L knit-plating-1+ -lX +yX +lX -yX 18 | L knit-fair-isle-2+ -lX +yX +lX -yX 19 | L knit-fair-isle-1+ -lX +yX +lX -yX 20 | L knit- -lX -yX +lX +yX 21 | L knit+.2111 -lX +yX +lX -yX 22 | L drop -l1 +y0 +l0 -y0 23 | L drop -l1 -y0 +l0 +y0 24 | L turn-tuck)(( -lX +lX +yX -yX 25 | L turn-tuck))( -lX -yX +yX +lX 26 | L edge) x x x +y1 -y1 27 | L edge( x -y1 +y1 x x 28 | L decrease-right- -lX -lX -yX +lX +yX 29 | L decrease-right+ -lX -lX +yX +lX -yX 30 | L decrease-left+ -lX -lX +yX +lX -yX 31 | L out+ x x -yX 32 | L out- x -yX x 33 | L start< -lX +yX +lX 34 | L start> -lX +lX +yX 35 | L in- x x +yX 36 | L in+ x +yX x 37 | L end> -lX +lX -yX 38 | v -1 -0.61 0 39 | v 1 -0.61 0 40 | v 1 0.61 0 41 | v -1 0.61 0 42 | v 1.32645 -0.61 0 43 | v 3.32645 -0.61 0 44 | v 3.32645 0.61 0 45 | v 1.32645 0.61 0 46 | v -3.34377 -0.61 0 47 | v -1.34377 -0.61 0 48 | v -1.34377 0.61 0 49 | v -3.34377 0.61 0 50 | v -3.34377 0.73874 0 51 | v -1.34377 0.73874 0 52 | v -1.34377 1.95874 0 53 | v -3.34377 1.95874 0 54 | v -1 0.738914 0 55 | v 1 0.738914 0 56 | v 1 1.95891 0 57 | v -1 1.95891 0 58 | v 1.32645 0.757035 0 59 | v 3.32645 0.757035 0 60 | v 3.32645 1.97704 0 61 | v 1.32645 1.97704 0 62 | v 3.55678 -0.590246 0 63 | v 5.02314 -0.592082 0 64 | v 3.55678 1.97704 0 65 | v 3.55678 0.693394 0 66 | v 4.55678 1.89889 0.559697 67 | v -5.56997 0.73874 0 68 | v -3.56997 0.73874 0 69 | v -3.56997 3.41089 0 70 | v -5.56997 3.41089 0 71 | v -3.56997 2.07482 0 72 | v -3.325 2.18319 0 73 | v -1.325 2.18319 0 74 | v -1.325 3.40319 0 75 | v -3.325 3.40319 0 76 | v -1 2.17178 0 77 | v 3.2387 2.17178 0 78 | v 3.2387 3.39178 0 79 | v -1 3.39178 0 80 | v 1.11935 2.17178 0 81 | v 0.119349 3.51233 0 82 | v 2.11935 3.51233 0 83 | v 2.11935 4.73233 0 84 | v 0.119349 4.73233 0 85 | v -3.325 3.48126 0 86 | v -1.325 3.48126 0 87 | v -1.325 4.70126 0 88 | v -3.325 4.70126 0 89 | v 3.43888 2.16347 0 90 | v 4.59233 2.75944 0 91 | v 3.43888 3.36791 0 92 | v -3.61959 -0.61 0 93 | v -3.61959 0.61 0 94 | v -4.77691 -0.0835095 0 95 | f 1 2 3 4 96 | T 12 97 | N 0 98 | f 5 6 7 8 99 | T 12 100 | N 0 101 | f 9 10 11 12 102 | T 12 103 | N 0 104 | f 13 14 15 16 105 | T 20 106 | N 0 107 | f 17 18 19 20 108 | T 20 109 | N 0 110 | f 21 22 23 24 111 | T 20 112 | N 0 113 | f 25 26 29 27 28 114 | T 26 115 | N 0 116 | f 30 31 34 32 33 117 | T 27 118 | N 0 119 | f 35 36 37 38 120 | T 1 121 | N 0 122 | f 39 43 40 41 42 123 | T 29 124 | N 0 125 | f 44 45 46 47 126 | T 22 127 | N 0 128 | f 48 49 50 51 129 | T 22 130 | N 0 131 | f 52 53 54 132 | T 31 133 | N 0 134 | f 57 55 56 135 | T 36 136 | N 0 137 | e 1/4 3/-2 138 | e 1/2 2/-4 139 | e 2/3 6/-1 140 | e 1/3 5/-1 141 | e 3/3 4/-1 142 | e 4/2 5/-4 143 | e 5/2 6/-4 144 | e 2/2 7/-5 145 | e 6/2 7/-4 146 | e 6/3 10/-2 147 | e 5/3 10/-1 148 | e 9/2 10/-5 149 | e 4/4 8/-2 150 | e 8/3 9/-4 151 | e 10/4 11/-1 152 | e 9/3 12/-1 153 | e 4/3 9/-1 154 | e 10/3 13/-3 155 | e 3/4 14/-2 156 | -------------------------------------------------------------------------------- /examples/decrease.yarns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textiles-lab/smobj/a0743546e88de8502a3538445b9b3b1c7a7a8628/examples/decrease.yarns -------------------------------------------------------------------------------- /examples/k.knitout: -------------------------------------------------------------------------------- 1 | ;!knitout-2 2 | ;;Carriers: 1 2 3 4 5 6 7 8 9 10 3 | 4 | ; reference: 5 | ; 6 | ; 01234567890123 7 | ; ..............8 8 | ; ......kk......7 9 | ; ......kk......6 10 | ; ......kk..kk..5 11 | ; ......kk.kk...4 12 | ; ......kkkk....3 13 | ; ..kk..kk.kk...2 14 | ; ..kk..kk..kk..1 15 | ; ..............0 16 | ; 17 | 18 | inhook 3 19 | tuck - f13 3 20 | tuck - f11 3 21 | tuck - f9 3 22 | tuck - f7 3 23 | tuck - f5 3 24 | tuck - f3 3 25 | tuck - f1 3 26 | tuck + f0 3 27 | tuck + f2 3 28 | tuck + f4 3 29 | tuck + f6 3 30 | tuck + f8 3 31 | tuck + f10 3 32 | tuck + f12 3 33 | releasehook 3 34 | 35 | knit - f13 3 36 | knit - f12 3 37 | knit - f11 3 38 | knit - f10 3 39 | knit - f9 3 40 | knit - f8 3 41 | knit - f7 3 42 | knit - f6 3 43 | knit - f5 3 44 | knit - f4 3 45 | knit - f3 3 46 | knit - f2 3 47 | knit - f1 3 48 | knit - f0 3 49 | 50 | knit + f0 3 51 | knit + f1 3 52 | knit + f2 3 53 | knit + f3 3 54 | knit + f4 3 55 | knit + f5 3 56 | knit + f6 3 57 | knit + f7 3 58 | knit + f8 3 59 | knit + f9 3 60 | knit + f10 3 61 | knit + f11 3 62 | knit + f12 3 63 | knit + f13 3 64 | 65 | ; row 1 66 | 67 | xfer f11 b11 68 | xfer f10 b10 69 | xfer f7 b7 70 | xfer f6 b6 71 | 72 | xfer f3 b3 73 | xfer f2 b2 74 | 75 | knit - f13 3 76 | knit - f12 3 77 | knit - b11 3 78 | knit - b10 3 79 | knit - f9 3 80 | knit - f8 3 81 | knit - b7 3 82 | knit - b6 3 83 | knit - f5 3 84 | knit - f4 3 85 | knit - b3 3 86 | knit - b2 3 87 | knit - f1 3 88 | knit - f0 3 89 | 90 | ; row 2 91 | 92 | xfer b11 f11 93 | xfer f9 b9 94 | 95 | knit + f0 3 96 | knit + f1 3 97 | knit + b2 3 98 | knit + b3 3 99 | knit + f4 3 100 | knit + f5 3 101 | knit + b6 3 102 | knit + b7 3 103 | knit + f8 3 104 | knit + b9 3 105 | knit + b10 3 106 | knit + f11 3 107 | knit + f12 3 108 | knit + f13 3 109 | 110 | ; row 3 111 | 112 | xfer b10 f10 113 | xfer b3 f3 114 | xfer b2 f2 115 | 116 | xfer f8 b8 117 | 118 | knit - f13 3 119 | knit - f12 3 120 | knit - f11 3 121 | knit - f10 3 122 | knit - b9 3 123 | knit - b8 3 124 | knit - b7 3 125 | knit - b6 3 126 | knit - f5 3 127 | knit - f4 3 128 | knit - f3 3 129 | knit - f2 3 130 | knit - f1 3 131 | knit - f0 3 132 | 133 | ; row 4 134 | 135 | xfer b8 f8 136 | xfer f10 b10 137 | 138 | knit + f0 3 139 | knit + f1 3 140 | knit + f2 3 141 | knit + f3 3 142 | knit + f4 3 143 | knit + f5 3 144 | knit + b6 3 145 | knit + b7 3 146 | knit + f8 3 147 | knit + b9 3 148 | knit + b10 3 149 | knit + f11 3 150 | knit + f12 3 151 | knit + f13 3 152 | 153 | ; row 5 154 | 155 | xfer b9 f9 156 | xfer f11 b11 157 | 158 | knit - f13 3 159 | knit - f12 3 160 | knit - b11 3 161 | knit - b10 3 162 | knit - f9 3 163 | knit - f8 3 164 | knit - b7 3 165 | knit - b6 3 166 | knit - f5 3 167 | knit - f4 3 168 | knit - f3 3 169 | knit - f2 3 170 | knit - f1 3 171 | knit - f0 3 172 | 173 | ; row 6 174 | 175 | xfer b10 f10 176 | xfer b11 f11 177 | 178 | knit + f0 3 179 | knit + f1 3 180 | knit + f2 3 181 | knit + f3 3 182 | knit + f4 3 183 | knit + f5 3 184 | knit + b6 3 185 | knit + b7 3 186 | knit + f8 3 187 | knit + f9 3 188 | knit + f10 3 189 | knit + f11 3 190 | knit + f12 3 191 | knit + f13 3 192 | 193 | ; row 7 194 | 195 | knit - f13 3 196 | knit - f12 3 197 | knit - f11 3 198 | knit - f10 3 199 | knit - f9 3 200 | knit - f8 3 201 | knit - b7 3 202 | knit - b6 3 203 | knit - f5 3 204 | knit - f4 3 205 | knit - f3 3 206 | knit - f2 3 207 | knit - f1 3 208 | knit - f0 3 209 | 210 | xfer b6 f6 211 | xfer b7 f7 212 | 213 | ; some blank 214 | 215 | knit + f0 3 216 | knit + f1 3 217 | knit + f2 3 218 | knit + f3 3 219 | knit + f4 3 220 | knit + f5 3 221 | knit + f6 3 222 | knit + f7 3 223 | knit + f8 3 224 | knit + f9 3 225 | knit + f10 3 226 | knit + f11 3 227 | knit + f12 3 228 | knit + f13 3 229 | 230 | knit - f13 3 231 | knit - f12 3 232 | knit - f11 3 233 | knit - f10 3 234 | knit - f9 3 235 | knit - f8 3 236 | knit - f7 3 237 | knit - f6 3 238 | knit - f5 3 239 | knit - f4 3 240 | knit - f3 3 241 | knit - f2 3 242 | knit - f1 3 243 | knit - f0 3 244 | 245 | -------------------------------------------------------------------------------- /examples/k.yarns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textiles-lab/smobj/a0743546e88de8502a3538445b9b3b1c7a7a8628/examples/k.yarns -------------------------------------------------------------------------------- /examples/short-row-hinted-2.smobj: -------------------------------------------------------------------------------- 1 | L tuck-twist+ -lX +yX +lX -yX 2 | L knit- -lX -yX +lX +yX 3 | L edge( x -y1 +y1 x x 4 | L knit+ -lX +yX +lX -yX 5 | L turn)(( -lX +lX +yX -yX 6 | L drop -l1 +y0 +l0 -y0 7 | L edge) x x x +y1 -y1 8 | L knit-fair-isle-1+ -lX +yX +lX -yX 9 | L knit-fair-isle-2+ -lX +yX +lX -yX 10 | L knit-plating-1+ -lX +yX +lX -yX 11 | L knit-plating-2+ -lX +yX +lX -yX 12 | L purl+ -lX +yX +lX -yX 13 | L purl- -lX -yX +lX +yX 14 | v -5.27318 -3.6578 0 15 | v -3.24733 -3.62183 0 16 | v -3.30763 -2.4022 0 17 | v -5.31881 -2.42261 0 18 | v -3.24733 -3.62183 0 19 | v -1.1661 -3.52229 0 20 | v -1.298 -2.32309 0 21 | v -3.30763 -2.4022 0 22 | v -1.1661 -3.52229 0 23 | v 0.924188 -3.19641 0 24 | v 0.707455 -2.04497 0 25 | v -1.298 -2.32309 0 26 | v 0.924188 -3.19641 0 27 | v 2.80584 -2.5733 0 28 | v 2.57869 -1.32956 0 29 | v 0.707455 -2.04497 0 30 | v 2.80584 -2.5733 0 31 | v 4.66314 -2.36828 0 32 | v 4.54855 -1.15229 0 33 | v 2.57869 -1.32956 0 34 | v 4.66314 -2.36828 0 35 | v 6.61469 -2.33012 0 36 | v 6.55376 -1.11404 0 37 | v 4.54855 -1.15229 0 38 | v -5.31881 -2.42261 0 39 | v -3.30763 -2.4022 0 40 | v -3.36694 -1.17951 0 41 | v -5.35264 -1.1927 0 42 | v -3.30763 -2.4022 0 43 | v -1.298 -2.32309 0 44 | v -1.4028 -1.13447 0 45 | v -3.36694 -1.17951 0 46 | v -1.298 -2.32309 0 47 | v 0.707455 -2.04497 0 48 | v 0.520227 -1.0235 0 49 | v -1.4028 -1.13447 0 50 | v 0.707455 -2.04497 0 51 | v 2.57869 -1.32956 0 52 | v 2.29216 0.0499119 0 53 | v 0.520227 -1.0235 0 54 | v 2.57869 -1.32956 0 55 | v 4.54855 -1.15229 0 56 | v 4.46237 0.0516259 0 57 | v 2.29216 0.0499119 0 58 | v 4.54855 -1.15229 0 59 | v 6.55376 -1.11404 0 60 | v 6.49917 0.0707092 0 61 | v 4.46237 0.0516259 0 62 | v -6.33017 -2.41747 0 63 | v -5.31881 -2.42261 0 64 | v -5.35264 -1.1927 0 65 | v -5.36816 0.04293 0 66 | v -6.36275 0.0419961 0 67 | v -6.36275 0.0419961 0 68 | v -5.36816 0.04293 0 69 | v -5.35496 1.27859 0 70 | v -5.32343 2.50856 0 71 | v -6.33479 2.50152 0 72 | v -5.35264 -1.1927 0 73 | v -3.36694 -1.17951 0 74 | v -3.38929 0.0447948 0 75 | v -5.36816 0.04293 0 76 | v -3.36694 -1.17951 0 77 | v -1.4028 -1.13447 0 78 | v -1.42741 0.0466406 0 79 | v -3.38929 0.0447948 0 80 | v -1.4028 -1.13447 0 81 | v 0.520227 -1.0235 0 82 | v 0.558813 0.0484673 0 83 | v -1.42741 0.0466406 0 84 | v 0.520227 -1.0235 0 85 | v 2.29216 0.0499119 0 86 | v 0.518215 1.12039 0 87 | v 0.558813 0.0484673 0 88 | v -5.36816 0.04293 0 89 | v -3.38929 0.0447948 0 90 | v -3.36923 1.26914 0 91 | v -5.35496 1.27859 0 92 | v -3.38929 0.0447948 0 93 | v -1.42741 0.0466406 0 94 | v -1.40501 1.22781 0 95 | v -3.36923 1.26914 0 96 | v -1.42741 0.0466406 0 97 | v 0.558813 0.0484673 0 98 | v 0.518215 1.12039 0 99 | v -1.40501 1.22781 0 100 | v -5.35496 1.27859 0 101 | v -3.36923 1.26914 0 102 | v -3.31222 2.49195 0 103 | v -5.32343 2.50856 0 104 | v -3.36923 1.26914 0 105 | v -1.40501 1.22781 0 106 | v -1.30242 2.41665 0 107 | v -3.31222 2.49195 0 108 | v -1.40501 1.22781 0 109 | v 0.518215 1.12039 0 110 | v 0.703535 2.14236 0 111 | v -1.30242 2.41665 0 112 | v 0.518215 1.12039 0 113 | v 2.29216 0.0499119 0 114 | v 2.57553 1.43039 0 115 | v 0.703535 2.14236 0 116 | v 2.29216 0.0499119 0 117 | v 4.46237 0.0516259 0 118 | v 4.54233 1.25469 0 119 | v 2.57553 1.43039 0 120 | v 4.46237 0.0516259 0 121 | v 6.49917 0.0707092 0 122 | v 6.54366 1.20977 0 123 | v 4.54233 1.25469 0 124 | v -5.32343 2.50856 0 125 | v -3.31222 2.49195 0 126 | v -3.25422 3.71168 0 127 | v -5.28013 3.74383 0 128 | v -3.31222 2.49195 0 129 | v -1.30242 2.41665 0 130 | v -1.17279 3.61612 0 131 | v -3.25422 3.71168 0 132 | v -1.30242 2.41665 0 133 | v 0.703535 2.14236 0 134 | v 0.918221 3.2943 0 135 | v -1.17279 3.61612 0 136 | v 0.703535 2.14236 0 137 | v 2.57553 1.43039 0 138 | v 2.80179 2.67489 0 139 | v 0.918221 3.2943 0 140 | v 2.57553 1.43039 0 141 | v 4.54233 1.25469 0 142 | v 4.6624 2.46941 0 143 | v 2.80179 2.67489 0 144 | v 4.54233 1.25469 0 145 | v 6.54366 1.20977 0 146 | v 6.61623 2.40042 0 147 | v 4.6624 2.46941 0 148 | v 6.61469 -2.33012 0 149 | v 7.61322 -2.29514 0 150 | v 7.49623 0.142057 0 151 | v 6.49917 0.0707092 0 152 | v 6.55376 -1.11404 0 153 | f 1 2 3 4 154 | T 1 155 | N 0 156 | f 5 6 7 8 157 | T 1 158 | N 0 159 | f 9 10 11 12 160 | T 1 161 | N 0 162 | f 13 14 15 16 163 | T 1 164 | N 0 165 | f 17 18 19 20 166 | T 1 167 | N 0 168 | f 21 22 23 24 169 | T 1 170 | N 0 171 | f 25 26 27 28 172 | T 13 173 | N 0 174 | f 29 30 31 32 175 | T 13 176 | N 0 177 | f 33 34 35 36 178 | T 13 179 | N 0 180 | f 37 38 39 40 181 | T 2 182 | N 0 183 | f 41 42 43 44 184 | T 2 185 | N 0 186 | f 45 46 47 48 187 | T 2 188 | N 0 189 | f 49 50 51 52 53 190 | T 3 191 | N 0 192 | f 54 55 56 57 58 193 | T 3 194 | N 0 195 | f 59 60 61 62 196 | T 4 197 | N 0 198 | f 63 64 65 66 199 | T 4 200 | N 0 201 | f 67 68 69 70 202 | T 4 203 | N 0 204 | f 71 72 73 74 205 | T 5 206 | N 0 207 | f 75 76 77 78 208 | T 2 209 | N 0 210 | f 79 80 81 82 211 | T 2 212 | N 0 213 | f 83 84 85 86 214 | T 2 215 | N 0 216 | f 87 88 89 90 217 | T 4 218 | N 0 219 | f 91 92 93 94 220 | T 4 221 | N 0 222 | f 95 96 97 98 223 | T 4 224 | N 0 225 | f 99 100 101 102 226 | T 4 227 | N 0 228 | f 103 104 105 106 229 | T 4 230 | N 0 231 | f 107 108 109 110 232 | T 4 233 | N 0 234 | f 111 112 113 114 235 | T 6 236 | N 0 237 | f 115 116 117 118 238 | T 6 239 | N 0 240 | f 119 120 121 122 241 | T 6 242 | N 0 243 | f 123 124 125 126 244 | T 6 245 | N 0 246 | f 127 128 129 130 247 | T 6 248 | N 0 249 | f 131 132 133 134 250 | T 6 251 | N 0 252 | f 135 136 137 138 139 253 | T 7 254 | N 0 255 | e 1/2 2/-4 256 | e 1/3 7/-1 257 | e 2/2 3/-4 258 | e 2/3 8/-1 259 | e 3/2 4/-4 260 | e 3/3 9/-1 261 | e 4/2 5/-4 262 | e 4/3 10/-1 263 | e 5/2 6/-4 264 | e 5/3 11/-1 265 | e 6/2 34/-5 266 | e 6/3 12/-1 267 | e 7/2 8/-4 268 | e 7/3 15/-1 269 | e 7/4 13/-2 270 | e 8/2 9/-4 271 | e 8/3 16/-1 272 | e 9/2 10/-4 273 | e 9/3 17/-1 274 | e 10/2 11/-4 275 | e 10/3 18/-1 276 | e 11/2 12/-4 277 | e 11/3 26/-1 278 | e 12/2 34/-4 279 | e 12/3 27/-1 280 | e 13/3 15/-4 281 | e 13/4 14/-1 282 | e 14/2 19/-4 283 | e 14/3 22/-4 284 | e 15/2 16/-4 285 | e 15/3 19/-1 286 | e 16/2 17/-4 287 | e 16/3 20/-1 288 | e 17/2 18/-4 289 | e 17/3 21/-1 290 | e 18/2 25/-1 291 | e 18/3 21/-2 292 | e 19/2 20/-4 293 | e 19/3 22/-1 294 | e 20/2 21/-4 295 | e 20/3 23/-1 296 | e 21/3 24/-1 297 | e 22/2 23/-4 298 | e 22/3 28/-1 299 | e 23/2 24/-4 300 | e 23/3 29/-1 301 | e 24/2 25/-4 302 | e 24/3 30/-1 303 | e 25/2 26/-4 304 | e 25/3 31/-1 305 | e 26/2 27/-4 306 | e 26/3 32/-1 307 | e 27/3 33/-1 308 | e 28/2 29/-4 309 | e 29/2 30/-4 310 | e 30/2 31/-4 311 | e 31/2 32/-4 312 | e 32/2 33/-4 313 | h 1/1 f1 u 314 | h 2/1 f2 u 315 | h 3/1 f3 u 316 | h 4/1 f4 u 317 | h 5/1 f5 u 318 | h 6/1 f6 u 319 | o 22/1 28/1 u 320 | o 9/1 8/1 u 321 | o 8/1 7/1 u 322 | o 9/2 8/2 u 323 | o 8/2 7/2 u 324 | o 7/1 9/2 u 325 | o 7/2 9/3 u 326 | o 9/3 8/3 u 327 | o 8/3 7/3 u 328 | t 1 front h 329 | t 2 front h 330 | t 3 front h 331 | t 4 front h 332 | t 5 front h 333 | t 6 front h 334 | h 1/2 f1.5 i 335 | h 1/3 f1 i 336 | h 1/4 f0.5 i 337 | h 2/2 f2.5 i 338 | h 2/3 f2 i 339 | h 2/4 f1.5 i 340 | h 3/2 f3.5 i 341 | h 3/3 f3 i 342 | h 3/4 f2.5 i 343 | h 4/2 f4.5 i 344 | h 4/3 f4 i 345 | h 4/4 f3.5 i 346 | h 5/2 f5.5 i 347 | h 5/3 f5 i 348 | h 5/4 f4.5 i 349 | h 6/2 f6.5 i 350 | h 6/3 f6 i 351 | h 6/4 f5.5 i 352 | h 7/1 f1 i 353 | h 8/1 f2 i 354 | h 9/1 f3 i 355 | h 10/1 f4 i 356 | h 11/1 f5 i 357 | h 12/1 f6 i 358 | h 34/5 f6.5 h 359 | o 1/1 1/2 h 360 | o 2/1 2/2 h 361 | o 3/1 3/2 h 362 | o 4/1 4/2 h 363 | o 5/1 5/2 h 364 | o 6/1 6/2 h 365 | t 7 front h 366 | t 8 front h 367 | t 9 front h 368 | t 10 front h 369 | t 11 front h 370 | t 12 front h 371 | t 34 front h 372 | h 7/2 f1.5 i 373 | h 7/3 f1 i 374 | h 7/4 f0.5 i 375 | h 8/2 f2.5 i 376 | h 8/3 f2 i 377 | h 8/4 f1.5 i 378 | h 9/2 f3.5 i 379 | h 9/3 f3 i 380 | h 9/4 f2.5 i 381 | h 10/2 f4.5 i 382 | h 10/3 f4 i 383 | h 10/4 f3.5 i 384 | h 11/2 f5.5 i 385 | h 11/3 f5 i 386 | h 11/4 f4.5 i 387 | h 12/2 f6.5 i 388 | h 12/3 f6 i 389 | h 12/4 f5.5 i 390 | h 13/2 f0.5 h 391 | h 15/1 f1 i 392 | h 16/1 f2 i 393 | h 17/1 f3 i 394 | h 18/1 f4 i 395 | h 26/1 f5 i 396 | h 27/1 f6 i 397 | h 34/1 x7 h 398 | h 34/2 x7 h 399 | h 34/3 x7 h 400 | h 34/4 f6.5 h 401 | o 9/1 9/2 h 402 | o 9/2 9/3 h 403 | o 8/1 8/2 h 404 | o 8/2 8/3 h 405 | o 7/1 7/2 h 406 | o 7/2 7/3 h 407 | t 13 front h 408 | t 15 front h 409 | t 16 front h 410 | t 17 front h 411 | t 18 front h 412 | t 26 front h 413 | t 27 front h 414 | h 13/1 x0 h 415 | h 13/3 f0.5 h 416 | h 13/4 x0 h 417 | h 13/5 x0 h 418 | h 14/1 x0 h 419 | h 15/2 f1.5 i 420 | h 15/3 f1 i 421 | h 15/4 f0.5 i 422 | h 16/2 f2.5 i 423 | h 16/3 f2 i 424 | h 16/4 f1.5 i 425 | h 17/2 f3.5 i 426 | h 17/3 f3 i 427 | h 17/4 f2.5 i 428 | h 18/2 f4 i 429 | h 18/3 f3.5 i 430 | h 18/4 f3.5 i 431 | h 19/1 f1 i 432 | h 20/1 f2 i 433 | h 21/1 f3 i 434 | h 21/2 f3.5 h 435 | h 25/1 f4 i 436 | h 25/2 f4.5 h 437 | h 26/2 f5.5 i 438 | h 26/3 f5 i 439 | h 26/4 f4.5 i 440 | h 27/2 f6.5 i 441 | h 27/3 f6 i 442 | h 27/4 f5.5 i 443 | h 32/1 f5 i 444 | h 33/1 f6 i 445 | t 14 front h 446 | t 19 front h 447 | t 20 front h 448 | t 21 front h 449 | t 25 front h 450 | t 32 front h 451 | t 33 front h 452 | h 14/2 f0.5 h 453 | h 19/2 f1.5 i 454 | h 19/3 f1 i 455 | h 19/4 f0.5 i 456 | h 20/2 f2.5 i 457 | h 20/3 f2 i 458 | h 20/4 f1.5 i 459 | h 21/3 f3 h 460 | h 21/4 f2.5 h 461 | h 22/1 f1 i 462 | h 23/1 f2 i 463 | h 24/1 f3 h 464 | h 24/2 f3.5 h 465 | h 25/3 f4 h 466 | h 25/4 f3.5 h 467 | h 31/1 f4 h 468 | h 31/2 f4.5 h 469 | h 32/2 f5.5 i 470 | h 32/3 x5 i 471 | h 32/4 f4.5 i 472 | h 33/2 f6.5 i 473 | h 33/3 x6 i 474 | h 33/4 f5.5 i 475 | t 22 front h 476 | t 23 front h 477 | t 24 front h 478 | t 31 front h 479 | h 14/3 f0.5 h 480 | h 14/4 x0 h 481 | h 14/5 x0 h 482 | h 22/2 f1.5 i 483 | h 22/3 f1 i 484 | h 22/4 f0.5 i 485 | h 23/2 f2.5 i 486 | h 23/3 f2 i 487 | h 23/4 f1.5 i 488 | h 24/3 f3 h 489 | h 24/4 f2.5 h 490 | h 28/1 f1 i 491 | h 29/1 f2 i 492 | h 30/1 f3 h 493 | h 30/2 f3.5 h 494 | h 31/3 x4 h 495 | h 31/4 f3.5 h 496 | t 28 front h 497 | t 29 front h 498 | t 30 front h 499 | h 28/2 f1.5 i 500 | h 28/3 x1 i 501 | h 28/4 f0.5 i 502 | h 29/2 f2.5 i 503 | h 29/3 x2 i 504 | h 29/4 f1.5 i 505 | h 30/3 x3 h 506 | h 30/4 f2.5 h 507 | o 1/2 2/1 u 508 | o 2/2 3/1 u 509 | o 3/2 4/1 u 510 | o 4/2 5/1 u 511 | o 5/2 6/1 u 512 | o 6/2 12/1 u 513 | o 12/1 11/1 u 514 | o 11/1 10/1 u 515 | o 10/1 9/1 u 516 | o 7/3 15/1 u 517 | o 15/1 16/1 u 518 | o 16/1 17/1 u 519 | o 17/1 18/1 u 520 | o 21/1 20/1 u 521 | o 20/1 19/1 u 522 | o 19/1 22/1 u 523 | o 22/1 23/1 u 524 | o 23/1 24/1 u 525 | o 24/1 25/1 u 526 | o 25/1 26/1 u 527 | o 26/1 27/1 u 528 | o 28/1 29/1 u 529 | o 29/1 30/1 u 530 | o 30/1 31/1 u 531 | o 31/1 32/1 u 532 | o 32/1 33/1 u 533 | o 27/1 28/1 u 534 | o 18/2 21/1 u 535 | I 1/1 536 | I 1/2 537 | I 2/1 538 | I 2/2 539 | I 3/1 540 | I 3/2 541 | I 4/1 542 | I 4/2 543 | I 5/1 544 | I 5/2 545 | I 6/1 546 | I 6/2 547 | I 12/1 548 | I 11/1 549 | I 10/1 550 | I 9/1 551 | I 8/1 552 | I 7/1 553 | I 9/2 554 | I 8/2 555 | I 7/2 556 | I 9/3 557 | I 8/3 558 | I 7/3 559 | I 15/1 560 | I 16/1 561 | I 17/1 562 | I 18/1 563 | I 18/2 564 | I 21/1 565 | I 20/1 566 | I 19/1 567 | I 22/1 568 | I 23/1 569 | I 24/1 570 | I 25/1 571 | I 26/1 572 | I 27/1 573 | I 28/1 574 | I 29/1 575 | I 30/1 576 | I 31/1 577 | I 32/1 578 | I 33/1 579 | -------------------------------------------------------------------------------- /examples/short-row-hinted.smobj: -------------------------------------------------------------------------------- 1 | L tuck-twist+ -lX +yX +lX -yX 2 | L knit- -lX -yX +lX +yX 3 | L edge( x -y1 +y1 x x 4 | L knit+ -lX +yX +lX -yX 5 | L turn)(( -lX +lX +yX -yX 6 | L drop -l1 +y0 +l0 -y0 7 | L edge) x x x +y1 -y1 8 | L knit-fair-isle-1+ -lX +yX +lX -yX 9 | L knit-fair-isle-2+ -lX +yX +lX -yX 10 | L knit-plating-1+ -lX +yX +lX -yX 11 | L knit-plating-2+ -lX +yX +lX -yX 12 | L purl+ -lX +yX +lX -yX 13 | L purl- -lX -yX +lX +yX 14 | v -5.27318 -3.6578 0 15 | v -3.24733 -3.62183 0 16 | v -3.30763 -2.4022 0 17 | v -5.31881 -2.42261 0 18 | v -3.24733 -3.62183 0 19 | v -1.1661 -3.52229 0 20 | v -1.298 -2.32309 0 21 | v -3.30763 -2.4022 0 22 | v -1.1661 -3.52229 0 23 | v 0.924188 -3.19641 0 24 | v 0.707455 -2.04497 0 25 | v -1.298 -2.32309 0 26 | v 0.924188 -3.19641 0 27 | v 2.80584 -2.5733 0 28 | v 2.57869 -1.32956 0 29 | v 0.707455 -2.04497 0 30 | v 2.80584 -2.5733 0 31 | v 4.66314 -2.36828 0 32 | v 4.54855 -1.15229 0 33 | v 2.57869 -1.32956 0 34 | v 4.66314 -2.36828 0 35 | v 6.61469 -2.33012 0 36 | v 6.55376 -1.11404 0 37 | v 4.54855 -1.15229 0 38 | v -5.31881 -2.42261 0 39 | v -3.30763 -2.4022 0 40 | v -3.36694 -1.17951 0 41 | v -5.35264 -1.1927 0 42 | v -3.30763 -2.4022 0 43 | v -1.298 -2.32309 0 44 | v -1.4028 -1.13447 0 45 | v -3.36694 -1.17951 0 46 | v -1.298 -2.32309 0 47 | v 0.707455 -2.04497 0 48 | v 0.520227 -1.0235 0 49 | v -1.4028 -1.13447 0 50 | v 0.707455 -2.04497 0 51 | v 2.57869 -1.32956 0 52 | v 2.29216 0.0499119 0 53 | v 0.520227 -1.0235 0 54 | v 2.57869 -1.32956 0 55 | v 4.54855 -1.15229 0 56 | v 4.46237 0.0516259 0 57 | v 2.29216 0.0499119 0 58 | v 4.54855 -1.15229 0 59 | v 6.55376 -1.11404 0 60 | v 6.49917 0.0707092 0 61 | v 4.46237 0.0516259 0 62 | v -6.33017 -2.41747 0 63 | v -5.31881 -2.42261 0 64 | v -5.35264 -1.1927 0 65 | v -5.36816 0.04293 0 66 | v -6.36275 0.0419961 0 67 | v -6.36275 0.0419961 0 68 | v -5.36816 0.04293 0 69 | v -5.35496 1.27859 0 70 | v -5.32343 2.50856 0 71 | v -6.33479 2.50152 0 72 | v -5.35264 -1.1927 0 73 | v -3.36694 -1.17951 0 74 | v -3.38929 0.0447948 0 75 | v -5.36816 0.04293 0 76 | v -3.36694 -1.17951 0 77 | v -1.4028 -1.13447 0 78 | v -1.42741 0.0466406 0 79 | v -3.38929 0.0447948 0 80 | v -1.4028 -1.13447 0 81 | v 0.520227 -1.0235 0 82 | v 0.558813 0.0484673 0 83 | v -1.42741 0.0466406 0 84 | v 0.520227 -1.0235 0 85 | v 2.29216 0.0499119 0 86 | v 0.518215 1.12039 0 87 | v 0.558813 0.0484673 0 88 | v -5.36816 0.04293 0 89 | v -3.38929 0.0447948 0 90 | v -3.36923 1.26914 0 91 | v -5.35496 1.27859 0 92 | v -3.38929 0.0447948 0 93 | v -1.42741 0.0466406 0 94 | v -1.40501 1.22781 0 95 | v -3.36923 1.26914 0 96 | v -1.42741 0.0466406 0 97 | v 0.558813 0.0484673 0 98 | v 0.518215 1.12039 0 99 | v -1.40501 1.22781 0 100 | v -5.35496 1.27859 0 101 | v -3.36923 1.26914 0 102 | v -3.31222 2.49195 0 103 | v -5.32343 2.50856 0 104 | v -3.36923 1.26914 0 105 | v -1.40501 1.22781 0 106 | v -1.30242 2.41665 0 107 | v -3.31222 2.49195 0 108 | v -1.40501 1.22781 0 109 | v 0.518215 1.12039 0 110 | v 0.703535 2.14236 0 111 | v -1.30242 2.41665 0 112 | v 0.518215 1.12039 0 113 | v 2.29216 0.0499119 0 114 | v 2.57553 1.43039 0 115 | v 0.703535 2.14236 0 116 | v 2.29216 0.0499119 0 117 | v 4.46237 0.0516259 0 118 | v 4.54233 1.25469 0 119 | v 2.57553 1.43039 0 120 | v 4.46237 0.0516259 0 121 | v 6.49917 0.0707092 0 122 | v 6.54366 1.20977 0 123 | v 4.54233 1.25469 0 124 | v -5.32343 2.50856 0 125 | v -3.31222 2.49195 0 126 | v -3.25422 3.71168 0 127 | v -5.28013 3.74383 0 128 | v -3.31222 2.49195 0 129 | v -1.30242 2.41665 0 130 | v -1.17279 3.61612 0 131 | v -3.25422 3.71168 0 132 | v -1.30242 2.41665 0 133 | v 0.703535 2.14236 0 134 | v 0.918221 3.2943 0 135 | v -1.17279 3.61612 0 136 | v 0.703535 2.14236 0 137 | v 2.57553 1.43039 0 138 | v 2.80179 2.67489 0 139 | v 0.918221 3.2943 0 140 | v 2.57553 1.43039 0 141 | v 4.54233 1.25469 0 142 | v 4.6624 2.46941 0 143 | v 2.80179 2.67489 0 144 | v 4.54233 1.25469 0 145 | v 6.54366 1.20977 0 146 | v 6.61623 2.40042 0 147 | v 4.6624 2.46941 0 148 | v 6.61469 -2.33012 0 149 | v 7.61322 -2.29514 0 150 | v 7.49623 0.142057 0 151 | v 6.49917 0.0707092 0 152 | v 6.55376 -1.11404 0 153 | f 1 2 3 4 154 | T 1 155 | N 0 156 | f 5 6 7 8 157 | T 1 158 | N 0 159 | f 9 10 11 12 160 | T 1 161 | N 0 162 | f 13 14 15 16 163 | T 1 164 | N 0 165 | f 17 18 19 20 166 | T 1 167 | N 0 168 | f 21 22 23 24 169 | T 1 170 | N 0 171 | f 25 26 27 28 172 | T 13 173 | N 0 174 | f 29 30 31 32 175 | T 13 176 | N 0 177 | f 33 34 35 36 178 | T 13 179 | N 0 180 | f 37 38 39 40 181 | T 2 182 | N 0 183 | f 41 42 43 44 184 | T 2 185 | N 0 186 | f 45 46 47 48 187 | T 2 188 | N 0 189 | f 49 50 51 52 53 190 | T 3 191 | N 0 192 | f 54 55 56 57 58 193 | T 3 194 | N 0 195 | f 59 60 61 62 196 | T 4 197 | N 0 198 | f 63 64 65 66 199 | T 4 200 | N 0 201 | f 67 68 69 70 202 | T 4 203 | N 0 204 | f 71 72 73 74 205 | T 5 206 | N 0 207 | f 75 76 77 78 208 | T 2 209 | N 0 210 | f 79 80 81 82 211 | T 2 212 | N 0 213 | f 83 84 85 86 214 | T 2 215 | N 0 216 | f 87 88 89 90 217 | T 4 218 | N 0 219 | f 91 92 93 94 220 | T 4 221 | N 0 222 | f 95 96 97 98 223 | T 4 224 | N 0 225 | f 99 100 101 102 226 | T 4 227 | N 0 228 | f 103 104 105 106 229 | T 4 230 | N 0 231 | f 107 108 109 110 232 | T 4 233 | N 0 234 | f 111 112 113 114 235 | T 6 236 | N 0 237 | f 115 116 117 118 238 | T 6 239 | N 0 240 | f 119 120 121 122 241 | T 6 242 | N 0 243 | f 123 124 125 126 244 | T 6 245 | N 0 246 | f 127 128 129 130 247 | T 6 248 | N 0 249 | f 131 132 133 134 250 | T 6 251 | N 0 252 | f 135 136 137 138 139 253 | T 7 254 | N 0 255 | e 1/2 2/-4 256 | e 1/3 7/-1 257 | e 2/2 3/-4 258 | e 2/3 8/-1 259 | e 3/2 4/-4 260 | e 3/3 9/-1 261 | e 4/2 5/-4 262 | e 4/3 10/-1 263 | e 5/2 6/-4 264 | e 5/3 11/-1 265 | e 6/2 34/-5 266 | e 6/3 12/-1 267 | e 7/2 8/-4 268 | e 7/3 15/-1 269 | e 7/4 13/-2 270 | e 8/2 9/-4 271 | e 8/3 16/-1 272 | e 9/2 10/-4 273 | e 9/3 17/-1 274 | e 10/2 11/-4 275 | e 10/3 18/-1 276 | e 11/2 12/-4 277 | e 11/3 26/-1 278 | e 12/2 34/-4 279 | e 12/3 27/-1 280 | e 13/3 15/-4 281 | e 13/4 14/-1 282 | e 14/2 19/-4 283 | e 14/3 22/-4 284 | e 15/2 16/-4 285 | e 15/3 19/-1 286 | e 16/2 17/-4 287 | e 16/3 20/-1 288 | e 17/2 18/-4 289 | e 17/3 21/-1 290 | e 18/2 25/-1 291 | e 18/3 21/-2 292 | e 19/2 20/-4 293 | e 19/3 22/-1 294 | e 20/2 21/-4 295 | e 20/3 23/-1 296 | e 21/3 24/-1 297 | e 22/2 23/-4 298 | e 22/3 28/-1 299 | e 23/2 24/-4 300 | e 23/3 29/-1 301 | e 24/2 25/-4 302 | e 24/3 30/-1 303 | e 25/2 26/-4 304 | e 25/3 31/-1 305 | e 26/2 27/-4 306 | e 26/3 32/-1 307 | e 27/3 33/-1 308 | e 28/2 29/-4 309 | e 29/2 30/-4 310 | e 30/2 31/-4 311 | e 31/2 32/-4 312 | e 32/2 33/-4 313 | h 1/1 f1 u 314 | h 2/1 f2 u 315 | h 3/1 f3 u 316 | h 4/1 f4 u 317 | h 5/1 f5 u 318 | h 6/1 f6 u 319 | t 1 front h 320 | t 2 front h 321 | t 3 front h 322 | t 4 front h 323 | t 5 front h 324 | t 6 front h 325 | h 1/2 f1.5 i 326 | h 1/3 f1 i 327 | h 1/4 f0.5 i 328 | h 2/2 f2.5 i 329 | h 2/3 f2 i 330 | h 2/4 f1.5 i 331 | h 3/2 f3.5 i 332 | h 3/3 f3 i 333 | h 3/4 f2.5 i 334 | h 4/2 f4.5 i 335 | h 4/3 f4 i 336 | h 4/4 f3.5 i 337 | h 5/2 f5.5 i 338 | h 5/3 f5 i 339 | h 5/4 f4.5 i 340 | h 6/2 f6.5 i 341 | h 6/3 f6 i 342 | h 6/4 f5.5 i 343 | h 7/1 f1 i 344 | h 8/1 f2 i 345 | h 9/1 f3 i 346 | h 10/1 f4 i 347 | h 11/1 f5 i 348 | h 12/1 f6 i 349 | h 34/5 f6.5 h 350 | o 1/1 1/2 h 351 | o 2/1 2/2 h 352 | o 3/1 3/2 h 353 | o 4/1 4/2 h 354 | o 5/1 5/2 h 355 | o 6/1 6/2 h 356 | t 7 front h 357 | t 8 front h 358 | t 9 front h 359 | t 10 front h 360 | t 11 front h 361 | t 12 front h 362 | t 34 front h 363 | h 7/2 f1.5 i 364 | h 7/3 f1 i 365 | h 7/4 f0.5 i 366 | h 8/2 f2.5 i 367 | h 8/3 f2 i 368 | h 8/4 f1.5 i 369 | h 9/2 f3.5 i 370 | h 9/3 f3 i 371 | h 9/4 f2.5 i 372 | h 10/2 f4.5 i 373 | h 10/3 f4 i 374 | h 10/4 f3.5 i 375 | h 11/2 f5.5 i 376 | h 11/3 f5 i 377 | h 11/4 f4.5 i 378 | h 12/2 f6.5 i 379 | h 12/3 f6 i 380 | h 12/4 f5.5 i 381 | h 13/2 f0.5 h 382 | h 15/1 f1 i 383 | h 16/1 f2 i 384 | h 17/1 f3 i 385 | h 18/1 f4 i 386 | h 26/1 f5 i 387 | h 27/1 f6 i 388 | h 34/1 x7 h 389 | h 34/2 x7 h 390 | h 34/3 x7 h 391 | h 34/4 f6.5 h 392 | o 9/1 9/2 h 393 | o 9/2 9/3 h 394 | o 8/1 8/2 h 395 | o 8/2 8/3 h 396 | o 7/1 7/2 h 397 | o 7/2 7/3 h 398 | t 13 front h 399 | t 15 front h 400 | t 16 front h 401 | t 17 front h 402 | t 18 front h 403 | t 26 front h 404 | t 27 front h 405 | h 13/1 x0 h 406 | h 13/3 f0.5 h 407 | h 13/4 x0 h 408 | h 13/5 x0 h 409 | h 14/1 x0 h 410 | h 15/2 f1.5 i 411 | h 15/3 f1 i 412 | h 15/4 f0.5 i 413 | h 16/2 f2.5 i 414 | h 16/3 f2 i 415 | h 16/4 f1.5 i 416 | h 17/2 f3.5 i 417 | h 17/3 f3 i 418 | h 17/4 f2.5 i 419 | h 18/2 f4 i 420 | h 18/3 f3.5 i 421 | h 18/4 f3.5 i 422 | h 19/1 f1 i 423 | h 20/1 f2 i 424 | h 21/1 f3 i 425 | h 21/2 f3.5 h 426 | h 25/1 f4 i 427 | h 25/2 f4.5 h 428 | h 26/2 f5.5 i 429 | h 26/3 f5 i 430 | h 26/4 f4.5 i 431 | h 27/2 f6.5 i 432 | h 27/3 f6 i 433 | h 27/4 f5.5 i 434 | h 32/1 f5 i 435 | h 33/1 f6 i 436 | t 14 front h 437 | t 19 front h 438 | t 20 front h 439 | t 21 front h 440 | t 25 front h 441 | t 32 front h 442 | t 33 front h 443 | h 14/2 f0.5 h 444 | h 19/2 f1.5 i 445 | h 19/3 f1 i 446 | h 19/4 f0.5 i 447 | h 20/2 f2.5 i 448 | h 20/3 f2 i 449 | h 20/4 f1.5 i 450 | h 21/3 f3 h 451 | h 21/4 f2.5 h 452 | h 22/1 f1 i 453 | h 23/1 f2 i 454 | h 24/1 f3 h 455 | h 24/2 f3.5 h 456 | h 25/3 f4 h 457 | h 25/4 f3.5 h 458 | h 31/1 f4 h 459 | h 31/2 f4.5 h 460 | h 32/2 f5.5 i 461 | h 32/3 x5 i 462 | h 32/4 f4.5 i 463 | h 33/2 f6.5 i 464 | h 33/3 x6 i 465 | h 33/4 f5.5 i 466 | t 22 front h 467 | t 23 front h 468 | t 24 front h 469 | t 31 front h 470 | h 14/3 f0.5 h 471 | h 14/4 x0 h 472 | h 14/5 x0 h 473 | h 22/2 f1.5 i 474 | h 22/3 f1 i 475 | h 22/4 f0.5 i 476 | h 23/2 f2.5 i 477 | h 23/3 f2 i 478 | h 23/4 f1.5 i 479 | h 24/3 f3 h 480 | h 24/4 f2.5 h 481 | h 28/1 f1 i 482 | h 29/1 f2 i 483 | h 30/1 f3 h 484 | h 30/2 f3.5 h 485 | h 31/3 x4 h 486 | h 31/4 f3.5 h 487 | t 28 front h 488 | t 29 front h 489 | t 30 front h 490 | h 28/2 f1.5 i 491 | h 28/3 x1 i 492 | h 28/4 f0.5 i 493 | h 29/2 f2.5 i 494 | h 29/3 x2 i 495 | h 29/4 f1.5 i 496 | h 30/3 x3 h 497 | h 30/4 f2.5 h 498 | o 1/2 2/1 u 499 | o 2/2 3/1 u 500 | o 3/2 4/1 u 501 | o 4/2 5/1 u 502 | o 5/2 6/1 u 503 | o 6/2 12/1 u 504 | o 12/1 11/1 u 505 | o 11/1 10/1 u 506 | o 10/1 9/1 u 507 | o 9/3 8/1 u 508 | o 8/3 7/1 u 509 | o 7/3 15/1 u 510 | o 15/1 16/1 u 511 | o 16/1 17/1 u 512 | o 17/1 18/1 u 513 | o 21/1 20/1 u 514 | o 20/1 19/1 u 515 | o 19/1 22/1 u 516 | o 22/1 23/1 u 517 | o 23/1 24/1 u 518 | o 24/1 25/1 u 519 | o 25/1 26/1 u 520 | o 26/1 27/1 u 521 | o 27/1 28/1 u 522 | o 28/1 29/1 u 523 | o 29/1 30/1 u 524 | o 30/1 31/1 u 525 | o 31/1 32/1 u 526 | o 32/1 33/1 u 527 | o 18/2 21/1 u 528 | I 1/1 529 | I 1/2 530 | I 2/1 531 | I 2/2 532 | I 3/1 533 | I 3/2 534 | I 4/1 535 | I 4/2 536 | I 5/1 537 | I 5/2 538 | I 6/1 539 | I 6/2 540 | I 12/1 541 | I 11/1 542 | I 10/1 543 | I 9/1 544 | I 9/2 545 | I 9/3 546 | I 8/1 547 | I 8/2 548 | I 8/3 549 | I 7/1 550 | I 7/2 551 | I 7/3 552 | I 15/1 553 | I 16/1 554 | I 17/1 555 | I 18/1 556 | I 18/2 557 | I 21/1 558 | I 20/1 559 | I 19/1 560 | I 22/1 561 | I 23/1 562 | I 24/1 563 | I 25/1 564 | I 26/1 565 | I 27/1 566 | I 28/1 567 | I 29/1 568 | I 30/1 569 | I 31/1 570 | I 32/1 571 | I 33/1 572 | -------------------------------------------------------------------------------- /examples/short-row.smobj: -------------------------------------------------------------------------------- 1 | L tuck-twist+ -lX +yX +lX -yX 2 | L knit- -lX -yX +lX +yX 3 | L edge( x -y1 +y1 x x 4 | L knit+ -lX +yX +lX -yX 5 | L turn)(( -lX +lX +yX -yX 6 | L drop -l1 +y0 +l0 -y0 7 | L edge) x x x +y1 -y1 8 | v -5.27318 -3.6578 0 9 | v -3.24733 -3.62183 0 10 | v -3.30763 -2.4022 0 11 | v -5.31881 -2.42261 0 12 | v -3.24733 -3.62183 0 13 | v -1.1661 -3.52229 0 14 | v -1.298 -2.32309 0 15 | v -3.30763 -2.4022 0 16 | v -1.1661 -3.52229 0 17 | v 0.924188 -3.19641 0 18 | v 0.707455 -2.04497 0 19 | v -1.298 -2.32309 0 20 | v 0.924188 -3.19641 0 21 | v 2.80584 -2.5733 0 22 | v 2.57869 -1.32956 0 23 | v 0.707455 -2.04497 0 24 | v 2.80584 -2.5733 0 25 | v 4.66314 -2.36828 0 26 | v 4.54855 -1.15229 0 27 | v 2.57869 -1.32956 0 28 | v 4.66314 -2.36828 0 29 | v 6.61469 -2.33012 0 30 | v 6.55376 -1.11404 0 31 | v 4.54855 -1.15229 0 32 | v -5.31881 -2.42261 0 33 | v -3.30763 -2.4022 0 34 | v -3.36694 -1.17951 0 35 | v -5.35264 -1.1927 0 36 | v -3.30763 -2.4022 0 37 | v -1.298 -2.32309 0 38 | v -1.4028 -1.13447 0 39 | v -3.36694 -1.17951 0 40 | v -1.298 -2.32309 0 41 | v 0.707455 -2.04497 0 42 | v 0.520227 -1.0235 0 43 | v -1.4028 -1.13447 0 44 | v 0.707455 -2.04497 0 45 | v 2.57869 -1.32956 0 46 | v 2.29216 0.0499119 0 47 | v 0.520227 -1.0235 0 48 | v 2.57869 -1.32956 0 49 | v 4.54855 -1.15229 0 50 | v 4.46237 0.0516259 0 51 | v 2.29216 0.0499119 0 52 | v 4.54855 -1.15229 0 53 | v 6.55376 -1.11404 0 54 | v 6.49917 0.0707092 0 55 | v 4.46237 0.0516259 0 56 | v -6.33017 -2.41747 0 57 | v -5.31881 -2.42261 0 58 | v -5.35264 -1.1927 0 59 | v -5.36816 0.04293 0 60 | v -6.36275 0.0419961 0 61 | v -6.36275 0.0419961 0 62 | v -5.36816 0.04293 0 63 | v -5.35496 1.27859 0 64 | v -5.32343 2.50856 0 65 | v -6.33479 2.50152 0 66 | v -5.35264 -1.1927 0 67 | v -3.36694 -1.17951 0 68 | v -3.38929 0.0447948 0 69 | v -5.36816 0.04293 0 70 | v -3.36694 -1.17951 0 71 | v -1.4028 -1.13447 0 72 | v -1.42741 0.0466406 0 73 | v -3.38929 0.0447948 0 74 | v -1.4028 -1.13447 0 75 | v 0.520227 -1.0235 0 76 | v 0.558813 0.0484673 0 77 | v -1.42741 0.0466406 0 78 | v 0.520227 -1.0235 0 79 | v 2.29216 0.0499119 0 80 | v 0.518215 1.12039 0 81 | v 0.558813 0.0484673 0 82 | v -5.36816 0.04293 0 83 | v -3.38929 0.0447948 0 84 | v -3.36923 1.26914 0 85 | v -5.35496 1.27859 0 86 | v -3.38929 0.0447948 0 87 | v -1.42741 0.0466406 0 88 | v -1.40501 1.22781 0 89 | v -3.36923 1.26914 0 90 | v -1.42741 0.0466406 0 91 | v 0.558813 0.0484673 0 92 | v 0.518215 1.12039 0 93 | v -1.40501 1.22781 0 94 | v -5.35496 1.27859 0 95 | v -3.36923 1.26914 0 96 | v -3.31222 2.49195 0 97 | v -5.32343 2.50856 0 98 | v -3.36923 1.26914 0 99 | v -1.40501 1.22781 0 100 | v -1.30242 2.41665 0 101 | v -3.31222 2.49195 0 102 | v -1.40501 1.22781 0 103 | v 0.518215 1.12039 0 104 | v 0.703535 2.14236 0 105 | v -1.30242 2.41665 0 106 | v 0.518215 1.12039 0 107 | v 2.29216 0.0499119 0 108 | v 2.57553 1.43039 0 109 | v 0.703535 2.14236 0 110 | v 2.29216 0.0499119 0 111 | v 4.46237 0.0516259 0 112 | v 4.54233 1.25469 0 113 | v 2.57553 1.43039 0 114 | v 4.46237 0.0516259 0 115 | v 6.49917 0.0707092 0 116 | v 6.54366 1.20977 0 117 | v 4.54233 1.25469 0 118 | v -5.32343 2.50856 0 119 | v -3.31222 2.49195 0 120 | v -3.25422 3.71168 0 121 | v -5.28013 3.74383 0 122 | v -3.31222 2.49195 0 123 | v -1.30242 2.41665 0 124 | v -1.17279 3.61612 0 125 | v -3.25422 3.71168 0 126 | v -1.30242 2.41665 0 127 | v 0.703535 2.14236 0 128 | v 0.918221 3.2943 0 129 | v -1.17279 3.61612 0 130 | v 0.703535 2.14236 0 131 | v 2.57553 1.43039 0 132 | v 2.80179 2.67489 0 133 | v 0.918221 3.2943 0 134 | v 2.57553 1.43039 0 135 | v 4.54233 1.25469 0 136 | v 4.6624 2.46941 0 137 | v 2.80179 2.67489 0 138 | v 4.54233 1.25469 0 139 | v 6.54366 1.20977 0 140 | v 6.61623 2.40042 0 141 | v 4.6624 2.46941 0 142 | v 6.61469 -2.33012 0 143 | v 7.61322 -2.29514 0 144 | v 7.49623 0.142057 0 145 | v 6.49917 0.0707092 0 146 | v 6.55376 -1.11404 0 147 | f 1 2 3 4 148 | T 1 149 | N 0 150 | f 5 6 7 8 151 | T 1 152 | N 0 153 | f 9 10 11 12 154 | T 1 155 | N 0 156 | f 13 14 15 16 157 | T 1 158 | N 0 159 | f 17 18 19 20 160 | T 1 161 | N 0 162 | f 21 22 23 24 163 | T 1 164 | N 0 165 | f 25 26 27 28 166 | T 2 167 | N 0 168 | f 29 30 31 32 169 | T 2 170 | N 0 171 | f 33 34 35 36 172 | T 2 173 | N 0 174 | f 37 38 39 40 175 | T 2 176 | N 0 177 | f 41 42 43 44 178 | T 2 179 | N 0 180 | f 45 46 47 48 181 | T 2 182 | N 0 183 | f 49 50 51 52 53 184 | T 3 185 | N 0 186 | f 54 55 56 57 58 187 | T 3 188 | N 0 189 | f 59 60 61 62 190 | T 4 191 | N 0 192 | f 63 64 65 66 193 | T 4 194 | N 0 195 | f 67 68 69 70 196 | T 4 197 | N 0 198 | f 71 72 73 74 199 | T 5 200 | N 0 201 | f 75 76 77 78 202 | T 2 203 | N 0 204 | f 79 80 81 82 205 | T 2 206 | N 0 207 | f 83 84 85 86 208 | T 2 209 | N 0 210 | f 87 88 89 90 211 | T 4 212 | N 0 213 | f 91 92 93 94 214 | T 4 215 | N 0 216 | f 95 96 97 98 217 | T 4 218 | N 0 219 | f 99 100 101 102 220 | T 4 221 | N 0 222 | f 103 104 105 106 223 | T 4 224 | N 0 225 | f 107 108 109 110 226 | T 4 227 | N 0 228 | f 111 112 113 114 229 | T 6 230 | N 0 231 | f 115 116 117 118 232 | T 6 233 | N 0 234 | f 119 120 121 122 235 | T 6 236 | N 0 237 | f 123 124 125 126 238 | T 6 239 | N 0 240 | f 127 128 129 130 241 | T 6 242 | N 0 243 | f 131 132 133 134 244 | T 6 245 | N 0 246 | f 135 136 137 138 139 247 | T 7 248 | N 0 249 | e 1/2 2/-4 250 | e 1/3 7/-1 251 | e 2/2 3/-4 252 | e 2/3 8/-1 253 | e 3/2 4/-4 254 | e 3/3 9/-1 255 | e 4/2 5/-4 256 | e 4/3 10/-1 257 | e 5/2 6/-4 258 | e 5/3 11/-1 259 | e 6/2 34/-5 260 | e 6/3 12/-1 261 | e 7/2 8/-4 262 | e 7/3 15/-1 263 | e 7/4 13/-2 264 | e 8/2 9/-4 265 | e 8/3 16/-1 266 | e 9/2 10/-4 267 | e 9/3 17/-1 268 | e 10/2 11/-4 269 | e 10/3 18/-1 270 | e 11/2 12/-4 271 | e 11/3 26/-1 272 | e 12/2 34/-4 273 | e 12/3 27/-1 274 | e 13/3 15/-4 275 | e 13/4 14/-1 276 | e 14/2 19/-4 277 | e 14/3 22/-4 278 | e 15/2 16/-4 279 | e 15/3 19/-1 280 | e 16/2 17/-4 281 | e 16/3 20/-1 282 | e 17/2 18/-4 283 | e 17/3 21/-1 284 | e 18/2 25/-1 285 | e 18/3 21/-2 286 | e 19/2 20/-4 287 | e 19/3 22/-1 288 | e 20/2 21/-4 289 | e 20/3 23/-1 290 | e 21/3 24/-1 291 | e 22/2 23/-4 292 | e 22/3 28/-1 293 | e 23/2 24/-4 294 | e 23/3 29/-1 295 | e 24/2 25/-4 296 | e 24/3 30/-1 297 | e 25/2 26/-4 298 | e 25/3 31/-1 299 | e 26/2 27/-4 300 | e 26/3 32/-1 301 | e 27/3 33/-1 302 | e 28/2 29/-4 303 | e 29/2 30/-4 304 | e 30/2 31/-4 305 | e 31/2 32/-4 306 | e 32/2 33/-4 307 | -------------------------------------------------------------------------------- /examples/short-row.txt: -------------------------------------------------------------------------------- 1 | tuck-twist+ . a 1- . 2 | tuck-twist+ . b 2- a 3 | tuck-twist+ . c 3- b 4 | tuck-twist+ . d 4- c 5 | tuck-twist+ . e 5- d 6 | tuck-twist+ . E5 6- e 7 | 8 | knit- 1- a 1 E1 9 | knit- 2- b 2 a 10 | knit- 3- c 3 b 11 | knit- 4- d 4 c 12 | knit- 5- e 5 d 13 | knit- 6- E6 6 e 14 | 15 | edge( . E1 E2 xx . 16 | edge( xx E3 E4 . . 17 | 18 | knit+ 1 a 1b E2 19 | knit+ 2 b 2b a 20 | knit+ 3 c 3b b 21 | turn)(( 4 4b x1 c 22 | 23 | knit- 1b a 1 E3 24 | knit- 2b b 2 a 25 | knit- 3b x1 3 b 26 | 27 | knit+ 1 a 1c E4 28 | knit+ 2 b 2c a 29 | knit+ 3 c 3c b 30 | knit+ 4b d 4c c 31 | knit+ 5 e 5c d 32 | knit+ 6 . 6c e 33 | 34 | drop 1c a . . 35 | drop 2c b . a 36 | drop 3c c . b 37 | drop 4c d . c 38 | drop 5c e . d 39 | drop 6c . . e 40 | 41 | edge) . . . E6 E5 42 | -------------------------------------------------------------------------------- /examples/spacer.smobj: -------------------------------------------------------------------------------- 1 | L knit+ -lX +yX +lX -yX 2 | L knit+.2111 -lX +yX +lX -yX 3 | L knit- -lX -yX +lX +yX 4 | L knit-fair-isle-1+ -lX +yX +lX -yX 5 | L spacer4+ -lX -lX -lX -lX -lX -lX -lX -lX +yX +lX +lX +lX +lX +lX +lX +lX +lX -yX 6 | L knit-fair-isle-1- -lX -yX +lX +yX 7 | L knit-fair-isle-2+ -lX +yX +lX -yX 8 | L knit-fair-isle-2- -lX -yX +lX +yX 9 | L knit-plating-1+ -lX +yX +lX -yX 10 | L knit-plating-1- -lX -yX +lX +yX 11 | L knit-plating-2+ -lX +yX +lX -yX 12 | L knit-plating-2- -lX -yX +lX +yX 13 | L knittuck+ -lX +yX +lX -yX 14 | L knittuck- -lX -yX +lX +yX 15 | L purl+ -lX +yX +lX -yX 16 | L purl- -lX -yX +lX +yX 17 | L tuck-twist+ -lX +yX +lX -yX 18 | L tuck-twist- -lX -yX +lX +yX 19 | L drop- -l1 -y0 +l0 +y0 20 | L drop+ -l1 +y0 +l0 -y0 21 | L make-left-split+ -lX +yX +lX +lX -yX 22 | L make-left-tuck+ -lX +yX +lX +lX -yX 23 | L edge) x x x +y1 -y1 24 | L edge( x -y1 +y1 x x 25 | L decrease-right- -lX -lX -yX +lX +yX 26 | v -1 -0.61 0 27 | v 1 -0.61 0 28 | v 1 0.61 0 29 | v -1 0.61 0 30 | v 1.04862 -0.61 0 31 | v 3.04862 -0.61 0 32 | v 3.04862 0.61 0 33 | v 1.04862 0.61 0 34 | v 3.07292 -0.61 0 35 | v 5.07292 -0.61 0 36 | v 5.07292 0.61 0 37 | v 3.07292 0.61 0 38 | v 5.07292 -0.61 0.0568886 39 | v 7.07292 -0.61 0.0568886 40 | v 7.07292 0.61 0.0568886 41 | v 5.07292 0.61 0.0568886 42 | v -1 -0.61 -1.51319 43 | v 1 -0.61 -1.51319 44 | v 1 0.61 -1.51319 45 | v -1 0.61 -1.51319 46 | v 1.15529 -0.61 -1.51319 47 | v 3.15529 -0.61 -1.51319 48 | v 3.15529 0.61 -1.51319 49 | v 1.15529 0.61 -1.51319 50 | v 3.28965 -0.61 -1.51319 51 | v 5.28965 -0.61 -1.51319 52 | v 5.28965 0.61 -1.51319 53 | v 3.28965 0.61 -1.51319 54 | v 5.32537 -0.61 -1.51319 55 | v 7.32537 -0.61 -1.51319 56 | v 7.32537 0.61 -1.51319 57 | v 5.32537 0.61 -1.51319 58 | v -1 0.846908 -0.402611 59 | v 7.04001 0.846908 -0.402611 60 | v 7.04001 2.06691 -0.402611 61 | v -1 2.06691 -0.402611 62 | v 3.02001 0.846908 -0.402611 63 | v 3.02001 2.06691 -0.402611 64 | v 1.21982 2.06691 -0.40184 65 | v 5.03001 2.06691 -0.402611 66 | v 1.21982 0.846908 -0.40184 67 | v 5.03001 0.846908 -0.402611 68 | v 0.214819 2.06691 -0.40184 69 | v 2.01501 2.06691 -0.402611 70 | v 4.02501 2.06691 -0.402611 71 | v 6.03501 2.06691 -0.402611 72 | v 6.03501 0.846908 -0.2342 73 | v 4.02501 0.846908 -0.402611 74 | v 2.01501 0.846908 -0.402611 75 | v 0.214819 0.846908 -0.40184 76 | v -1 2.48213 0 77 | v 1 2.48213 0 78 | v 1 3.70213 0 79 | v -1 3.70213 0 80 | v 1 2.48213 0 81 | v 3 2.48213 0 82 | v 3 3.70213 0 83 | v 1 3.70213 0 84 | v 3 2.48213 0 85 | v 5 2.48213 0 86 | v 5 3.70213 0 87 | v 3 3.70213 0 88 | v 5 2.48213 0 89 | v 7 2.48213 0 90 | v 7 3.70213 0 91 | v 5 3.70213 0 92 | v -1 2.46922 -1.82498 93 | v 1 2.46922 -1.82498 94 | v 1 3.68922 -1.82498 95 | v -1 3.68922 -1.82498 96 | v 1 2.46922 -1.82498 97 | v 3 2.46922 -1.82498 98 | v 3 3.68922 -1.82498 99 | v 1 3.68922 -1.82498 100 | v 3 2.46922 -1.82498 101 | v 5 2.46922 -1.82498 102 | v 5 3.68922 -1.82498 103 | v 3 3.68922 -1.82498 104 | v 5 2.46922 -1.82498 105 | v 7 2.46922 -1.82498 106 | v 7 3.68922 -1.82498 107 | v 5 3.68922 -1.82498 108 | v -1 -1.83 0 109 | v 1 -1.83 0 110 | v 1 -0.61 0 111 | v -1 -0.61 0 112 | v 1 -1.83 0 113 | v 3 -1.83 0 114 | v 3 -0.61 0 115 | v 1 -0.61 0 116 | v 3.07292 -1.83 0 117 | v 5.07292 -1.83 0 118 | v 5.07292 -0.61 0 119 | v 3.07292 -0.61 0 120 | v 5.07292 -1.83 0 121 | v 7.07292 -1.83 0 122 | v 7.07292 -0.61 0 123 | v 5.07292 -0.61 0 124 | v -1 -1.83 -1.51319 125 | v 1 -1.83 -1.51319 126 | v 1 -0.61 -1.51319 127 | v -1 -0.61 -1.51319 128 | v 1.15529 -1.83 -1.51319 129 | v 3.15529 -1.83 -1.51319 130 | v 3.15529 -0.61 -1.51319 131 | v 1.15529 -0.61 -1.51319 132 | v 3.28965 -1.83 -1.51319 133 | v 5.28965 -1.83 -1.51319 134 | v 5.28965 -0.61 -1.51319 135 | v 3.28965 -0.61 -1.51319 136 | v 5.32537 -1.83 -1.51319 137 | v 7.32537 -1.83 -1.51319 138 | v 7.32537 -0.61 -1.51319 139 | v 5.32537 -0.61 -1.51319 140 | v -1 3.70213 0 141 | v 1 3.70213 0 142 | v 1 4.92213 0 143 | v -1 4.92213 0 144 | v 1 3.70213 0 145 | v 3 3.70213 0 146 | v 3 4.92213 0 147 | v 1 4.92213 0 148 | v 3 3.70213 0 149 | v 5 3.70213 0 150 | v 5 4.92213 0 151 | v 3 4.92213 0 152 | v 5 3.70213 0 153 | v 7 3.70213 0 154 | v 7 4.92213 0 155 | v 5 4.92213 0 156 | v -1 3.68922 -1.82498 157 | v 1 3.68922 -1.82498 158 | v 1 4.90922 -1.82498 159 | v -1 4.90922 -1.82498 160 | v 1 3.68922 -1.82498 161 | v 3 3.68922 -1.82498 162 | v 3 4.90922 -1.82498 163 | v 1 4.90922 -1.82498 164 | v 3 3.68922 -1.82498 165 | v 5 3.68922 -1.82498 166 | v 5 4.90922 -1.82498 167 | v 3 4.90922 -1.82498 168 | v 5 3.68922 -1.82498 169 | v 7 3.68922 -1.82498 170 | v 7 4.90922 -1.82498 171 | v 5 4.90922 -1.82498 172 | v -3.48437 -0.61 0 173 | v -1.48437 -0.61 0 174 | v -1.48437 2.89557 0 175 | v -3.48437 2.89557 0 176 | v -1.48437 1.14278 0 177 | v 7.69952 -1.83 0 178 | v 9.69952 -1.83 0 179 | v 9.69952 0.583564 0 180 | v 7.69952 0.583564 0 181 | v 7.69952 -0.623218 0 182 | v 7.62688 -1.83 -1.51319 183 | v 9.62688 -1.83 -1.51319 184 | v 9.62688 0.716924 -1.51319 185 | v 7.62688 0.716924 -1.51319 186 | v 7.62688 0.550018 -1.51319 187 | v -3.11639 -0.61 -1.51319 188 | v -1.11639 -0.61 -1.51319 189 | v -1.11639 2.87541 -1.51319 190 | v -3.11639 2.87541 -1.51319 191 | v -1.11639 1.1327 -1.51319 192 | f 1 2 3 4 193 | T 3 194 | N 0 195 | f 5 6 7 8 196 | T 3 197 | N 0 198 | f 9 10 11 12 199 | T 3 200 | N 0 201 | f 13 14 15 16 202 | T 3 203 | N 0 204 | f 17 18 19 20 205 | T 3 206 | N 0 207 | f 21 22 23 24 208 | T 3 209 | N 0 210 | f 25 26 27 28 211 | T 3 212 | N 0 213 | f 29 30 31 32 214 | T 3 215 | N 0 216 | f 33 50 41 49 37 48 42 47 34 35 46 40 45 38 44 39 43 36 217 | T 5 218 | N 0 219 | f 51 52 53 54 220 | T 13 221 | N 0 222 | f 55 56 57 58 223 | T 1 224 | N 0 225 | f 59 60 61 62 226 | T 13 227 | N 0 228 | f 63 64 65 66 229 | T 1 230 | N 0 231 | f 67 68 69 70 232 | T 1 233 | N 0 234 | f 71 72 73 74 235 | T 13 236 | N 0 237 | f 75 76 77 78 238 | T 1 239 | N 0 240 | f 79 80 81 82 241 | T 13 242 | N 0 243 | f 83 84 85 86 244 | T 17 245 | N 0 246 | f 87 88 89 90 247 | T 17 248 | N 0 249 | f 91 92 93 94 250 | T 17 251 | N 0 252 | f 95 96 97 98 253 | T 17 254 | N 0 255 | f 99 100 101 102 256 | T 17 257 | N 0 258 | f 103 104 105 106 259 | T 17 260 | N 0 261 | f 107 108 109 110 262 | T 17 263 | N 0 264 | f 111 112 113 114 265 | T 17 266 | N 0 267 | f 115 116 117 118 268 | T 19 269 | N 0 270 | f 119 120 121 122 271 | T 19 272 | N 0 273 | f 123 124 125 126 274 | T 19 275 | N 0 276 | f 127 128 129 130 277 | T 19 278 | N 0 279 | f 131 132 133 134 280 | T 19 281 | N 0 282 | f 135 136 137 138 283 | T 19 284 | N 0 285 | f 139 140 141 142 286 | T 19 287 | N 0 288 | f 143 144 145 146 289 | T 19 290 | N 0 291 | f 147 148 151 149 150 292 | T 24 293 | N 0 294 | f 152 153 154 155 156 295 | T 23 296 | N 0 297 | f 157 158 159 160 161 298 | T 23 299 | N 0 300 | f 162 163 166 164 165 301 | T 24 302 | N 0 303 | e 1/3 9/-1 304 | e 5/3 9/-2 305 | e 2/3 9/-3 306 | e 6/3 9/-4 307 | e 3/3 9/-5 308 | e 7/3 9/-6 309 | e 4/3 9/-7 310 | e 8/3 9/-8 311 | e 1/2 2/-4 312 | e 2/2 3/-4 313 | e 3/2 4/-4 314 | e 5/2 6/-4 315 | e 6/2 7/-4 316 | e 7/2 8/-4 317 | e 9/17 10/-1 318 | e 10/2 11/-4 319 | e 11/2 12/-4 320 | e 12/2 13/-4 321 | e 16/2 17/-4 322 | e 15/2 16/-4 323 | e 14/2 15/-4 324 | e 9/16 14/-1 325 | e 9/15 11/-1 326 | e 9/14 15/-1 327 | e 9/13 12/-1 328 | e 9/12 16/-1 329 | e 9/10 17/-1 330 | e 9/11 13/-1 331 | e 1/1 18/-3 332 | e 2/1 19/-3 333 | e 18/2 19/-4 334 | e 19/2 20/-4 335 | e 3/1 20/-3 336 | e 20/2 21/-4 337 | e 4/1 21/-3 338 | e 5/1 22/-3 339 | e 22/2 23/-4 340 | e 23/2 24/-4 341 | e 7/1 24/-3 342 | e 24/2 25/-4 343 | e 8/1 25/-3 344 | e 6/1 23/-3 345 | e 10/3 26/-1 346 | e 11/3 27/-1 347 | e 12/3 28/-1 348 | e 13/3 29/-1 349 | e 17/3 33/-1 350 | e 16/3 32/-1 351 | e 15/3 31/-1 352 | e 14/3 30/-1 353 | e 1/4 34/-2 354 | e 10/4 34/-3 355 | e 21/2 35/-5 356 | e 4/2 35/-4 357 | e 25/2 36/-5 358 | e 8/2 36/-4 359 | e 14/4 37/-3 360 | e 5/4 37/-2 361 | t 5 back u 362 | t 6 back u 363 | t 7 back u 364 | t 8 back u 365 | t 11 front u 366 | t 14 back u 367 | t 15 back u 368 | t 16 back u 369 | t 17 back u 370 | t 22 back u 371 | t 23 back u 372 | t 24 back u 373 | t 25 back u 374 | h 18/1 f0 u 375 | t 37 back u 376 | t 35 front u 377 | t 36 back u 378 | t 18 front h 379 | h 1/1 f0 i 380 | h 18/2 f0.5 i 381 | h 18/3 f0 i 382 | h 18/4 f-0.5 i 383 | h 19/4 f0.5 h 384 | o 6/1 5/1 i 385 | o 7/1 6/1 i 386 | o 8/1 7/1 i 387 | o 14/1 15/1 i 388 | o 15/1 16/1 i 389 | o 16/1 17/1 i 390 | o 22/1 5/1 i 391 | o 23/1 6/1 i 392 | o 24/1 7/1 i 393 | o 25/1 8/1 i 394 | o 22/1 23/1 i 395 | o 23/1 24/1 i 396 | o 24/1 25/1 i 397 | t 1 front h 398 | t 19 front h 399 | h 1/2 f0.5 i 400 | h 1/3 f0 i 401 | h 1/4 f-0.5 i 402 | h 2/1 f1 h 403 | h 2/4 f0.5 h 404 | h 9/1 f0 i 405 | h 19/1 f1 h 406 | h 19/2 f1.5 h 407 | h 19/3 f1 h 408 | h 20/4 f1.5 h 409 | h 34/2 f-0.5 h 410 | o 18/1 18/2 i 411 | o 18/2 1/1 i 412 | o 18/2 19/2 i 413 | o 19/1 19/2 i 414 | o 18/2 19/1 i 415 | t 2 front h 416 | t 9 front-back h 417 | t 20 front h 418 | t 34 front h 419 | h 2/2 f1.5 h 420 | h 2/3 f1 h 421 | h 3/1 f2 h 422 | h 3/3 f2 i 423 | h 3/4 f1.5 h 424 | h 4/3 f3 i 425 | h 5/3 b0 i 426 | h 6/3 b1 i 427 | h 7/3 b2 i 428 | h 8/3 b3 i 429 | h 9/2 b0 i 430 | h 9/3 f1 i 431 | h 9/4 b1 i 432 | h 9/5 f2 i 433 | h 9/6 b2 i 434 | h 9/7 f3 i 435 | h 9/8 b3 i 436 | h 9/9 b3.5 i 437 | h 9/10 b3 i 438 | h 9/11 f3 i 439 | h 9/12 b2 i 440 | h 9/13 f2 i 441 | h 9/14 b1 i 442 | h 9/15 f1 i 443 | h 9/16 b0 i 444 | h 9/17 f0 i 445 | h 9/18 f-0.5 i 446 | h 10/1 f0 i 447 | h 10/4 f-0.5 h 448 | h 11/1 f1 i 449 | h 12/1 f2 i 450 | h 13/1 f3 i 451 | h 14/1 b0 i 452 | h 15/1 b1 i 453 | h 16/1 b2 i 454 | h 17/1 b3 i 455 | h 20/1 f2 h 456 | h 20/2 f2.5 h 457 | h 20/3 f2 h 458 | h 21/4 f2.5 h 459 | h 34/1 x-1 h 460 | h 34/3 f-0.5 h 461 | h 34/4 x-1 h 462 | h 34/5 x-1 h 463 | o 2/1 1/1 i 464 | o 9/1 11/1 i 465 | o 9/1 14/1 i 466 | o 9/1 15/1 i 467 | o 9/1 16/1 i 468 | o 9/1 17/1 i 469 | o 9/2 11/1 i 470 | o 9/2 14/1 i 471 | o 9/2 15/1 i 472 | o 9/2 16/1 i 473 | o 9/2 17/1 i 474 | o 9/3 11/1 i 475 | o 9/3 14/1 i 476 | o 9/3 15/1 i 477 | o 9/3 16/1 i 478 | o 9/3 17/1 i 479 | o 9/4 11/1 i 480 | o 9/4 14/1 i 481 | o 9/4 15/1 i 482 | o 9/4 16/1 i 483 | o 9/4 17/1 i 484 | o 19/2 2/1 i 485 | o 19/2 20/2 i 486 | o 20/1 20/2 i 487 | o 1/1 9/1 i 488 | o 2/1 9/1 i 489 | o 5/1 9/1 i 490 | o 6/1 9/1 i 491 | o 7/1 9/1 i 492 | o 8/1 9/1 i 493 | o 9/1 9/2 i 494 | o 9/2 9/3 i 495 | o 9/3 9/4 i 496 | o 19/2 20/1 i 497 | t 3 front h 498 | t 4 front h 499 | t 10 front h 500 | t 12 front h 501 | t 13 front h 502 | t 21 front h 503 | o 3/1 2/1 i 504 | o 4/1 3/1 i 505 | o 9/1 10/1 i 506 | o 9/1 12/1 i 507 | o 9/1 13/1 i 508 | o 9/2 10/1 i 509 | o 9/2 12/1 i 510 | o 9/2 13/1 i 511 | o 9/3 10/1 i 512 | o 9/3 12/1 i 513 | o 9/3 13/1 i 514 | o 9/4 10/1 i 515 | o 9/4 12/1 i 516 | o 9/4 13/1 i 517 | o 10/1 11/1 i 518 | o 11/1 12/1 i 519 | o 12/1 13/1 i 520 | o 20/2 3/1 i 521 | o 20/2 21/2 i 522 | o 21/1 21/2 i 523 | o 21/2 4/1 i 524 | o 3/1 9/1 i 525 | o 4/1 9/1 i 526 | o 20/2 21/1 i 527 | -------------------------------------------------------------------------------- /examples/tube-decrease.smobj: -------------------------------------------------------------------------------- 1 | L knit+ -lX +yX +lX -yX 2 | L make-left-split+ -lX +yX +lX +lX -yX 3 | L make-left-tuck+ -lX +yX +lX +lX -yX 4 | L make-left-tuck-twist+ -lX +yX +lX +lX -yX 5 | L make-left-tuck-twist- -lX -yX +lX +lX +yX 6 | L make-right-split+ -lX +yX +lX +lX -yX 7 | L make-right-tuck+ -lX +yX +lX +lX -yX 8 | L make-right-tuck-twist+ -lX +yX +lX +lX -yX 9 | L make-right-tuck-twist- -lX -yX +lX +lX +yX 10 | L edge) x x x +y1 -y1 11 | L edge( x -y1 +y1 x x 12 | L decrease-right- -lX -lX -yX +lX +yX 13 | L decrease-right+ -lX -lX +yX +lX -yX 14 | L drop- -l1 -y0 +l0 +y0 15 | L drop+ -l1 +y0 +l0 -y0 16 | L knit+.2111 -lX +yX +lX -yX 17 | L knit- -lX -yX +lX +yX 18 | L knit-fair-isle-1+ -lX +yX +lX -yX 19 | L knit-fair-isle-2+ -lX +yX +lX -yX 20 | L knit-plating-1+ -lX +yX +lX -yX 21 | L knit-plating-2+ -lX +yX +lX -yX 22 | L purl+ -lX +yX +lX -yX 23 | L purl- -lX -yX +lX +yX 24 | L tuck-twist+ -lX +yX +lX -yX 25 | v -3.84466 -0.61 0 26 | v -1.84466 -0.61 0 27 | v -1.84466 0.61 0 28 | v -3.84466 0.61 0 29 | v -1.5499 -0.61 0 30 | v 0.450104 -0.61 0 31 | v 0.450104 0.61 0 32 | v -1.5499 0.61 0 33 | v 0.919813 -0.61 0 34 | v 2.91981 -0.61 0 35 | v 2.91981 0.61 0 36 | v 0.919813 0.61 0 37 | v 3.26969 -0.61 0 38 | v 5.26969 -0.61 0 39 | v 5.26969 0.61 0 40 | v 3.26969 0.61 0 41 | v 3.27755 -0.61 -2.2735 42 | v 5.27755 -0.61 -2.2735 43 | v 5.27755 0.61 -2.2735 44 | v 3.27755 0.61 -2.2735 45 | v 1.05008 -0.61 -2.2735 46 | v 3.05008 -0.61 -2.2735 47 | v 3.05008 0.61 -2.2735 48 | v 1.05008 0.61 -2.2735 49 | v -1.21575 -0.61 -2.2735 50 | v 0.784252 -0.61 -2.2735 51 | v 0.784252 0.61 -2.2735 52 | v -1.21575 0.61 -2.2735 53 | v -3.84466 1.04194 0 54 | v -1.84466 1.04194 0 55 | v -1.84466 2.26194 0 56 | v -3.84466 2.26194 0 57 | v -1.53557 1.04194 0 58 | v 0.464426 1.04194 0 59 | v 0.464426 2.26194 0 60 | v -1.53557 2.23989 0 61 | v 0.939105 1.04194 0 62 | v 2.93911 1.04194 0 63 | v 2.93911 2.26194 0 64 | v 0.939105 2.26194 0 65 | v 3.25603 1.04194 0 66 | v 5.25603 1.04194 0 67 | v 5.25603 2.26194 0 68 | v 3.25603 2.26194 0 69 | v 3.27755 0.899715 -2.2735 70 | v 5.27755 0.899715 -2.2735 71 | v 5.27755 2.11971 -2.2735 72 | v 3.27755 2.11971 -2.2735 73 | v 1.05008 0.892475 -2.2735 74 | v 3.05008 0.892475 -2.2735 75 | v 3.05008 2.11247 -2.2735 76 | v 1.05008 2.11247 -2.2735 77 | v -1.21575 0.885125 -2.2735 78 | v 0.784252 0.885125 -2.2735 79 | v 0.784252 2.10512 -2.2735 80 | v -1.21575 2.10512 -2.2735 81 | v -3.84466 2.47941 0 82 | v -1.84466 2.47941 0 83 | v -1.84466 3.69941 0 84 | v -3.84466 3.69941 0 85 | v -1.53557 2.51831 0 86 | v 0.464426 2.51831 0 87 | v 0.464426 3.73831 0 88 | v -1.53557 3.73831 0 89 | v 0.939105 2.52685 0 90 | v 2.93911 2.52685 0 91 | v 2.93911 3.74685 0 92 | v 0.939105 3.74685 0 93 | v 3.25603 2.50519 0 94 | v 5.25603 2.50519 0 95 | v 5.25603 3.72519 0 96 | v 3.25603 3.72519 0 97 | v 0.891629 2.52159 -2.2735 98 | v 5.27755 2.52159 -2.2735 99 | v 5.27755 3.74159 -2.2735 100 | v 0.891629 3.74159 -2.2735 101 | v 3.08459 2.52159 -2.2735 102 | v -1.48991 2.52159 -2.2735 103 | v 0.510087 2.52159 -2.2735 104 | v 0.510087 3.74159 -2.2735 105 | v -1.48991 3.74159 -2.2735 106 | v -3.84466 3.95147 0 107 | v -1.84466 3.95147 0 108 | v -1.84466 5.17147 0 109 | v -3.84466 5.17147 0 110 | v -1.53557 3.95358 0 111 | v 0.464426 3.95358 0 112 | v 0.464426 5.17358 0 113 | v -1.53557 5.17358 0 114 | v 0.939105 3.94679 0 115 | v 2.93911 3.94679 0 116 | v 2.93911 5.16679 0 117 | v 0.939105 5.16679 0 118 | v 3.25603 3.90796 0 119 | v 5.25603 3.90796 0 120 | v 5.25603 5.12796 0 121 | v 3.25603 5.12796 0 122 | v 2.08459 4.01417 -2.2735 123 | v 4.08459 4.01417 -2.2735 124 | v 4.08459 5.23417 -2.2735 125 | v 2.08459 5.23417 -2.2735 126 | v -1.48991 3.87969 -2.2735 127 | v 0.510087 3.87969 -2.2735 128 | v 0.510087 5.09969 -2.2735 129 | v -1.48991 5.09969 -2.2735 130 | f 1 2 3 4 131 | T 24 132 | N 0 133 | f 5 6 7 8 134 | T 24 135 | N 0 136 | f 9 10 11 12 137 | T 24 138 | N 0 139 | f 13 14 15 16 140 | T 24 141 | N 0 142 | f 18 17 20 19 143 | T 24 144 | N 0 145 | f 22 21 24 23 146 | T 24 147 | N 0 148 | f 26 25 28 27 149 | T 24 150 | N 0 151 | f 29 30 31 32 152 | T 1 153 | N 0 154 | f 33 34 35 36 155 | T 1 156 | N 0 157 | f 37 38 39 40 158 | T 1 159 | N 0 160 | f 41 42 43 44 161 | T 1 162 | N 0 163 | f 46 45 48 47 164 | T 1 165 | N 0 166 | f 50 49 52 51 167 | T 1 168 | N 0 169 | f 54 53 56 55 170 | T 1 171 | N 0 172 | f 57 58 59 60 173 | T 1 174 | N 0 175 | f 61 62 63 64 176 | T 1 177 | N 0 178 | f 65 66 67 68 179 | T 1 180 | N 0 181 | f 69 70 71 72 182 | T 1 183 | N 0 184 | f 74 77 73 76 75 185 | T 13 186 | N 0 187 | f 79 78 81 80 188 | T 1 189 | N 0 190 | f 82 83 84 85 191 | T 15 192 | N 0 193 | f 86 87 88 89 194 | T 15 195 | N 0 196 | f 90 91 92 93 197 | T 15 198 | N 0 199 | f 94 95 96 97 200 | T 15 201 | N 0 202 | f 99 98 101 100 203 | T 15 204 | N 0 205 | f 103 102 105 104 206 | T 15 207 | N 0 208 | e 1/2 2/-4 209 | e 2/2 3/-4 210 | e 3/2 4/-4 211 | e 4/2 5/-4 212 | e 5/2 6/-4 213 | e 6/2 7/-4 214 | e 7/2 8/-4 215 | e 8/2 9/-4 216 | e 9/2 10/-4 217 | e 10/2 11/-4 218 | e 5/3 12/-1 219 | e 12/2 13/-4 220 | e 6/3 13/-1 221 | e 1/3 8/-1 222 | e 2/3 9/-1 223 | e 3/3 10/-1 224 | e 4/3 11/-1 225 | e 13/2 14/-4 226 | e 7/3 14/-1 227 | e 8/3 15/-1 228 | e 15/2 16/-4 229 | e 9/3 16/-1 230 | e 10/3 17/-1 231 | e 17/2 18/-4 232 | e 11/3 18/-1 233 | e 12/3 19/-1 234 | e 13/3 19/-2 235 | e 14/3 20/-1 236 | e 19/3 20/-4 237 | e 15/3 21/-1 238 | e 17/3 23/-1 239 | e 18/3 24/-1 240 | e 16/2 17/-4 241 | e 18/2 19/-5 242 | e 19/4 25/-1 243 | e 16/3 22/-1 244 | e 20/3 26/-1 245 | e 11/2 12/-4 246 | e 14/2 15/-4 247 | -------------------------------------------------------------------------------- /examples/twill.smobj: -------------------------------------------------------------------------------- 1 | L over -a1 +e1 +a1 -e1 2 | L under -a1 +e1 +a1 -e1 3 | v 0.2 -0.2 0 4 | v 0.6 -0.2 0 5 | v 0.6 0.2 0 6 | v 0.2 0.2 0 7 | v 0.6 -0.2 0 8 | v 1 -0.2 0 9 | v 1 0.2 0 10 | v 0.6 0.2 0 11 | v 1 -0.2 0 12 | v 1.4 -0.2 0 13 | v 1.4 0.2 0 14 | v 1 0.2 0 15 | v 1.4 -0.2 0 16 | v 1.8 -0.2 0 17 | v 1.8 0.2 0 18 | v 1.4 0.2 0 19 | v -0.2 0.2 0 20 | v 0.2 0.2 0 21 | v 0.2 0.6 0 22 | v -0.2 0.6 0 23 | v 0.2 0.2 0 24 | v 0.6 0.2 0 25 | v 0.6 0.6 0 26 | v 0.2 0.6 0 27 | v 0.6 0.2 0 28 | v 1 0.2 0 29 | v 1 0.6 0 30 | v 0.6 0.6 0 31 | v 1 0.2 0 32 | v 1.4 0.2 0 33 | v 1.4 0.6 0 34 | v 1 0.6 0 35 | v 1.4 0.2 0 36 | v 1.8 0.2 0 37 | v 1.8 0.6 0 38 | v 1.4 0.6 0 39 | v -0.2 0.6 0 40 | v 0.2 0.6 0 41 | v 0.2 1 0 42 | v -0.2 1 0 43 | v 0.2 0.6 0 44 | v 0.6 0.6 0 45 | v 0.6 1 0 46 | v 0.2 1 0 47 | v 0.6 0.6 0 48 | v 1 0.6 0 49 | v 1 1 0 50 | v 0.6 1 0 51 | v 1 0.6 0 52 | v 1.4 0.6 0 53 | v 1.4 1 0 54 | v 1 1 0 55 | v 1.4 0.6 0 56 | v 1.8 0.6 0 57 | v 1.8 1 0 58 | v 1.4 1 0 59 | v -0.2 1 0 60 | v 0.2 1 0 61 | v 0.2 1.4 0 62 | v -0.2 1.4 0 63 | v 0.2 1 0 64 | v 0.6 1 0 65 | v 0.6 1.4 0 66 | v 0.2 1.4 0 67 | v 0.6 1 0 68 | v 1 1 0 69 | v 1 1.4 0 70 | v 0.6 1.4 0 71 | v 1 1 0 72 | v 1.4 1 0 73 | v 1.4 1.4 0 74 | v 1 1.4 0 75 | v 1.4 1 0 76 | v 1.8 1 0 77 | v 1.8 1.4 0 78 | v 1.4 1.4 0 79 | v -0.2 -0.2 0 80 | v 0.2 -0.2 0 81 | v 0.2 0.2 0 82 | v -0.2 0.2 0 83 | v -0.2 1.4 0 84 | v 0.2 1.4 0 85 | v 0.2 1.8 0 86 | v -0.2 1.8 0 87 | v 0.2 1.4 0 88 | v 0.6 1.4 0 89 | v 0.6 1.8 0 90 | v 0.2 1.8 0 91 | v 0.6 1.4 0 92 | v 1 1.4 0 93 | v 1 1.8 0 94 | v 0.6 1.8 0 95 | v 1 1.4 0 96 | v 1.4 1.4 0 97 | v 1.4 1.8 0 98 | v 1 1.8 0 99 | v 1.4 1.4 0 100 | v 1.8 1.4 0 101 | v 1.8 1.8 0 102 | v 1.4 1.8 0 103 | f 1 2 3 4 104 | T 1 105 | N 0 106 | f 5 6 7 8 107 | T 2 108 | N 0 109 | f 9 10 11 12 110 | T 2 111 | N 0 112 | f 13 14 15 16 113 | T 1 114 | N 0 115 | f 17 18 19 20 116 | T 2 117 | N 0 118 | f 21 22 23 24 119 | T 1 120 | N 0 121 | f 25 26 27 28 122 | T 1 123 | N 0 124 | f 29 30 31 32 125 | T 2 126 | N 0 127 | f 33 34 35 36 128 | T 2 129 | N 0 130 | f 37 38 39 40 131 | T 2 132 | N 0 133 | f 41 42 43 44 134 | T 2 135 | N 0 136 | f 45 46 47 48 137 | T 1 138 | N 0 139 | f 49 50 51 52 140 | T 1 141 | N 0 142 | f 53 54 55 56 143 | T 2 144 | N 0 145 | f 57 58 59 60 146 | T 1 147 | N 0 148 | f 61 62 63 64 149 | T 2 150 | N 0 151 | f 65 66 67 68 152 | T 2 153 | N 0 154 | f 69 70 71 72 155 | T 1 156 | N 0 157 | f 73 74 75 76 158 | T 1 159 | N 0 160 | f 77 78 79 80 161 | T 1 162 | N 0 163 | f 81 82 83 84 164 | T 1 165 | N 0 166 | f 85 86 87 88 167 | T 1 168 | N 0 169 | f 89 90 91 92 170 | T 2 171 | N 0 172 | f 93 94 95 96 173 | T 2 174 | N 0 175 | f 97 98 99 100 176 | T 1 177 | N 0 178 | e 1/2 2/-4 179 | e 2/2 3/-4 180 | e 3/2 4/-4 181 | e 5/2 6/-4 182 | e 6/2 7/-4 183 | e 7/2 8/-4 184 | e 8/2 9/-4 185 | e 13/2 14/-4 186 | e 12/2 13/-4 187 | e 11/2 12/-4 188 | e 10/2 11/-4 189 | e 15/2 16/-4 190 | e 16/2 17/-4 191 | e 17/2 18/-4 192 | e 18/2 19/-4 193 | e 24/2 25/-4 194 | e 23/2 24/-4 195 | e 22/2 23/-4 196 | e 21/2 22/-4 197 | e 5/3 10/-1 198 | e 10/3 15/-1 199 | e 15/3 21/-1 200 | e 16/3 22/-1 201 | e 11/3 16/-1 202 | e 6/3 11/-1 203 | e 1/3 6/-1 204 | e 5/1 20/-3 205 | e 1/4 20/-2 206 | e 2/3 7/-1 207 | e 3/3 8/-1 208 | e 4/3 9/-1 209 | e 9/3 14/-1 210 | e 8/3 13/-1 211 | e 7/3 12/-1 212 | e 12/3 17/-1 213 | e 13/3 18/-1 214 | e 14/3 19/-1 215 | e 19/3 25/-1 216 | e 18/3 24/-1 217 | e 17/3 23/-1 218 | -------------------------------------------------------------------------------- /examples/twill.yarns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/textiles-lab/smobj/a0743546e88de8502a3538445b9b3b1c7a7a8628/examples/twill.yarns -------------------------------------------------------------------------------- /examples/two-sheets.smobj: -------------------------------------------------------------------------------- 1 | L knit+ -lX +yX +lX -yX 2 | L knit+.2111 -lX +yX +lX -yX 3 | L drop- -l1 -y0 +l0 +y0 4 | L drop+ -l1 +y0 +l0 -y0 5 | L knit- -lX -yX +lX +yX 6 | L knit-fair-isle-1+ -lX +yX +lX -yX 7 | L knit-fair-isle-2+ -lX +yX +lX -yX 8 | L knit-plating-1+ -lX +yX +lX -yX 9 | L knit-plating-2+ -lX +yX +lX -yX 10 | L purl+ -lX +yX +lX -yX 11 | L purl- -lX -yX +lX +yX 12 | L tuck-twist+ -lX +yX +lX -yX 13 | L edge) x x x +y1 -y1 14 | L edge( x -y1 +y1 x x 15 | L make-left-split+ -lX +yX +lX +lX -yX 16 | L make-left-tuck+ -lX +yX +lX +lX -yX 17 | L make-left-tuck-twist+ -lX +yX +lX +lX -yX 18 | L make-left-tuck-twist- -lX -yX +lX +lX +yX 19 | L make-right-split+ -lX +yX +lX +lX -yX 20 | L make-right-tuck+ -lX +yX +lX +lX -yX 21 | L make-right-tuck-twist+ -lX +yX +lX +lX -yX 22 | L make-right-tuck-twist- -lX -yX +lX +lX +yX 23 | L tuck-twist- -lX -yX +lX +yX 24 | L decrease-right- -lX -lX -yX +lX +yX 25 | v -1 -0.61 0 26 | v 0.928562 -0.61 0 27 | v 0.904285 0.61 0 28 | v -1 0.61 0 29 | v 1.26738 -0.61 0 30 | v 3.19594 -0.61 0 31 | v 3.19594 0.61 0 32 | v 1.29048 0.61 0 33 | v 3.52499 -0.61 0 34 | v 5.52499 -0.61 0 35 | v 5.52499 0.61 0 36 | v 3.52499 0.61 0 37 | v -1.04786 0.982386 0 38 | v 0.952142 0.982386 0 39 | v 0.952142 2.16391 0 40 | v -1.04786 2.08704 0 41 | v 1.24321 0.95146 0 42 | v 3.24321 0.95146 0 43 | v 3.24321 2.17146 0 44 | v 1.24321 2.17146 0 45 | v 3.52499 0.919362 0 46 | v 5.52499 0.919362 0 47 | v 5.52499 2.13936 0 48 | v 3.52499 2.13936 0 49 | v 3.52499 2.44505 0 50 | v 5.52499 2.44505 0 51 | v 5.52499 3.66505 0 52 | v 3.52499 3.66505 0 53 | v 1.24321 2.47587 0 54 | v 3.24321 2.47587 0 55 | v 3.24321 3.69588 0 56 | v 1.24321 3.69588 0 57 | v -1.04786 2.49228 0 58 | v 0.952142 2.47268 0 59 | v 0.952142 3.68495 0 60 | v -1.04786 3.68495 0 61 | v 5.95728 -0.61 0 62 | v 7.95728 -0.61 0 63 | v 7.95728 2.05717 0 64 | v 5.95728 2.05717 0 65 | v 5.95728 0.723585 0 66 | v -9.57265 -0.0872602 0 67 | v -7.57265 -0.0872602 0 68 | v -7.57265 1.13274 0 69 | v -9.57265 1.13274 0 70 | v -7.2665 -0.0872602 0 71 | v -5.2665 -0.0872602 0 72 | v -5.2665 1.13274 0 73 | v -7.2665 1.13274 0 74 | v -5.01435 -0.0872602 0 75 | v -3.01435 -0.0872602 0 76 | v -3.01435 1.13274 0 77 | v -5.01435 1.13274 0 78 | v -9.57265 1.34886 0 79 | v -7.57265 1.34886 0 80 | v -7.57265 2.56886 0 81 | v -9.57265 2.56886 0 82 | v -7.2665 1.33179 0 83 | v -5.2665 1.33179 0 84 | v -5.2665 2.55179 0 85 | v -7.2665 2.55179 0 86 | v -5.01435 1.3546 0 87 | v -3.01435 1.3546 0 88 | v -3.01435 2.5746 0 89 | v -5.01435 2.5746 0 90 | v -5.01435 2.81851 0 91 | v -3.01435 2.81851 0 92 | v -3.01435 4.03851 0 93 | v -5.01435 4.03851 0 94 | v -7.2665 2.81701 0 95 | v -5.2665 2.81701 0 96 | v -5.2665 4.03701 0 97 | v -7.2665 4.03701 0 98 | v -9.57265 2.80292 0 99 | v -7.57265 2.80292 0 100 | v -7.57265 4.02292 0 101 | v -9.57265 4.02292 0 102 | v -12.0633 -0.123425 0 103 | v -10.0633 -0.123425 0 104 | v -10.0633 2.54207 0 105 | v -12.0633 2.54207 0 106 | v -10.0633 1.20932 0 107 | f 1 2 3 4 108 | T 12 109 | N 0 110 | f 5 6 7 8 111 | T 12 112 | N 0 113 | f 9 10 11 12 114 | T 12 115 | N 0 116 | f 13 14 15 16 117 | T 5 118 | N 0 119 | f 17 18 19 20 120 | T 5 121 | N 0 122 | f 21 22 23 24 123 | T 5 124 | N 0 125 | f 25 26 27 28 126 | T 4 127 | N 0 128 | f 29 30 31 32 129 | T 4 130 | N 0 131 | f 33 34 35 36 132 | T 4 133 | N 0 134 | f 37 38 39 40 41 135 | T 13 136 | N 0 137 | f 42 43 44 45 138 | T 23 139 | N 0 140 | f 46 47 48 49 141 | T 23 142 | N 0 143 | f 50 51 52 53 144 | T 23 145 | N 0 146 | f 54 55 56 57 147 | T 1 148 | N 0 149 | f 58 59 60 61 150 | T 1 151 | N 0 152 | f 62 63 64 65 153 | T 1 154 | N 0 155 | f 66 67 68 69 156 | T 3 157 | N 0 158 | f 70 71 72 73 159 | T 3 160 | N 0 161 | f 74 75 76 77 162 | T 3 163 | N 0 164 | f 78 79 82 80 81 165 | T 14 166 | N 0 167 | e 1/2 2/-4 168 | e 2/2 3/-4 169 | e 3/3 6/-1 170 | e 2/3 5/-1 171 | e 1/3 4/-1 172 | e 4/3 9/-1 173 | e 5/3 8/-1 174 | e 6/3 7/-1 175 | e 5/2 6/-4 176 | e 4/2 5/-4 177 | e 3/2 10/-5 178 | e 6/2 10/-4 179 | e 11/3 14/-1 180 | e 12/3 15/-1 181 | e 13/3 16/-1 182 | e 16/3 17/-1 183 | e 15/3 18/-1 184 | e 14/3 19/-1 185 | e 11/2 12/-4 186 | e 14/2 15/-4 187 | e 15/2 16/-4 188 | e 12/2 13/-4 189 | e 11/4 20/-2 190 | e 14/4 20/-3 191 | h 11/1 f0 u 192 | h 12/1 f1 u 193 | h 13/1 f2 u 194 | h 20/2 f-0.5 u 195 | h 1/1 f2 u 196 | h 2/1 f3 u 197 | h 3/1 f4 u 198 | h 10/5 f4.5 u 199 | t 1 front h 200 | t 2 front h 201 | t 3 front h 202 | t 10 front h 203 | t 11 front h 204 | t 12 front h 205 | t 13 front h 206 | t 20 front h 207 | h 1/2 f2.5 i 208 | h 1/3 f2 i 209 | h 1/4 f1.5 i 210 | h 2/2 f3.5 i 211 | h 2/3 f3 i 212 | h 2/4 f2.5 i 213 | h 3/2 f4.5 i 214 | h 3/3 f4 i 215 | h 3/4 f3.5 i 216 | h 4/1 f2 i 217 | h 5/1 f3 i 218 | h 6/1 f4 i 219 | h 6/2 f4.5 h 220 | h 10/1 x5 i 221 | h 10/2 x5 i 222 | h 10/3 x5 i 223 | h 10/4 f4.5 i 224 | h 11/2 f0.5 i 225 | h 11/3 f0 i 226 | h 11/4 f-0.5 i 227 | h 12/2 f1.5 i 228 | h 12/3 f1 i 229 | h 12/4 f0.5 i 230 | h 13/2 f2.5 i 231 | h 13/3 f2 i 232 | h 13/4 f1.5 i 233 | h 14/1 f0 i 234 | h 14/4 f-0.5 h 235 | h 15/1 f1 i 236 | h 16/1 f2 i 237 | h 20/1 x-1 i 238 | h 20/3 f-0.5 i 239 | h 20/4 x-1 i 240 | h 20/5 x-1 i 241 | o 1/1 1/2 h 242 | o 2/1 2/2 h 243 | o 3/1 3/2 h 244 | o 13/1 13/2 h 245 | o 12/1 12/2 h 246 | o 11/1 11/2 h 247 | t 4 front h 248 | t 5 front h 249 | t 6 front h 250 | t 14 front h 251 | t 15 front h 252 | t 16 front h 253 | h 4/2 f2.5 i 254 | h 4/3 f2 i 255 | h 4/4 f1.5 i 256 | h 5/2 f3.5 i 257 | h 5/3 f3 i 258 | h 5/4 f2.5 i 259 | h 6/3 f4 h 260 | h 6/4 f3.5 h 261 | h 7/1 f4 h 262 | h 8/1 f3 i 263 | h 9/1 f2 i 264 | h 14/2 f0.5 h 265 | h 14/3 f0 h 266 | h 15/2 f1.5 i 267 | h 15/3 f1 i 268 | h 15/4 f0.5 i 269 | h 16/2 f2.5 i 270 | h 16/3 f2 i 271 | h 16/4 f1.5 i 272 | h 17/1 f2 i 273 | h 18/1 f1 i 274 | h 19/1 f0 h 275 | t 7 front h 276 | t 8 front h 277 | t 9 front h 278 | t 17 front h 279 | t 18 front h 280 | t 19 front h 281 | h 7/2 f4.5 h 282 | h 7/3 x4 h 283 | h 7/4 f3.5 h 284 | h 8/2 f3.5 i 285 | h 8/3 x3 i 286 | h 8/4 f2.5 i 287 | h 9/2 f2.5 i 288 | h 9/3 x2 i 289 | h 9/4 f1.5 i 290 | h 17/2 f2.5 i 291 | h 17/3 x2 i 292 | h 17/4 f1.5 i 293 | h 18/2 f1.5 i 294 | h 18/3 x1 i 295 | h 18/4 f0.5 i 296 | h 19/2 f0.5 h 297 | h 19/3 x0 h 298 | h 19/4 f-0.5 h 299 | o 1/2 2/1 u 300 | o 2/2 3/1 u 301 | o 3/2 6/1 u 302 | o 6/1 5/1 u 303 | o 5/1 4/1 u 304 | o 4/1 9/1 u 305 | o 9/1 8/1 u 306 | o 8/1 7/1 u 307 | o 13/2 12/1 u 308 | o 12/2 11/1 u 309 | o 11/2 14/1 u 310 | o 14/1 15/1 u 311 | o 15/1 16/1 u 312 | o 16/1 17/1 u 313 | o 17/1 18/1 u 314 | o 18/1 19/1 u 315 | #o 7/1 13/1 u 316 | I 1/1 317 | I 1/2 318 | I 2/1 319 | I 2/2 320 | I 3/1 321 | I 3/2 322 | I 6/1 323 | I 5/1 324 | I 4/1 325 | I 9/1 326 | I 8/1 327 | I 7/1 328 | I 13/1 329 | I 13/2 330 | I 12/1 331 | I 12/2 332 | I 11/1 333 | I 11/2 334 | I 14/1 335 | I 15/1 336 | I 16/1 337 | I 17/1 338 | I 18/1 339 | I 19/1 340 | -------------------------------------------------------------------------------- /faces/README.md: -------------------------------------------------------------------------------- 1 | # Stitch Mesh Face Libraries 2 | 3 | This folder contains several face libraries for use in various stitch meshes. 4 | 5 | ## `illustration.sf` -- faces for knitting illustration 6 | 7 | Faces included in the library: 8 | 9 | ### Increases (`make-*`) 10 | 11 | Increases are point-up pentagonal faces with a loop entering from the bottom, yarns entering/exiting to the sides, and two loops exiting from the top. 12 | The name indicates which of the existing loops is the "new" loop and how it is made, along with the direction of yarn travel. 13 | 14 | Increases are named `make-`(`left`|`right`)`-`(`tuck`|`tuck-twist`|`split`)(`+`|`-`). 15 | - `left`|`right` indicates which loop is new (i.e., "not just knit through [or exactly] the old loop") 16 | - `left`: the left loop is the new one 17 | - `right`: the right loop is the new one 18 | - `tuck`|... indicates the method of making the new loop. 19 | - `tuck`: the new loop is tucked in the same direction as the yarn is already tavelling 20 | - `twisted-tuck`: the new loop is tucked on the front bed opposite the direction the yarn is already travelling. (I.e., a twisted tuck, with the direction of the twist such that the exiting yarn is behind the entering yarn.) 21 | - `split`: the new loop is split through the old loop (the other loop is just the old loop) 22 | - `+`|`-` indicates direction of yarn travel 23 | - `+` yarn enters from the left, exits to the right 24 | - `-` yarn enters from the right, exits to the left 25 | 26 | *NOTE:* it is slightly odd that the `split` increase doesn't knit through the old loop after splitting through it, while the other increases all do this. 27 | 28 | ### Decreases (`decrease-*`) 29 | 30 | Decreases are point-down pentogonal faces with two loops entering from the bottom, yarns entering/exiting from the sides, and a single loop (knit through both entering loops) exiting from the top. 31 | The name indicates the stacking order of the loops and the direction of yarn travel. 32 | 33 | Decreases are named `decrease-`(`left`|`right`)(`+`|`-`) 34 | - `left`|`right` indicates the lean of the decrease (i.e., which entering loop is stacked on top) 35 | - `left`: the right loop is stacked atop the left loop. (a "left-leaning" decrease) 36 | - `right`: the right loop is stacked atop the right loop. (a "right-leaning" decrease) 37 | - `+`|`-` direction of yarn travel 38 | - `+` yarn enters from the left, exits to the right 39 | - `-` yarn enters from the right, exits to the left 40 | 41 | *NOTE:* in previous versions of this face library, the `-` versions of the decreases had the incorrect names (left vs right), such that changing from the `+` to the `-` version of a face would also change the loop stacking order. 42 | 43 | ### Turns (`turn-*`) 44 | 45 | Faces for yarns turning at the end of a short row. 46 | Diamond-shaped with yarns entering/exiting on two adjacent sides and loops entering/exiting on the other two sides. 47 | 48 | Turns are named `turn`(`-tuck`)?(`)((`|`))(`) 49 | - `-tuck` indicates that the entering yarn tucks (in its direction of travel) a loop behind the entering loop. If missing, the yarn just turns around. 50 | - `)((`|`))(` indicates the shape 51 | - `)((`: the yarn enters via the lower left edge, exits via the upper left edge; the loop enters via the lower right edge, exits via the upper right edge. 52 | - `))(`: the yarn enters via the lower right edge, exits via the upper right face; the loop enters via the lower left edge, exits via the upper left edge. 53 | 54 | 55 | ### Edges (`edge*`) 56 | 57 | Edges are pentagonal faces for connecting yarns between rows of knitting. 58 | 59 | Edges are named `edge`(`(`|`)`). 60 | - `edge(` connects yarn from the lower right to the upper right face. 61 | - `edge)` connects yarn from the lower left to the upper left face. 62 | 63 | ### Starts (`start*`) 64 | 65 | Starts are the first stitch made by an entering yarn. They are left-or-right-pointing triangular faces with loops entering from the bottom and exiting from the top, and yarns exiting to the left or right. 66 | 67 | Starts are named `start`(`<`|`>`). 68 | - `start<` is a leftward-pointing triangle with yarn exiting to the right 69 | - `start>` is a rightward-pointing triangle with yarn exiting to the left 70 | 71 | *NOTE:* the `.sf` format provides no way to start a yarn in the middle of a face, so the "fresh yarn" starts at the corner of the triangle. 72 | 73 | ### Ends (`end*`) 74 | 75 | Ends are the last stitch made by an exiting yarn. They are left-or-right-pointing triangular faces with loops entering from the bottom and exiting from the top, and yarns entering to the left or right. 76 | 77 | Ends are named `end`(`<`|`>`). 78 | - `end<` is a leftward-pointing triangle with yarn entering from the right 79 | - `end>` is a rightward-pointing triangle with yarn entering from the left 80 | 81 | *NOTE:* the `.sf` format provides no way to end a yarn in the middle of a face, so the "exiting yarn" ends at the corner of the triangle. 82 | 83 | ### Ins / Outs (`in*`, `out*`) 84 | 85 | Faces that just take a yarn in or out. Triangular with only one yarn in/out edge. The `+` variety is for yarns travelling right, the `-` variety is for yarns travelling left. 86 | 87 | ### Knits (`knit*`,`purl*`) 88 | 89 | Rectangular stitches that front- or back-bed knit a stitch. Loops enter from the bottom and exit to the top; yarns enter from the left/right and exit to the right/left. 90 | 91 | Knits are named (`knit`|`purl`)(`-`|`+`) 92 | - `knit`|`purl` indicates the direction the new loop is pulled through the old loop. 93 | - `knit`: the new loop is pulled forward (i.e., a front-bed knit) 94 | - `purl`: the new loop is pulled backward (i.e., a back-bed knit) 95 | - `+`|`-` direction of yarn travel 96 | - `+` yarn enters from the left, exits to the right 97 | - `-` yarn enters from the right, exits to the left 98 | 99 | ### Drops (`drop`) 100 | Rectangular faces that drop a loop. A loop enters from the bottom, all other edges remain uncrossed. 101 | 102 | *NOTE:* in the past, there were both `drop+` and `drop-` variations, but these don't actually differ unless you keep track of the directions of empty edges so were removed. 103 | 104 | ### Twisted Tucks (`tuck-twist*`) 105 | 106 | Rectangular face holding an against-yarn-direction front-bed tuck (that is, a twisted tuck where the entering yarn passes in front of the exiting yarn). 107 | The bottom edge is blank, the left and right edges connect to yarns, a loop exits from the top edge. 108 | 109 | Twisted tucks are named `tuck-twist`(`+`|`-`) 110 | - `+`|`-` direction of yarn travel (also sets twist direction of tuck) 111 | - `+` yarn enters from the left, exits to the right 112 | - `-` yarn enters from the right, exits to the left 113 | 114 | ### Et Cetera 115 | 116 | There are other faces in `illustration.sf` from various projects; in many cases there aren't full directional sets or they aren't quite modelled properly. As such, they are not documented here. (Eventually, though, they should be!) 117 | 118 | 119 | ## `knitout.sf` -- faces used by `knitout-to-smobj` 120 | 121 | Basic faces for machine operations along with faces for yarn movement between operations. 122 | Really not meant to be used other than as part of the `knitout-to-smobj` + `smobj-to-yarns` pipeline. 123 | 124 | ## `weave.sf` -- faces for weaving 125 | 126 | Contains two square faces, `over` and `under`, modelling a weft crossing either over or under a warp. 127 | -------------------------------------------------------------------------------- /faces/illustration.code: -------------------------------------------------------------------------------- 1 | # convention 2 | # face face-name[yarn-dir] 3 | ###Note: yarn-dir convention when looking at the face from the outside on the front i.e., knit+ uses knit + f./knit - b. 4 | # edge [consume/produce+type]edge-label needle-resource yarn-resoure (for each edge in face) 5 | # variant name 6 | # code 7 | # ##knitout code 8 | # ;;Carriers: 9 | # op bedneedle(s) yarn-carriers(s) 10 | # #(consume loops from bedneedle(s) bound to incoming edges -yX -lX) 11 | # #(produce loops on bedneedle(s) bound to outgoing edges +yX +lX) 12 | # #(every out edge must be produced!) 13 | # #(every in edge must be utilized!) 14 | 15 | 16 | #TODO 17 | #1. Yarn in and yarn out faces 18 | 19 | #### front-bed variants ##### 20 | face make-left-tuck+ 21 | edge -lX f0 22 | edge +yX f0.5 A 23 | edge +lX f0 24 | edge +lX f-1 25 | edge -yX f-0.5 A 26 | variant front 27 | code 28 | ;;Carriers: A 29 | tuck + f-1 A 30 | knit + f0 A 31 | 32 | face make-right-tuck+ 33 | edge -lX f0 34 | edge +yX f0.5 A 35 | edge +lX f1 36 | edge +lX f0 37 | edge -yX f-0.5 A 38 | variant front 39 | code 40 | ;;Carriers: A 41 | knit + f0 A 42 | tuck + f1 A 43 | 44 | face make-left-tuck-twist+ 45 | edge -lX f0 46 | edge +yX f0.5 A 47 | edge +lX f0 48 | edge +lX f-1 49 | edge -yX f-0.5 A 50 | variant front 51 | code 52 | ;;Carriers: A 53 | tuck - f-1 A 54 | knit + f0 A 55 | 56 | face make-left-tuck-twist- 57 | edge -lX f0 58 | edge -yX f0.5 A 59 | edge +lX f0 60 | edge +lX f-1 61 | edge +yX f-0.5 A 62 | variant front 63 | code 64 | ;;Carriers: A 65 | knit - f0 A 66 | tuck + f-1 A 67 | 68 | face make-right-tuck-twist+ 69 | edge -lX f0 70 | edge +yX f0.5 A 71 | edge +lX f0 72 | edge +lX f1 73 | edge -yX f-0.5 A 74 | variant front 75 | code 76 | ;;Carriers: A 77 | knit + f0 A 78 | tuck - f1 A 79 | 80 | face make-right-tuck-twist- 81 | edge -lX f0 82 | edge -yX f+0.5 A 83 | edge +lX f0 84 | edge +lX f1 85 | edge +yX f-0.5 A 86 | variant front 87 | code 88 | ;;Carriers: A 89 | tuck + f1 A 90 | knit - f0 A 91 | 92 | #face make-left-split+ 93 | # edge -lX f0 94 | # edge +yX f-0.5 A 95 | # edge +lX f1 96 | # edge +lX f0 97 | # edge -yX f0.5 A 98 | # code 99 | # pass #TODO placeholder 100 | # 101 | #face make-right-split+ 102 | # edge -lX f0 103 | # edge +yX f0.5 A 104 | # edge +lX f1 105 | # edge +lX f0 106 | # edge -yX f-0.5 A 107 | # code 108 | # pass #TODO placeholder 109 | # 110 | face decrease-right+ #decrease onto the rightwards vs decrease the rightmost 111 | edge -lX f0 112 | edge -lX f1 113 | edge +yX f1.5 A 114 | edge +lX f1 115 | edge -yX f0.5 A 116 | variant front 117 | code 118 | ;;Carriers: A 119 | xfer - f0 b0 #+/- direction are hints on the src, + = everything to the right of f0 120 | #rack 1, implicit racking should be fine right? 121 | xfer - b0 f1 122 | knit + f1 A 123 | 124 | face decrease-left- 125 | edge -lX f0 126 | edge -lX f1 127 | edge -yX f1.5 A 128 | edge +lX f0 129 | edge +yX f-0.5 A 130 | variant front 131 | code 132 | ;;Carriers: A 133 | xfer f1 b1 134 | xfer b1 f0 135 | knit - f0 A 136 | 137 | face decrease-left+ 138 | edge -lX f0 139 | edge -lX f1 140 | edge +yX f0.5 A 141 | edge +lX f0 142 | edge -yX f-0.5 A 143 | variant front 144 | code 145 | ;;Carriers: A 146 | xfer f1 b1 147 | xfer b1 f0 148 | knit + f0 A 149 | 150 | face decrease-right- 151 | edge -lX f0 152 | edge -lX f1 153 | edge -yX f-0.5 A 154 | edge +lX f1 155 | edge +yX f+0.5 A 156 | variant front 157 | code 158 | ;;Carriers: A 159 | xfer f0 b0 160 | xfer b0 f1 161 | knit + f1 A 162 | 163 | 164 | 165 | face turn-tuck)(( #NOTE: tuck is in the direction of the lower course 166 | edge -lX f0 167 | edge +lX f0 168 | edge +yX f-0.5 A 169 | edge -yX f-0.5 A 170 | variant front 171 | code 172 | ;;Carriers: A 173 | tuck + f0 A 174 | miss - f0 A 175 | 176 | face turn-tuck))( 177 | edge -lX f0 178 | edge -yX f0.5 A 179 | edge +yX f0.5 A 180 | edge +lX f0 181 | variant front 182 | code 183 | ;;Carriers: A 184 | tuck - f0 A 185 | miss + f0 A 186 | #TODO update the geometry face 187 | face turn)(( 188 | edge -lX f0 189 | edge +lX f0 190 | edge +yX f-0.5 A 191 | edge -yX f-0.5 A 192 | variant front 193 | code 194 | ;;Carriers: A 195 | miss + f0 A 196 | miss - f0 A 197 | 198 | face turn))( 199 | edge -lX f0 200 | edge -yX f0.5 A 201 | edge +yX f0.5 A 202 | edge +lX f0 203 | variant front 204 | code 205 | ;;Carriers: A 206 | miss - f0 A 207 | miss + f0 A 208 | 209 | face edge( 210 | edge x 211 | edge -y1 f0.5 A 212 | edge +y1 f0.5 A 213 | edge x 214 | edge x 215 | variant front 216 | code 217 | #pass #misses, maybe nothing to do other than get ready for going the other way 218 | ;;Carriers: A 219 | 220 | face edge) 221 | edge x 222 | edge x 223 | edge x 224 | edge +y1 f-0.5 A 225 | edge -y1 f-0.5 A 226 | variant front 227 | code 228 | #pass #misses? nothing to do other than get ready for going the other way 229 | ;;Carriers: A 230 | 231 | face end< #NOTE: needs another type for "in" which is also the more complex type (inhook or tuck from gripper/release) 232 | edge -lX f0 233 | edge -yX f+0.5 A 234 | edge +lX f0 235 | variant front 236 | code 237 | ;;Carriers: A 238 | knit - f0 A 239 | out A 240 | 241 | face end> 242 | edge -lX f0 243 | edge +lX f0 244 | edge -yX f-0.5 A 245 | variant front 246 | code 247 | ;;Carriers: A 248 | knit + f0 A 249 | out A 250 | 251 | 252 | face start< 253 | edge -lX f0 254 | edge +lX f0 255 | edge +yX f0.5 A 256 | variant front 257 | code 258 | ;;Carriers: A 259 | in A 260 | knit - f0 A 261 | 262 | face start> 263 | edge -lX f0 264 | edge +yX f-0.5 A 265 | edge +lX f0 266 | variant front 267 | code 268 | ;;Carriers: A 269 | in A 270 | knit + f0 A 271 | 272 | face knit+ 273 | edge -lX f0 274 | edge +yX f0.5 A 275 | edge +lX f0 276 | edge -yX f-0.5 A 277 | variant front 278 | code 279 | ;;Carriers: A 280 | knit + f0 A 281 | 282 | face knit- 283 | edge -lX f0 284 | edge -yX f+0.5 A 285 | edge +lX f0 286 | edge +yX f-0.5 A 287 | variant front 288 | code 289 | ;;Carriers: A 290 | knit - f0 A 291 | 292 | face knit-fair-isle-2+ #slightly awkward in terms of using all resources 293 | edge -lX f0 294 | edge +yX f0.5 A B 295 | edge +lX f0 296 | edge -yX f-0.5 A B 297 | variant frontB 298 | code 299 | ;;Carriers: A B 300 | knit + f0 B 301 | miss + f0 A 302 | 303 | face knit-fair-isle-1+ 304 | edge -lX f0 305 | edge +yX f0.5 A B 306 | edge +lX f0 307 | edge -yX f-0.5 A B 308 | variant frontA 309 | code 310 | ;;Carriers: A B 311 | knit + f0 A 312 | miss + f0 B 313 | 314 | face knit-fair-isle-1- 315 | edge -lX f0 316 | edge -yX f+0.5 A B 317 | edge +lX f0 318 | edge +yX f-0.5 A B 319 | variant front 320 | code 321 | ;;Carriers: A B 322 | knit - f0 A 323 | 324 | face knit-fair-isle-2- 325 | edge -lX f0 326 | edge -yX f+0.5 A B 327 | edge +lX f0 328 | edge +yX f-0.5 A B 329 | variant front 330 | code 331 | ;;Carriers: A B 332 | knit - f0 B 333 | 334 | 335 | 336 | face knit-plating-1+ 337 | edge -lX f0 338 | edge +yX f0.5 A B 339 | edge +lX f0 340 | edge -yX f-0.5 A B 341 | variant frontAB 342 | code 343 | ;;Carriers: A B 344 | knit + f0 A B 345 | 346 | face knit-plating-2+ 347 | edge -lX f0 348 | edge +yX f0.5 A B 349 | edge +lX f0 350 | edge -yX f-0.5 A B 351 | variant frontBA 352 | code 353 | ;;Carriers: A B 354 | knit + f0 B A 355 | 356 | face knit+.2111 #What face is this ?? 357 | edge -lX f0 358 | edge +yX f-0.5 A 359 | edge +lX f0 360 | edge -yX f0.5 A 361 | variant front 362 | code 363 | ;;Carriers: A 364 | knit + f0 A 365 | 366 | face knittuck+ 367 | edge -lX f0 368 | edge +yX f0.5 A 369 | edge +lX f0 370 | edge -yX f-0.5 A 371 | variant front 372 | code 373 | ;;Carriers: A 374 | knit + f0 A 375 | 376 | face knittuck- 377 | edge -lX f0 378 | edge -yX f-0.5 A 379 | edge +lX f0 380 | edge +yX f0.5 A 381 | variant front 382 | code 383 | ;;Carriers: A 384 | knit - f0 A 385 | 386 | 387 | face knittuck+ 388 | edge -lX b0 389 | edge +yX b+0.5 A 390 | edge +lX b0 391 | edge -yX b-0.5 A 392 | variant back 393 | code 394 | ;;Carriers: A 395 | knit + b0 A 396 | 397 | face knittuck- 398 | edge -lX b0 399 | edge -yX b-0.5 A 400 | edge +lX b0 401 | edge +yX b+0.5 A 402 | variant back 403 | code 404 | ;;Carriers: A 405 | knit - b0 A 406 | 407 | 408 | face drop+ 409 | edge -l1 f0 410 | edge +y0 f0.5 411 | edge +l0 x 412 | edge -y0 f-0.5 413 | variant front 414 | code 415 | ;;Carriers: A 416 | drop f0 417 | 418 | face drop- 419 | edge -l1 f0 420 | edge -y0 f0.5 421 | edge +l0 x 422 | edge +y0 f-0.5 423 | variant front 424 | code 425 | ;;Carriers: A 426 | drop f0 427 | 428 | face tuck-twist+ 429 | edge -lX f0 430 | edge +yX f0.5 A 431 | edge +lX f0 432 | edge -yX f-0.5 A 433 | variant front 434 | code 435 | ;;Carriers: A 436 | tuck - f0 A 437 | miss + f0 A 438 | 439 | face tuck-twist- 440 | edge -lX f0 441 | edge -yX f+0.5 A 442 | edge +lX f0 443 | edge +yX f-0.5 A 444 | variant front 445 | code 446 | ;;Carriers: A 447 | tuck + f0 A 448 | miss - f0 A 449 | 450 | 451 | face purl+ 452 | edge -lX f0 453 | edge +yX f0.5 A 454 | edge +lX f0 455 | edge -yX f-0.5 A 456 | variant front 457 | code 458 | ;;Carriers: A 459 | xfer f0 b0 460 | knit + b0 A 461 | xfer b0 f0 462 | 463 | face purl- 464 | edge -lX f0 465 | edge -yX f0.5 A 466 | edge +lX f0 467 | edge +yX f-0.5 A 468 | variant front 469 | code 470 | ;;Carriers: A 471 | xfer f0 b0 472 | knit - b0 A 473 | xfer b0 f0 474 | 475 | #### back-bed variants ##### 476 | face make-left-tuck+ 477 | edge -lX b0 478 | edge +yX b0.5 A 479 | edge +lX b0 480 | edge +lX b-1 481 | edge -yX b-0.5 A 482 | variant back 483 | code 484 | ;;Carriers: A 485 | knit - b0 A 486 | tuck - b-1 A 487 | 488 | face make-right-tuck+ 489 | edge -lX b0 490 | edge +yX b0.5 A 491 | edge +lX b1 492 | edge +lX b0 493 | edge -yX b-0.5 A 494 | variant back 495 | code 496 | ;;Carriers: A 497 | tuck - b1 A 498 | knit - b0 A 499 | 500 | face make-left-tuck-twist+ 501 | edge -lX b0 502 | edge +yX b0.5 A 503 | edge +lX b0 504 | edge +lX b-1 505 | edge -yX b-0.5 A 506 | variant bacl 507 | code 508 | ;;Carriers: A 509 | knit + b0 A 510 | tuck - b-1 A 511 | 512 | face make-left-tuck-twist- 513 | edge -lX b0 514 | edge -yX b0.5 A 515 | edge +lX b0 516 | edge +lX b-1 517 | edge +yX b-0.5 A 518 | variant back 519 | code 520 | ;;Carriers: A 521 | knit - b0 A 522 | tuck + b-1 A 523 | 524 | face make-right-tuck-twist+ 525 | edge -lX b0 526 | edge +yX b0.5 A 527 | edge +lX b0 528 | edge +lX b1 529 | edge -yX b-0.5 A 530 | variant back 531 | code 532 | ;;Carriers: A 533 | tuck - b1 A 534 | knit + b0 A 535 | 536 | face make-right-tuck-twist- 537 | edge -lX b0 538 | edge -yX b+0.5 A 539 | edge +lX b0 540 | edge +lX b1 541 | edge +yX b-0.5 A 542 | variant back 543 | code 544 | ;;Carriers: A 545 | knit - b0 A 546 | tuck + b1 A 547 | 548 | #face make-left-split+ 549 | # edge -lX f0 550 | # edge +yX f-0.5 A 551 | # edge +lX f1 552 | # edge +lX f0 553 | # edge -yX f0.5 A 554 | # code 555 | # pass #TODO placeholder 556 | # 557 | #face make-right-split+ 558 | # edge -lX f0 559 | # edge +yX f0.5 A 560 | # edge +lX f1 561 | # edge +lX f0 562 | # edge -yX f-0.5 A 563 | # code 564 | # pass #TODO placeholder 565 | # 566 | face decrease-right+ #decrease onto the rightwards vs decrease the rightmost 567 | edge -lX b1 568 | edge -lX b0 569 | edge +yX b1.5 A 570 | edge +lX b0 571 | edge -yX b0.5 A 572 | variant back 573 | code 574 | ;;Carriers: A 575 | xfer b1 f0 #+/- direction are hints on the src, + = everything to the right of f0 576 | #rack 1, implicit racking should be fine right? 577 | xfer f0 b0 578 | knit + b0 A 579 | 580 | face decrease-left- 581 | edge -lX b1 582 | edge -lX b0 583 | edge -yX b1.5 A 584 | edge +lX b1 585 | edge +yX b-0.5 A 586 | variant back 587 | code 588 | ;;Carriers: A 589 | xfer b0 f1 590 | xfer f1 b1 591 | knit + b1 A 592 | 593 | face decrease-left+ 594 | edge -lX b1 595 | edge -lX b0 596 | edge +yX b0.5 A 597 | edge +lX b1 598 | edge -yX b-0.5 A 599 | variant back 600 | code 601 | ;;Carriers: A 602 | xfer b0 f1 603 | xfer f1 b1 604 | knit - b1 A 605 | 606 | face decrease-right- 607 | edge -lX b1 608 | edge -lX b0 609 | edge -yX b-0.5 A 610 | edge +lX b0 611 | edge +yX b+0.5 A 612 | variant back 613 | code 614 | ;;Carriers: A 615 | xfer b1 f0 616 | xfer f0 b0 617 | knit - b0 A 618 | 619 | 620 | 621 | face turn-tuck)(( #NOTE: tuck is in the direction of the lower course 622 | edge -lX b0 623 | edge +lX b0 624 | edge +yX b-0.5 A 625 | edge -yX b-0.5 A 626 | variant back 627 | code 628 | ;;Carriers: A 629 | miss + b0 A 630 | tuck - b0 A 631 | 632 | face turn-tuck))( 633 | edge -lX b0 634 | edge -yX b0.5 A 635 | edge +yX b0.5 A 636 | edge +lX b0 637 | variant back 638 | code 639 | ;;Carriers: A 640 | tuck + b0 A 641 | miss - b0 A 642 | 643 | face turn)(( 644 | edge -lX b0 645 | edge +lX b0 646 | edge +yX b+0.5 A 647 | edge -yX b+0.5 A 648 | variant back 649 | code 650 | ;;Carriers: A 651 | miss + b0 A 652 | 653 | face turn))( 654 | edge -lX b0 655 | edge -yX b-0.5 A 656 | edge +yX b-0.5 A 657 | edge +lX b0 658 | variant back 659 | code 660 | ;;Carriers: A 661 | miss - b0 A 662 | 663 | face edge( 664 | edge x 665 | edge -y1 b-0.5 A 666 | edge +y1 b-0.5 A 667 | edge x 668 | edge x 669 | variant back 670 | code 671 | #pass #misses, maybe nothing to do other than get ready for going the other way 672 | ;;Carriers: A 673 | 674 | face edge) 675 | edge x 676 | edge x 677 | edge x 678 | edge +y1 b0.5 A 679 | edge -y1 b0.5 A 680 | variant back 681 | code 682 | #pass #misses? nothing to do other than get ready for going the other way 683 | ;;Carriers: A 684 | 685 | face end< #NOTE: needs another type for "in" which is also the more complex type (inhook or tuck from gripper/release) 686 | edge -lX b0 687 | edge -yX b-0.5 A 688 | edge +lX b0 689 | variant back 690 | code 691 | ;;Carriers: A 692 | knit + b0 A 693 | out A 694 | 695 | face end> 696 | edge -lX b0 697 | edge +lX b0 698 | edge -yX b+0.5 A 699 | variant back 700 | code 701 | ;;Carriers: A 702 | knit - b0 A 703 | out A 704 | 705 | 706 | face start< 707 | edge -lX b0 708 | edge +lX b0 709 | edge +yX b-0.5 A 710 | variant back 711 | code 712 | ;;Carriers: A 713 | in A 714 | knit + b0 A 715 | 716 | face start> 717 | edge -lX b0 718 | edge +yX b0.5 A 719 | edge +lX b0 720 | variant back 721 | code 722 | ;;Carriers: A 723 | in A 724 | knit - b0 A 725 | 726 | face knit+ 727 | edge -lX b0 728 | edge +yX b+0.5 A 729 | edge +lX b0 730 | edge -yX b-0.5 A 731 | variant back 732 | code 733 | ;;Carriers: A 734 | knit + b0 A 735 | 736 | face knit- 737 | edge -lX b0 738 | edge -yX b+0.5 A 739 | edge +lX b0 740 | edge +yX b-0.5 A 741 | variant back 742 | code 743 | ;;Carriers: A 744 | knit - b0 A 745 | 746 | face knit-fair-isle-2+ #slightly awkward in terms of using all resources 747 | edge -lX b0 748 | edge +yX b-0.5 A B 749 | edge +lX b0 750 | edge -yX b+0.5 A B 751 | variant backB 752 | code 753 | ;;Carriers: A B 754 | knit - b0 B 755 | 756 | face knit-fair-isle-1+ 757 | edge -lX b0 758 | edge +yX b-0.5 A B 759 | edge +lX b0 760 | edge -yX b+0.5 A B 761 | variant backA 762 | code 763 | ;;Carriers: A B 764 | knit - b0 A 765 | 766 | face knit-plating-1+ 767 | edge -lX b0 768 | edge +yX b-0.5 A B 769 | edge +lX b0 770 | edge -yX b0.5 A B 771 | variant backAB 772 | code 773 | ;;Carriers: A B 774 | knit - b0 A B 775 | 776 | face knit-plating-2+ 777 | edge -lX b0 778 | edge +yX b-0.5 A B 779 | edge +lX b0 780 | edge -yX b0.5 A B 781 | variant backBA 782 | code 783 | ;;Carriers: A B 784 | knit - b0 B A 785 | 786 | face knit+.2111 #What face is this ?? 787 | edge -lX b0 788 | edge +yX b0.5 A 789 | edge +lX b0 790 | edge -yX b-0.5 A 791 | variant back 792 | code 793 | ;;Carriers: A 794 | knit - b0 A 795 | 796 | face drop+ 797 | edge -l1 b0 798 | edge +y0 b-0.5 799 | edge +l0 x 800 | edge -y0 b+0.5 801 | variant back 802 | code 803 | ;;Carriers: A 804 | drop b0 805 | 806 | face drop- 807 | edge -l1 b0 808 | edge -y0 b-0.5 809 | edge +l0 x 810 | edge +y0 b0.5 811 | variant back 812 | code 813 | ;;Carriers: A 814 | drop b0 815 | 816 | face tuck-twist+ 817 | edge -lX b0 818 | edge +yX b+0.5 A 819 | edge +lX b0 820 | edge -yX b-0.5 A 821 | variant back 822 | code 823 | ;;Carriers: A 824 | tuck - b0 A 825 | miss + b0 A 826 | 827 | face tuck-twist- 828 | edge -lX b0 829 | edge -yX b-0.5 A 830 | edge +lX b0 831 | edge +yX b+0.5 A 832 | variant back 833 | code 834 | ;;Carriers: A 835 | tuck + b0 A 836 | miss - b0 A 837 | 838 | 839 | face purl+ 840 | edge -lX b0 841 | edge +yX b-0.5 A 842 | edge +lX b0 843 | edge -yX b0.5 A 844 | variant back 845 | code 846 | ;;Carriers: A 847 | xfer b0 f0 848 | knit - f0 A 849 | xfer f0 b0 850 | 851 | face purl- 852 | edge -lX b0 853 | edge -yX b-0.5 A 854 | edge +lX b0 855 | edge +yX b0.5 A 856 | variant back 857 | code 858 | ;;Carriers: A 859 | xfer b0 f0 860 | knit + f0 A 861 | xfer f0 b0 862 | 863 | 864 | 865 | 866 | 867 | 868 | #### front-back variants #### 869 | 870 | #TODO 871 | 872 | 873 | 874 | #### back-front variants #### 875 | 876 | #TODO 877 | 878 | 879 | 880 | #complex faces 881 | face spacer4+ 882 | edge -lX f0 883 | edge -lX b0 884 | edge -lX f1 885 | edge -lX b1 886 | edge -lX f2 887 | edge -lX b2 888 | edge -lX f3 889 | edge -lX b3 890 | edge +yX b3.5 B 891 | edge +lX b3 892 | edge +lX f3 893 | edge +lX b2 894 | edge +lX f2 895 | edge +lX b1 896 | edge +lX f1 897 | edge +lX b0 898 | edge +lX f0 899 | edge -yX f-0.5 B 900 | variant front-back 901 | code 902 | ;;Carriers: B 903 | tuck + f0 B 904 | tuck + b1 B 905 | tuck + f2 B 906 | tuck + b3 B 907 | #todo 908 | #face seed-stitch+ 909 | # edge -l1 f0 910 | # edge -l1 f1 911 | # edge -y1 f1.5 A 912 | # edge +y1 f1.5 B 913 | # edge +l1 f1 914 | # edge +l1 f0 915 | # edge -y1 f0.5 B 916 | # edge +y1 f0.5 A 917 | # variant fb 918 | # code 919 | # ;;Carriers: A B 920 | # #block1 921 | # xfer f0 b0 922 | # knit - f1 A 923 | # knit - b0 A 924 | # xfer b0 f0 925 | # #block2 926 | # xfer f1 b1 927 | # knit + f0 B 928 | # knit + b1 B 929 | # xfer b1 f1 930 | 931 | -------------------------------------------------------------------------------- /faces/illustration.sf: -------------------------------------------------------------------------------- 1 | face make-left-tuck+ 2 | edge (-1,-1.062) -lX 3 | edge (1,-1.062) +yX 4 | edge (1.6,0) +lX 5 | edge (0,1.2) +lX 6 | edge (-1.6,0) -yX 7 | yarn [1:0.25,0] (0.321847,-0.211278,-0.19533) (0.390594,0.0406245,0.196892) [2:0.275,0] 8 | yarn [2:0.725,0] (0.257785,0.276222,0.206233) (-0.0984679,0.224999,-0.276545) [3:0.275,0] 9 | yarn [3:0.725,0] (-0.917159,-0.201903,0) [4:0.75,0] 10 | yarn [0:0.275,0] (-0.28123,-0.0375,0.0968753) (0.0125145,0.592189,-0.0593829) (0.529687,0.375012,-0.0609375) (0.648423,-0.064061,-0.034383) (0.389042,-0.473437,0.0968753) [0:0.725,0] 11 | derive make-left-tuck- -lX -yX +lX +lX +yX by reverse-yarn from make-left-tuck+ -lX +yX +lX +lX -yX 12 | derive make-right-tuck+ -lX +yX +lX +lX -yX by mirror-x reverse-yarn from make-left-tuck+ -lX +yX +lX +lX -yX 13 | derive make-right-tuck- -lX -yX +lX +lX +yX by reverse-yarn from make-right-tuck+ -lX +yX +lX +lX -yX 14 | face make-left-tuck-twist+ 15 | edge (-1,-1.062) -lX 16 | edge (1,-1.062) +yX 17 | edge (1.6,0) +lX 18 | edge (0,1.2) +lX 19 | edge (-1.6,0) -yX 20 | yarn [1:0.25,0] (0.321847,-0.211278,-0.19533) (0.390594,0.0406245,0.196892) [2:0.275,0] 21 | yarn [2:0.725,0] (0.257785,0.276222,0.206233) (-0.11253,0.154686,-0.276545) (-0.742187,0.1375,-0.15467) [3:0.725,0] 22 | yarn [3:0.275,0] (-0.420284,0.252785,0.0484375) (-0.785937,-0.384375,-0.0437325) [4:0.75,0] 23 | yarn [0:0.275,0] (-0.28123,-0.0375,0.0968753) (0.0125145,0.592189,-0.0593829) (0.529687,0.375012,-0.0609375) (0.648423,-0.064061,-0.034383) (0.389042,-0.473437,0.0968753) [0:0.725,0] 24 | face make-left-tuck-twist- 25 | edge (-1,-1.062) -lX 26 | edge (1,-1.062) -yX 27 | edge (1.6,0) +lX 28 | edge (0,1.2) +lX 29 | edge (-1.6,0) +yX 30 | yarn [1:0.25,0] (0.321847,-0.211278,-0.19533) (0.390594,0.0406245,0.196892) [2:0.275,0] 31 | yarn [2:0.725,0] (0.257785,0.276222,0.206233) (-0.11253,0.154686,-0.276545) (-0.698437,0.192188,0.165642) [3:0.725,0] 32 | yarn [3:0.275,0] (-0.699972,0.221535,-0.142188) (-0.946874,-0.384375,-0.0437325) [4:0.75,0] 33 | yarn [0:0.275,0] (-0.28123,-0.0375,0.0968753) (0.0125145,0.592189,-0.0593829) (0.529687,0.375012,-0.0609375) (0.648423,-0.064061,-0.034383) (0.389042,-0.473437,0.0968753) [0:0.725,0] 34 | derive make-right-tuck-twist+ -lX +yX +lX +lX -yX by mirror-x from make-left-tuck-twist- -lX -yX +lX +lX +yX 35 | derive make-right-tuck-twist- -lX -yX +lX +lX +yX by mirror-x from make-left-tuck-twist+ -lX +yX +lX +lX -yX 36 | face make-left-split+ 37 | edge (-1,-1.062) -lX 38 | edge (1,-1.062) +yX 39 | edge (1.6,0) +lX 40 | edge (0,1.2) +lX 41 | edge (-1.6,0) -yX 42 | yarn [1:0.25,0] (0.418722,-0.211278,-0.19533) (0.196844,0.396874,0.209392) [3:0.275,0] 43 | yarn [3:0.725,0] (0.07966,0.276222,0.279671) (0.0984075,-0.434377,-0.19217) [4:0.75,0] 44 | yarn [0:0.275,0] (-0.220293,-0.14375,0.0421877) (0.137514,0.475002,-0.0593829) [2:0.725,0] 45 | yarn [0:0.725,0] (0.353111,-0.510936,0.0421795) (0.63748,-0.0781246,0.0968753) [2:0.275,0] 46 | derive make-left-split- -lX -yX +lX +lX +yX by reverse-yarn from make-left-split+ -lX +yX +lX +lX -yX 47 | derive make-right-split+ -lX +yX +lX +lX -yX by mirror-x reverse-yarn from make-left-split+ -lX +yX +lX +lX -yX 48 | derive make-right-split- -lX -yX +lX +lX +yX by reverse-yarn from make-right-split+ -lX +yX +lX +lX -yX 49 | face decrease-right+ 50 | edge (-1.6,0) -lX 51 | edge (0,-1.2) -lX 52 | edge (1.6,0) +yX 53 | edge (1,1.062) +lX 54 | edge (-1,1.062) -yX 55 | yarn [4:0.75,0] (-0.382785,0.044972,-0.323455) (-0.079657,0.240624,0.362517) [3:0.725,0] 56 | yarn [2:0.25,0] (0.321847,-0.0972155,-0.22033) (0.0812196,0.226562,0.378142) [3:0.275,0] 57 | yarn [0:0.275,0] (-0.729667,-0.179688,0.165625) (-0.481236,0.307814,0.167179) (0,0.389074,-0.0109376) (0.442173,0.253127,0.240617) (0.371855,-0.309375,0.13125) [0:0.725,0] 58 | yarn [1:0.275,0] (-0.528105,-0.309375,-0.189062) (-0.553111,0.278126,0.062492) (0,0.420324,-0.235938) (0.471861,0.284377,0.087492) (0.721855,-0.217187,-0.0124998) [1:0.725,0] 59 | derive decrease-right- -lX -lX -yX +lX +yX by mirror-x from decrease-left+ -lX -lX +yX +lX -yX 60 | derive decrease-left+ -lX -lX +yX +lX -yX by mirror-x reverse-yarn from decrease-right+ -lX -lX +yX +lX -yX 61 | derive decrease-left- -lX -lX -yX +lX +yX by mirror-x from decrease-right+ -lX -lX +yX +lX -yX 62 | face turn-tuck)(( 63 | edge (-0.792,-1.22) -lX 64 | edge (0.792,0) +lX 65 | edge (-0.792,1.22) +yX 66 | edge (-0.792,0) -yX 67 | yarn [0:0.275,0] (-0.15625,0,0.135938) [1:0.725,0] 68 | yarn [0:0.725,0] (0.35,0,0) [1:0.275,0] 69 | yarn [3:0.75,0] (-0.5,0,0.125) [1:0.735,-0.2] 70 | yarn [2:0.75,0] (-0.553125,-0.028125,-0.125) (-0.0546876,-0.114062,-0.1) [1:0.265,-0.2] 71 | derive turn-tuck))( -lX -yX +yX +lX by mirror-x from turn-tuck)(( -lX +lX +yX -yX 72 | face turn)(( 73 | edge (-0.792,-1.22) -lX 74 | edge (0.792,0) +lX 75 | edge (-0.792,1.22) +yX 76 | edge (-0.792,0) -yX 77 | yarn [0:0.275,0] (-0.15625,0,0) [1:0.725,0] 78 | yarn [0:0.725,0] (0.35,0,0) [1:0.275,0] 79 | yarn [3:0.75,0] (-0.473438,-0.285938,0) [2:0.75,0] 80 | derive turn))( -lX -yX +yX +lX by mirror-x from turn)(( -lX +lX +yX -yX 81 | face edge( 82 | edge (-0.5,-1.22) x 83 | edge (0.5,-1.22) -y1 84 | edge (0.5,0) +y1 85 | edge (0.5,1.22) x 86 | edge (-0.5,1.22) x 87 | yarn [1:0.25,0] (0.123438,-0.785937,0) (0.09375,0.198438,0) [2:0.25,0] 88 | derive edge) x x x +y1 -y1 by mirror-x from edge( x -y1 +y1 x x 89 | face start> 90 | edge (-0.952,-0.61) -lX 91 | edge (0.952,0) +lX 92 | edge (-0.952,0.61) +yX 93 | yarn [0:0.275,0] (-0.606716,-0.149663,0.169228) (-0.759235,0.151189,-0.050332) (0.378368,0.186132,-0.0941806) [0:0.725,0] 94 | yarn [1:0,0] (0.891181,-0.085622,-0.19533) (0.0831026,-0.153897,-0.371019) (0.00638064,0.242545,0.324701) [1:0.275,0] 95 | yarn [2:0.75,0] (-0.524186,-0.123972,-0.0761219) (-0.395259,0.277524,0.19289) [1:0.725,0] 96 | derive start< -lX +yX +lX by mirror-x from start> -lX +lX +yX 97 | face in+ 98 | edge (-0.5,0.0) x 99 | edge (0.5,-0.61) +yX 100 | edge (0.5,0.61) x 101 | yarn [0:0,0] (0.1,-0.2,0.0) (0.1,0.0,0.0) [1:0.25,0] 102 | derive in- x x +yX by mirror-x from in+ x +yX x 103 | face out- 104 | edge (-0.5,0.0) x 105 | edge (0.5,-0.61) -yX 106 | edge (0.5,0.61) x 107 | yarn [0:0,0] (0.1, 0.2,0.0) (0.1,0.0,0.0) [1:0.25,0] 108 | derive out+ x x -yX by mirror-x from out- x -yX x 109 | face end< 110 | edge (-0.952,0) -lX 111 | edge (0.952,-0.61) -yX 112 | edge (0.952,0.61) +lX 113 | yarn [0:0,0] (-0.584375,-0.0109375,-0.107812) (0.123466,0.00278445,-0.215642) (-0.0421566,0.207812,0.168767) [2:0.725,0] 114 | yarn [1:0.25,0] (0.321847,-0.211278,-0.19533) (0.295282,0.207812,0.135955) [2:0.275,0] 115 | yarn [0:0.275,0] (-0.129667,-0.109375,0.0968753) (-0.196861,0.159377,-0.137508) (0.203125,0.307824,-0.0890625) (0.632798,0.150001,-0.137508) (0.578105,-0.196875,0.0968753) [0:0.725,0] 116 | derive end> -lX +lX -yX by mirror-x from end< -lX -yX +lX 117 | face knit+ 118 | edge (-1,-0.61) -lX 119 | edge (1,-0.61) +yX 120 | edge (1,0.61) +lX 121 | edge (-1,0.61) -yX 122 | yarn [3:0.75,0] (-0.321847,-0.211278,-0.19533) (-0.295282,0.207812,0.153142) [2:0.725,0] 123 | yarn [1:0.25,0] (0.321847,-0.211278,-0.19533) (0.295282,0.207812,0.153142) [2:0.275,0] 124 | yarn [0:0.275,0] (-0.528105,-0.309375,0.0968753) (-0.632798,0.129689,-0.137508) (0,0.307824,0) (0.632798,0.129689,-0.137508) (0.528105,-0.309375,0.0968753) [0:0.725,0] 125 | derive knit- -lX -yX +lX +yX by mirror-x from knit+ -lX +yX +lX -yX 126 | face knit-fair-isle-2+ 127 | edge (-1,-0.61) -lX 128 | edge (1,-0.61) +yX 129 | edge (1,0.61) +lX 130 | edge (-1,0.61) -yX 131 | yarn [3:0.6,0] (-0.321847,-0.145653,-0.0797046) (-0.295282,0.207812,0.206267) [2:0.725,0] 132 | yarn [1:0.4,0] (0.321847,-0.161278,-0.0500169) (0.295282,0.207812,0.203142) [2:0.275,0] 133 | yarn [3:0.75,0] (-0.421847,-0.354688,0) (0.37843,-0.351563,0) [1:0.25,0] 134 | yarn [0:0.275,0] (-0.528105,-0.309375,0.246875) (-0.551548,0.129689,0.0453044) (0,0.307824,-0.123438) (0.523423,0.129689,0.0531169) (0.528105,-0.309375,0.19375) [0:0.725,0] 135 | face knit-fair-isle-1+ 136 | edge (-1,-0.61) -lX 137 | edge (1,-0.61) +yX 138 | edge (1,0.61) +lX 139 | edge (-1,0.61) -yX 140 | yarn [3:0.75,0] (-0.321847,-0.286278,-0.0797046) (-0.295282,0.207812,0.206267) [2:0.725,0] 141 | yarn [1:0.25,0] (0.321847,-0.306591,-0.0500169) (0.295282,0.207812,0.203142) [2:0.275,0] 142 | yarn [3:0.6,0] (-0.421847,-0.121876,-0.2) (0.37843,-0.107813,-0.226562) [1:0.4,0] 143 | yarn [0:0.275,0] (-0.528105,-0.309375,0.201563) (-0.551548,0.129689,0.0453044) (0,0.307824,-0.123438) (0.523423,0.129689,0.0531169) (0.528105,-0.309375,0.19375) [0:0.725,0] 144 | face knit-plating-1+ 145 | edge (-1,-0.61) -lX 146 | edge (1,-0.61) +yX 147 | edge (1,0.61) +lX 148 | edge (-1,0.61) -yX 149 | yarn [3:0.75,0] (-0.321847,-0.328466,-0.046892) (-0.33747,0.207812,0.259392) [2:0.725,0] 150 | yarn [3:0.6,0] (-0.421847,-0.211278,-0.228142) (-0.345008,0.207812,0.059392) [2:0.735,-0.2] 151 | yarn [1:0.25,0] (0.321847,-0.290965,-0.0468921) (0.295282,0.207812,0.250017) [2:0.275,0] 152 | yarn [1:0.4,0] (0.414034,-0.211278,-0.254705) (0.360633,0.207812,0.10158) [2:0.265,-0.2] 153 | yarn [0:0.275,0] (-0.528105,-0.234375,0.246875) (-0.551548,0.290626,-0.228133) (0,0.350011,-0.240626) (0.578111,0.296876,-0.178133) (0.528105,-0.25625,0.19375) [0:0.725,0] 154 | face knit-plating-2+ 155 | edge (-1,-0.61) -lX 156 | edge (1,-0.61) +yX 157 | edge (1,0.61) +lX 158 | edge (-1,0.61) -yX 159 | yarn [3:0.6,0] (-0.321847,-0.240966,-0.046892) (-0.33747,0.207812,0.259392) [2:0.725,0] 160 | yarn [3:0.75,0] (-0.421847,-0.283153,-0.228142) (-0.345008,0.207812,0.059392) [2:0.735,-0.2] 161 | yarn [1:0.4,0] (0.320284,-0.233152,-0.0468921) (0.31872,0.207812,0.250017) [2:0.275,0] 162 | yarn [1:0.25,0] (0.414034,-0.281591,-0.254705) (0.360633,0.207812,0.10158) [2:0.265,-0.2] 163 | yarn [0:0.275,0] (-0.528105,-0.234375,0.246875) (-0.551548,0.290626,-0.228133) (0,0.350011,-0.240626) (0.578111,0.296876,-0.178133) (0.528105,-0.25625,0.19375) [0:0.725,0] 164 | derive knit-fair-isle-2- -lX -yX +lX +yX by mirror-x from knit-fair-isle-2+ -lX +yX +lX -yX 165 | derive knit-fair-isle-1- -lX -yX +lX +yX by mirror-x from knit-fair-isle-1+ -lX +yX +lX -yX 166 | derive knit-plating-2- -lX -yX +lX +yX by mirror-x from knit-plating-2+ -lX +yX +lX -yX 167 | derive knit-plating-1- -lX -yX +lX +yX by mirror-x from knit-plating-1+ -lX +yX +lX -yX 168 | 169 | face knit+.2111 170 | edge (-1,-0.61) -lX 171 | edge (1,-0.61) +yX 172 | edge (1,0.61) +lX 173 | edge (-1,0.61) -yX 174 | yarn [3:0.75,0] (-0.321847,-0.211278,-0.271892) (-0.295282,0.207812,0.206267) [2:0.725,0] 175 | yarn [1:0.25,0] (0.321847,-0.211278,-0.303142) (0.295282,0.207812,0.203142) [2:0.275,0] 176 | yarn [0:0.275,0] (-0.528105,-0.309375,0.246875) (-0.551548,0.129689,0.0453044) (0,0.307824,-0.123438) (0.523423,0.129689,0.0531169) (0.528105,-0.309375,0.19375) [0:0.725,0] 177 | yarn [0:0.265,-0.2] (-0.528105,-0.309375,0.110937) (-0.532798,0.129689,-0.184383) (0,0.217199,-0.301562) (0.585923,0.129689,-0.140633) (0.528105,-0.309375,0) [0:0.735,-0.2] 178 | face drop 179 | edge (-1,-0.61) -l1 180 | edge (1,-0.61) +y0 181 | edge (1,0.61) +l0 182 | edge (-1,0.61) -y0 183 | yarn [0:0.275,0] (-0.528105,-0.309375,0.0968753) (-0.632798,0.129689,-0.137508) (0,0.307824,0) (0.632798,0.129689,-0.137508) (0.528105,-0.309375,0.0968753) [0:0.725,0] 184 | 185 | #it doesn't make sense to have directional drops given they have empty yarn edges anyway 186 | #derive drop- -l1 -y0 +l0 +y0 by mirror-x from drop+ -l1 +y0 +l0 -y0 187 | 188 | face knittuck+ 189 | edge (-1,-0.61) -lX 190 | edge (1,-0.61) +yX 191 | edge (1,0.61) +lX 192 | edge (-1,0.61) -yX 193 | yarn [3:0.75,0] (-0.321847,-0.211278,-0.271892) (-0.295282,0.207812,0.206267) [2:0.725,0] 194 | yarn [1:0.25,0] (0.321847,-0.211278,-0.303142) (0.295282,0.207812,0.203142) [2:0.275,0] 195 | yarn [0:0.275,0] (-0.528105,-0.309375,0.246875) (-0.551548,0.129689,0.0453044) (0,0.307824,-0.123438) (0.523423,0.129689,0.0531169) (0.528105,-0.309375,0.19375) [0:0.725,0] 196 | yarn [0:0.275,+0.2] (-0.528105,-0.309375,0.110937) (-0.532798,0.129689,-0.184383) (0,0.217199,-0.301562) (0.585923,0.129689,-0.140633) (0.528105,-0.309375,0) [0:0.725,+0.2] #0.275 to 0.265, 0.735 to 0.725 197 | 198 | derive knittuck- -lX -yX +lX +yX by mirror-x from knittuck+ -lX +yX +lX -yX 199 | 200 | 201 | face tuck-twist+ 202 | edge (-1,-0.61) -lX 203 | edge (1,-0.61) +yX 204 | edge (1,0.61) +lX 205 | edge (-1,0.61) -yX 206 | yarn [3:0.75,0] (-0.257784,-0.276903,0.146858) (0.401593,0.207812,0.104704) [2:0.275,0] 207 | yarn [1:0.25,0] (0.306222,-0.250341,-0.100017) (-0.362531,0.174999,-0.0577956) [2:0.725,0] 208 | derive tuck-twist- -lX -yX +lX +yX by mirror-x from tuck-twist+ -lX +yX +lX -yX 209 | face purl+ 210 | edge (-1,-0.61) -lX 211 | edge (1,-0.61) +yX 212 | edge (1,0.61) +lX 213 | edge (-1,0.61) -yX 214 | yarn [3:0.75,0] (-0.321847,-0.211278,0.19533) (-0.295282,0.207812,-0.153142) [2:0.725,0] 215 | yarn [1:0.25,0] (0.321847,-0.211278,0.19533) (0.295282,0.207812,-0.153142) [2:0.275,0] 216 | yarn [0:0.275,0] (-0.528105,-0.309375,-0.0968753) (-0.632798,0.129689,0.137508) (0,0.307824,0) (0.632798,0.129689,0.137508) (0.528105,-0.309375,-0.0968753) [0:0.725,0] 217 | derive purl- -lX -yX +lX +yX by mirror-x from purl+ -lX +yX +lX -yX 218 | face xfer+1 219 | edge (-1,-0.61) -lX 220 | edge (1,-0.61) x 221 | edge (1,0.61) +lX 222 | edge (-1,0.61) x 223 | yarn [0:0.275,0] [2:0.725,0] 224 | yarn [0:0.725,0] [2:0.275,0] 225 | 226 | face spacer4+ 227 | edge (-7,-0.61) -lX 228 | edge (-5,-0.61) -lX 229 | edge (-3,-0.61) -lX 230 | edge (-1,-0.61) -lX 231 | edge (1,-0.61) -lX 232 | edge (3,-0.61) -lX 233 | edge (5,-0.61) -lX 234 | edge (7,-0.61) -lX 235 | edge (9,-0.61) +yX 236 | edge (9,0.61) +lX 237 | edge (7,0.61) +lX 238 | edge (5,0.61) +lX 239 | edge (3,0.61) +lX 240 | edge (1,0.61) +lX 241 | edge (-1,0.61) +lX 242 | edge (-3,0.61) +lX 243 | edge (-5,0.61) +lX 244 | edge (-7,0.61) -yX 245 | yarn [17:0.75,0.2] (-6.3807,0.0615054,0.0783768) [16:0.725,0.2] 246 | yarn [16:0.275,0.2] (-5.53152,-0.263767,0.0783768) (-0.448553,-0.20429,0.0783768) [13:0.725,0.2] 247 | yarn [13:0.275,0.2] (0.448813,-0.230587,0.0783768) (3.50419,-0.252973,0.0783768) [12:0.725,0.2] 248 | yarn [12:0.275,0.2] (4.40271,-0.0750856,0.0783768) (7.54326,-0.0875983,0.0783768) [9:0.725,0.2] 249 | yarn [9:0.275,0.2] (8.37946,-0.246589,0) [8:0.25,0.2] 250 | 251 | yarn [0:0.275,0] [16:0.725,0] 252 | yarn [0:0.725,0] [16:0.275,0] 253 | yarn [1:0.275,0] [15:0.725,0] 254 | yarn [1:0.725,0] [15:0.275,0] 255 | yarn [2:0.275,0] [14:0.725,0] 256 | yarn [2:0.725,0] [14:0.275,0] 257 | yarn [3:0.275,0] [13:0.725,0] 258 | yarn [3:0.725,0] [13:0.275,0] 259 | yarn [4:0.275,0] [12:0.725,0] 260 | yarn [4:0.725,0] [12:0.275,0] 261 | yarn [5:0.275,0] [11:0.725,0] 262 | yarn [5:0.725,0] [11:0.275,0] 263 | yarn [6:0.275,0] [10:0.725,0] 264 | yarn [6:0.725,0] [10:0.275,0] 265 | yarn [7:0.275,0] [9:0.725,0] 266 | yarn [7:0.725,0] [9:0.275,0] 267 | 268 | 269 | #for pockets: 270 | 271 | face pocketedge-plating( 272 | edge (-1,-0.61) -l1 273 | edge (1, -0.61) -y1 274 | edge (1,0.61) -y1 275 | edge (1,1.83) +l2 276 | edge (-1,0.61) +y1 277 | 278 | yarn [4:0.75,0] (-0.321847,-0.211278,-0.160243) (-0.295282,0.207812,0.246004) [3:0.725,0] 279 | yarn [1:0.25,0] (0.321847,-0.332519,-0.19533) (0.295282,0.0112654,0.23587) [3:0.275,0] 280 | yarn [0:0.275,0] (-0.528105,-0.309375,0.0968753) (-0.632798,0.129689,-0.167848) (0,0.307824,-0.0544934) (0.632798,0.129689,-0.0425662) (0.528105,-0.309375,0.0968753) [0:0.725,0] 281 | yarn [2:0.25,0] (0.321847,-0.175244,-0.19533) (0.295282,0.207812,0.142015) [3:0.265,-0.2] 282 | yarn [4:0.6,0] (-0.321847,-0.211278,-0.267911) (-0.295282,0.207812,0.134247) [3:0.735,-0.2] 283 | 284 | 285 | derive pocketedge-plating) -l1 +y1 +l2 -y1 -y1 by mirror-x from pocketedge-plating( -l1 -y1 -y1 +l2 +y1 286 | 287 | 288 | 289 | face pocketedge( 290 | edge (-1,-1.22) -l1 291 | edge ( 1,-1.22) -y1 292 | edge ( 1,-0.61) -y1 293 | edge ( 1, 0.0 ) +y1 294 | edge ( 1, 0.61) +y1 295 | edge ( 1, 1.22) +l1 296 | edge (-1, 1.22) -y1 297 | edge (-1, 0.0 ) +y1 298 | 299 | yarn [1:0.25,0] (0.543028,-0.74329,-0.100862) (0.688572,-0.292925,-0.121927) (-0.0336773,-0.0395826,-0.238296) (-0.499376,-0.293063,-0.281293) (-0.439727,-0.738544,-0.140647) (-0.736914,-1.18448,0) (-0.865421,-0.316692,0.264004) (-0.492667,0.284253,0.0608442) (-0.608861,0.762228,-0.275417) (0.511038,0.786415,-0.223257) (0.516782,0.203661,-0.0780975) [3:0.25,0] 300 | yarn [2:0.25,0] (0.590018,-0.747071,-0.352666) (0.359931,-0.500861,-0.189323) (0.351557,-0.254652,0.204723) (0.472784,0.278684,0.102362) (0.625069,0.787986,0) (-0.0719096,0.892346,-0.0908363) (-0.583898,0.71198,-0.0959212) (-0.503119,0.312233,0.309832) (-0.341961,-0.21664,0.0799649) (-0.16644,-0.460651,-0.186262) (-0.410292,-0.750701,-0.361349) (-0.837584,-0.703797,0) [7:0.75,0] 301 | yarn [6:0.75,0] (-0.573587,0.278305,-0.180858) (-0.313174,0.513729,-0.223092) (-0.301368,0.749152,0.188838) [5:0.725,0] 302 | yarn [5:0.275,0] (0.35311,0.820318,0.207595) (0.229266,0.516868,-0.254486) (0.612775,0.223947,-0.371523) [4:0.25,0] 303 | yarn [0:0.275,0] (-0.448723,-0.703725,0.0968753) (-0.508038,-0.272489,-0.167848) (0,0.0181742,-0.0544934) (0.632798,-0.253431,-0.0425662) (0.528105,-0.775606,0.0968753) [0:0.725,0] 304 | 305 | 306 | derive pocketedge) -l1 +y1 -y1 +l1 +y1 +y1 -y1 -y1 by mirror-x from pocketedge( -l1 -y1 -y1 +y1 +y1 +l1 -y1 +y1 307 | 308 | 309 | face pocketedgeT( 310 | edge (-1,-1.22) -l1 311 | edge ( 1,-1.22) -y1 312 | edge ( 1,-0.61) -y1 313 | edge ( 1, 0.0 ) +y1 314 | edge ( 1, 0.61) -y1 315 | edge ( 1, 1.22) +l1 316 | edge (-1, 1.22) +y1 317 | edge (-1, 0.0 ) +y1 318 | 319 | yarn [1:0.25,0] (0.543028,-0.74329,-0.100862) (0.688572,-0.292925,-0.121927) (-0.0336773,-0.0395826,-0.238296) (-0.499376,-0.293063,-0.281293) (-0.439727,-0.738544,-0.140647) (-0.736914,-1.18448,0) (-0.865421,-0.316692,0.264004) (-0.492667,0.284253,0.0608442) (-0.608861,0.762228,-0.275417) (0.511038,0.786415,-0.223257) (0.516782,0.203661,-0.0780975) [3:0.25,0] 320 | yarn [2:0.25,0] (0.590018,-0.747071,-0.352666) (0.359931,-0.500861,-0.189323) (0.351557,-0.254652,0.204723) (0.472784,0.278684,0.102362) (0.625069,0.787986,0) (-0.0719096,0.892346,-0.0908363) (-0.583898,0.71198,-0.0959212) (-0.503119,0.312233,0.309832) (-0.341961,-0.21664,0.0799649) (-0.16644,-0.460651,-0.186262) (-0.410292,-0.750701,-0.361349) (-0.837584,-0.703797,0) [7:0.75,0] 321 | yarn [6:0.75,0] (-0.573587,0.278305,-0.180858) (-0.313174,0.513729,-0.223092) (-0.301368,0.749152,0.188838) [5:0.725,0] 322 | yarn [5:0.275,0] (0.35311,0.820318,0.207595) (0.229266,0.516868,-0.254486) (0.612775,0.223947,-0.371523) [4:0.25,0] 323 | yarn [0:0.275,0] (-0.448723,-0.703725,0.0968753) (-0.508038,-0.272489,-0.167848) (0,0.0181742,-0.0544934) (0.632798,-0.253431,-0.0425662) (0.528105,-0.775606,0.0968753) [0:0.725,0] 324 | 325 | 326 | derive pocketedgeT) -l1 -y1 -y1 +l1 +y1 -y1 +y1 +y1 by mirror-x reverse-yarn from pocketedgeT( -l1 -y1 -y1 +y1 -y1 +l1 +y1 +y1 -------------------------------------------------------------------------------- /faces/weave.sf: -------------------------------------------------------------------------------- 1 | face over 2 | edge (-0.2,-0.2) -a1 3 | edge (0.2,-0.2) +e1 4 | edge (0.2,0.2) +a1 5 | edge (-0.2,0.2) -e1 6 | yarn [0:0.5,0] (0.018722,-0.0644024,0.10783) (0.02497,0.089062,0.0812325) [2:0.5,0] 7 | yarn [1:0.5,0] (0.101534,-0.00502697,-0.0874825) (-0.053155,0.00624941,-0.109392) [3:0.5,0] 8 | face under 9 | edge (-0.2,-0.2) -a1 10 | edge (0.2,-0.2) +e1 11 | edge (0.2,0.2) +a1 12 | edge (-0.2,0.2) -e1 13 | yarn [0:0.5,0] (0.018722,-0.0644024,-0.10783) (0.02497,0.089062,-0.0812325) [2:0.5,0] 14 | yarn [1:0.5,0] (0.101534,-0.00502697,0.0874825) (-0.053155,0.00624941,0.109392) [3:0.5,0] 15 | -------------------------------------------------------------------------------- /utilities/.gitignore: -------------------------------------------------------------------------------- 1 | knitout-to-smobj.dSYM 2 | knitout-to-smobj 3 | smobj-to-yarns.dSYM 4 | smobj-to-yarns 5 | text-to-smobj.dSYM 6 | text-to-smobj 7 | simplify-yarns.dSYM 8 | simplify-yarns 9 | merge-faces.dSYM 10 | merge-faces 11 | yarns-to-bccx 12 | yarns-to-bccx.dSYM 13 | yarn-units 14 | yarn-units.dSYM 15 | sm.o 16 | -------------------------------------------------------------------------------- /utilities/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY : all 2 | 3 | #From: https://stackoverflow.com/questions/714100/os-detecting-makefile 4 | UNAME_S := $(shell uname -s) 5 | ifeq ($(UNAME_S),Linux) 6 | CPP=g++ -std=c++17 -Wall -Werror -g -DGLM_ENABLE_EXPERIMENTAL -O2 7 | else 8 | CPP=clang++ -std=c++17 -Wall -Werror -g -DGLM_ENABLE_EXPERIMENTAL -O2 -I/opt/homebrew/include 9 | endif 10 | 11 | all : knitout-to-smobj smobj-to-yarns text-to-smobj simplify-yarns merge-faces yarns-to-bccx yarn-units 12 | 13 | clean : 14 | rm -f knitout-to-smobj text-to-smobj smobj-to-yarns simplify-yarns merge-faces sm.o 15 | 16 | knitout-to-smobj : knitout-to-smobj.cpp 17 | $(CPP) -o '$@' '$<' 18 | 19 | 20 | text-to-smobj : text-to-smobj.cpp sm.hpp sm.o 21 | $(CPP) -o '$@' '$<' sm.o 22 | 23 | smobj-to-yarns : smobj-to-yarns.cpp sm.hpp sm.o 24 | $(CPP) -o '$@' '$<' sm.o 25 | 26 | simplify-yarns : simplify-yarns.cpp sm.hpp sm.o 27 | $(CPP) -o '$@' '$<' sm.o 28 | 29 | yarn-units : yarn-units.cpp sm.hpp sm.o 30 | $(CPP) -o '$@' '$<' sm.o 31 | 32 | yarns-to-bccx : yarns-to-bccx.cpp sm.hpp sm.o 33 | $(CPP) -o '$@' '$<' sm.o 34 | 35 | sm.o : sm.cpp sm.hpp 36 | $(CPP) -c -o '$@' '$<' 37 | 38 | hinters.o : hinters.cpp hinters.hpp 39 | $(CPP) -c -o '$@' '$<' 40 | 41 | merge-faces : merge-faces.cpp sm.hpp sm.o 42 | $(CPP) -o '$@' '$<' sm.o 43 | 44 | test-code : test-code.cpp hinters.hpp sm.hpp sm.o hinters.o 45 | $(CPP) -o '$@' '$<' hinters.o sm.o 46 | 47 | #generic rules for knitout -> smobj -> yarns 48 | 49 | %.smobj : %.knitout knitout-to-smobj 50 | ./knitout-to-smobj '$<' '$@' 51 | 52 | %.yarns : %.smobj ../faces/knitout.sf smobj-to-yarns 53 | ./smobj-to-yarns '$<' '../faces/knitout.sf' '$@' 54 | -------------------------------------------------------------------------------- /utilities/NOTES.txt: -------------------------------------------------------------------------------- 1 | 2 | Basic flow of knitout to smobj translation: 3 | 4 | Maintain: 5 | - height of each column of stitches (per needle location per bed) 6 | - face/edge index at the top of each column 7 | - locations of all inter-bed crossings 8 | - parking locations for each yarn carrier 9 | 10 | Per instruction -- 11 | (1a) if yarn not in, yarn appears on carrier track at stitch-aligned location 12 | (1b) if yarn is in, line is made from old location to stitch-aligned location 13 | (2) line is made from carrier track to stitch edge 14 | (3) stitch face is made 15 | (4) line is made from stitch edge to carrier track 16 | (5) whole assembly is hoisted as needed to avoid collisions 17 | 18 | ----- 19 | 20 | TODO: 21 | - Check: does leading carrier end up on the front or the back when pulling a loop to the back during plating? (Currently, face library assumes it ends up to the back.) 22 | - Consider making yarn travel faces shorter somehow. 23 | 24 | - When not dropping loops, should somehow add checkpoints at yarn ends, otherwise to-yarns translator is unhappy (and even if it fixes this with a zero-length checkpoint, it still fails to split yarn length in loop properly) 25 | => intrinsically, this is a problem with the opaque way in which yarn connections inside faces are handled in knitout-to-smobj; using more explicit faces might simplify things, since dangling yarn ends could be searched back to their origins. 26 | -------------------------------------------------------------------------------- /utilities/hinters.hpp: -------------------------------------------------------------------------------- 1 | // helpers to generate hinted smobjs 2 | #include "sm.hpp" 3 | // add to the sm namespace 4 | namespace sm{ 5 | sm::Mesh constraint_assign_frontface_variant(sm::Mesh const &mesh, sm::Code const &code_library); 6 | sm::Mesh hint_shortrow_only_patch(sm::Mesh const &in, sm::Code const &code_library); 7 | sm::Mesh hint_shortrow_only_tubes(sm::Mesh const &in, sm::Code const &code_library); 8 | sm::Mesh infer_constraints(sm::Mesh &in, sm::Code const &code_library, sm::Library const &face_library); 9 | bool constraint_assign_order_from_face_order(sm::Mesh &mesh, sm::Code const &code_library, sm::Library const &face_library); 10 | bool constraint_assign_variant_from_resource(sm::Mesh &mesh, sm::Code const &code_library); 11 | bool constraint_extend_resource_from_resource(sm::Mesh &mesh, sm::Code const &code_library); 12 | bool constraint_face_instruction_order(sm::Mesh &mesh, sm::Code const &code_library); 13 | 14 | }; 15 | -------------------------------------------------------------------------------- /utilities/merge-faces.cpp: -------------------------------------------------------------------------------- 1 | #include "sm.hpp" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | // assumes that the given smobj is a single connected component... 9 | int main(int argc, char* argv[]){ 10 | if(argc < 5){ 11 | std::cout << "Usage: ./merge-faces lib.sf face1 face2 out.sf" << std::endl; 12 | return 1; 13 | } 14 | std::string in_sf = argv[1]; 15 | std::string in_smobj = argv[2]; 16 | std::string out_sf = argv[3]; 17 | std::string out_smobj = argv[4]; 18 | 19 | //load in_sf library, load in_smobj, merge all faces in it based on connections.. 20 | // along any connection, turn an edge point into a 3D spline position 21 | // update the end points' edges 22 | //generate a new library face and a new smobj 23 | 24 | sm::Library library = sm::Library::load(in_sf); 25 | sm::Mesh smobj = sm::Mesh::load(in_smobj); 26 | std::cout << "Library has " << library.faces.size() << " faces." << std::endl; 27 | std::cout << "Smobj has " << smobj.faces.size() << " faces." << std::endl; 28 | 29 | std::map< sm::Mesh::FaceEdge, sm::Mesh::FaceEdge> old_fe_to_new_fe; 30 | std::set deleted_faces; 31 | 32 | std::map library_name_to_index; 33 | for(auto const &l : library.faces){ 34 | library_name_to_index[l.key()] = &l - &library.faces[0]; 35 | } 36 | 37 | 38 | // keep track of connections per face for cheaper handling + dealing with multi connection faces. 39 | 40 | for(auto const &c : smobj.connections){ 41 | // merge along connection c 42 | 43 | sm::Mesh::FaceEdge a = c.a; 44 | sm::Mesh::FaceEdge b = c.b; 45 | if(smobj.faces[a.face].type < 0 || smobj.faces[a.face].type >= smobj.library.size()){ 46 | std::cout << "face a's type is out of bounds. " << std::endl; 47 | } 48 | if(smobj.faces[b.face].type < 0 || smobj.faces[b.face].type >= smobj.library.size()){ 49 | std::cout << "face b's type is out of bounds. " << std::endl; 50 | } 51 | std::string a_name = smobj.library[smobj.faces[a.face].type]; 52 | std::string b_name = smobj.library[smobj.faces[b.face].type]; 53 | if(library_name_to_index.count(a_name) == 0){ 54 | std::cerr << "Face a's lib name not found in library " << a_name << std::endl; 55 | } 56 | if(library_name_to_index.count(b_name) == 0){ 57 | std::cerr << "Face b's lib name not found in library " << b_name << std::endl; 58 | } 59 | sm::Library::Face la = library.faces[library_name_to_index[a_name]]; 60 | sm::Library::Face lb = library.faces[library_name_to_index[b_name]]; 61 | 62 | if(a.face == b.face) { 63 | std::cout << "----- face has multiple connects, TODO resolve this ---- " << std::endl; 64 | continue; 65 | } 66 | 67 | std::cout << "Merging face " << b.face << " into " << a.face << std::endl; 68 | 69 | // merge library faces 70 | { 71 | sm::Library::Face l; 72 | l.name = "combo_"+la.name+"_"+lb.name; 73 | // the face and library share the same pattern, so create edges based on the new edges 74 | // need to translate based on the previous vertex 75 | assert(la.edges.size() == smobj.faces[a.face].size()); 76 | assert(lb.edges.size() == smobj.faces[b.face].size()); 77 | // l.edges.emplace_back() 78 | glm::vec2 translate = 0.5f*(la.edges[a.edge].vertex + la.edges[(a.edge+1)%la.edges.size()].vertex) - 0.5f*(lb.edges[b.edge].vertex + lb.edges[(b.edge+1)%lb.edges.size()].vertex); 79 | std::map a_edge_map, b_edge_map; 80 | { 81 | 82 | for(uint32_t k = 0; k < a.edge; ++k){ 83 | l.edges.emplace_back(la.edges[k]); 84 | a_edge_map[k] = l.edges.size()-1; 85 | } 86 | for(uint32_t k = 0; k < smobj.faces[b.face].size()-1; ++k){ 87 | l.edges.emplace_back(lb.edges[(b.edge + k + 1)%smobj.faces[b.face].size()]); 88 | l.edges.back().vertex += translate; 89 | b_edge_map[ (b.edge + k + 1)%smobj.faces[b.face].size()] = l.edges.size()-1; 90 | } 91 | for(uint32_t k = a.edge + 1; k < smobj.faces[a.face].size(); ++k){ 92 | l.edges.emplace_back(la.edges[k]); 93 | a_edge_map[k] = l.edges.size()-1; 94 | } 95 | } 96 | // translate the midpoints for all the spline points in face b: 97 | for(auto &y : lb.yarns){ 98 | for(auto &p : y.middle){ 99 | p += glm::vec3(translate, 0.f); 100 | } 101 | } 102 | // any yarn that does not end or begin on a.edge or b.edge, directly copy them 103 | for(auto ya : la.yarns){ 104 | if(ya.begin.edge != a.edge && ya.end.edge != a.edge){ 105 | l.yarns.emplace_back(ya); 106 | //map the edge to the correct new index 107 | //l.yarns.back().edge 108 | l.yarns.back().begin.edge = a_edge_map[l.yarns.back().begin.edge]; 109 | l.yarns.back().end.edge = a_edge_map[l.yarns.back().end.edge]; 110 | } 111 | } 112 | for(auto yb : lb.yarns){ 113 | if(yb.begin.edge != b.edge && yb.end.edge != b.edge){ 114 | l.yarns.emplace_back(yb); 115 | //map the edge to the correct new index 116 | //l.yarns.back().edge 117 | l.yarns.back().begin.edge = b_edge_map[l.yarns.back().begin.edge]; 118 | l.yarns.back().end.edge = b_edge_map[l.yarns.back().end.edge]; 119 | 120 | } 121 | } 122 | // merge yarns based on location 123 | // std::cout << "Trying to merge yarns between 2 faces. YA = " << la.yarns.size() << " YB = " << lb.yarns.size() << std::endl; 124 | for(auto ya : la.yarns){ 125 | //std::cout << "ya begin " << ya.begin.edge << " end " << ya.end.edge << std::endl; 126 | for(auto yb : lb.yarns){ 127 | //std::cout << "\tyb begin " << yb.begin.edge << " end " << yb.end.edge << std::endl; 128 | if(ya.end.edge == a.edge && yb.begin.edge == b.edge){ 129 | l.yarns.emplace_back(); 130 | l.yarns.back().begin = ya.begin; 131 | l.yarns.back().begin.edge = a_edge_map[l.yarns.back().begin.edge]; 132 | l.yarns.back().end = yb.end; 133 | l.yarns.back().end.edge = b_edge_map[l.yarns.back().end.edge]; 134 | 135 | glm::vec3 p1 = glm::vec3(la.edges[ya.end.edge].vertex * (1.f - ya.end.along) + ya.end.along * la.edges[(ya.end.edge+1)%la.edges.size()].vertex, 0.f); 136 | glm::vec3 p2 = glm::vec3((lb.edges[yb.begin.edge].vertex * (1.f - yb.begin.along) + yb.begin.along * lb.edges[(yb.begin.edge+1)%lb.edges.size()].vertex) + translate, 0.f); 137 | // add middle point 3D 138 | for(auto a_it = ya.middle.begin(); a_it != ya.middle.end(); ++a_it){ 139 | l.yarns.back().middle.emplace_back(*a_it); 140 | } 141 | 142 | l.yarns.back().middle.emplace_back(p1); 143 | l.yarns.back().middle.emplace_back(p2); 144 | 145 | for(auto b_it = yb.middle.begin(); b_it != yb.middle.end(); ++b_it){ 146 | l.yarns.back().middle.emplace_back(*b_it); 147 | } 148 | 149 | 150 | 151 | std::cout << "Merge yarn point between yb and ya (1)" << std::endl; 152 | } 153 | else if(ya.begin.edge == a.edge && yb.end.edge == b.edge){ 154 | l.yarns.emplace_back(); 155 | l.yarns.back().begin = yb.begin; 156 | l.yarns.back().begin.edge = b_edge_map[l.yarns.back().begin.edge]; 157 | l.yarns.back().end = ya.end; 158 | l.yarns.back().end.edge = a_edge_map[l.yarns.back().end.edge]; 159 | 160 | glm::vec3 p1 = glm::vec3((lb.edges[yb.end.edge].vertex * (1.f - yb.end.along) + yb.end.along * lb.edges[(yb.end.edge+1)%lb.edges.size()].vertex) + translate, 0.f); 161 | glm::vec3 p2 = glm::vec3(la.edges[ya.begin.edge].vertex * (1.f - ya.begin.along) + ya.begin.along * la.edges[(ya.begin.edge+1)%la.edges.size()].vertex, 0.f); 162 | // add middle point 3D 163 | 164 | for(auto b_it = yb.middle.begin(); b_it != yb.middle.end(); ++b_it){ 165 | l.yarns.back().middle.emplace_back(*b_it); 166 | } 167 | l.yarns.back().middle.emplace_back(p1); 168 | l.yarns.back().middle.emplace_back(p2); 169 | for(auto a_it = ya.middle.begin(); a_it != ya.middle.end(); ++a_it){ 170 | l.yarns.back().middle.emplace_back(*a_it); 171 | } 172 | 173 | 174 | std::cout << "Merge yarn point between ya and yb (2)" << std::endl; 175 | } 176 | else if(ya.begin.edge == a.edge && yb.begin.edge == b.edge){ 177 | l.yarns.emplace_back(); 178 | l.yarns.back().begin = ya.end; 179 | l.yarns.back().begin.edge = a_edge_map[l.yarns.back().begin.edge]; 180 | l.yarns.back().end = yb.end; 181 | l.yarns.back().end.edge = b_edge_map[l.yarns.back().end.edge]; 182 | 183 | glm::vec3 p1 = glm::vec3(la.edges[ya.begin.edge].vertex * (1.f - ya.begin.along) + ya.begin.along * la.edges[(ya.begin.edge+1)%la.edges.size()].vertex, 0.f); 184 | glm::vec3 p2 = glm::vec3((lb.edges[yb.begin.edge].vertex * (1.f - yb.begin.along) + yb.begin.along * lb.edges[(yb.begin.edge+1)%lb.edges.size()].vertex) + translate, 0.f); 185 | (void)p2; 186 | // add middle point 3D 187 | 188 | for(auto a_it = ya.middle.rbegin(); a_it != ya.middle.rend(); ++a_it){ 189 | l.yarns.back().middle.emplace_back(*a_it); 190 | } 191 | 192 | l.yarns.back().middle.emplace_back(p1); 193 | //l.yarns.back().middle.emplace_back(p2); 194 | 195 | for(auto b_it = yb.middle.begin(); b_it != yb.middle.end(); ++b_it){ 196 | l.yarns.back().middle.emplace_back(*b_it); 197 | } 198 | std::cout << "Merge yarn point between ya and yb (3)" << std::endl; 199 | } 200 | else if(ya.end.edge == a.edge && yb.end.edge == b.edge){ 201 | l.yarns.emplace_back(); 202 | l.yarns.back().begin = ya.begin; 203 | l.yarns.back().begin.edge = a_edge_map[l.yarns.back().begin.edge]; 204 | l.yarns.back().end = yb.begin; 205 | l.yarns.back().end.edge = b_edge_map[l.yarns.back().end.edge]; 206 | 207 | glm::vec3 p1 = glm::vec3(la.edges[ya.end.edge].vertex * (1.f - ya.end.along) + ya.end.along * la.edges[(ya.end.edge+1)%la.edges.size()].vertex, 0.f); 208 | glm::vec3 p2 = glm::vec3((lb.edges[yb.end.edge].vertex * (1.f - yb.end.along) + yb.end.along * lb.edges[(yb.end.edge+1)%lb.edges.size()].vertex) + translate, 0.f); 209 | (void)p2; 210 | // add middle point 3D 211 | 212 | for(auto a_it = ya.middle.begin(); a_it != ya.middle.end(); ++a_it){ 213 | l.yarns.back().middle.emplace_back(*a_it); 214 | } 215 | 216 | l.yarns.back().middle.emplace_back(p1); 217 | //l.yarns.back().middle.emplace_back(p2); 218 | 219 | for(auto b_it = yb.middle.rbegin(); b_it != yb.middle.rend(); ++b_it){ 220 | l.yarns.back().middle.emplace_back(*b_it); 221 | } 222 | std::cout << "Merge yarn point between ya and yb (4)" << std::endl; 223 | 224 | } 225 | 226 | } 227 | } 228 | library.faces.emplace_back(l); 229 | } 230 | // TODO handle the case when multiple connections between two faces exist... 231 | 232 | // merge smobj faces 233 | { 234 | // a <-- b 235 | deleted_faces.insert(b.face); 236 | // update all the fe in a.face and b.face 237 | // 5-6 238 | // | | 239 | // .=. 240 | // | | 241 | // 1-2 242 | sm::Mesh::Face face; 243 | face.type = smobj.library.size(); 244 | uint32_t expected_total = smobj.faces[a.face].size() + smobj.faces[b.face].size()-2; 245 | old_fe_to_new_fe.clear(); 246 | // a first half: 247 | for(uint32_t k = 0; k < a.edge; ++k){ 248 | face.emplace_back(smobj.faces[a.face][k]); 249 | // replace any connection with a.face, k with a.face, face.size()-1 250 | sm::Mesh::FaceEdge old_fe, new_fe; 251 | old_fe.face = a.face; new_fe.face = a.face; 252 | old_fe.edge = k; new_fe.edge = face.size()-1; 253 | old_fe_to_new_fe[old_fe] = new_fe; 254 | } 255 | // b: 256 | for(uint32_t k = 0; k < smobj.faces[b.face].size()-1; ++k){ 257 | face.emplace_back(smobj.faces[b.face][(b.edge + k + 1)%smobj.faces[b.face].size()]); 258 | // replace any connection with b.face, (b.edge + k + 1)%smobj.faces[b.face].size() 259 | // with a.face, face.size()-1 260 | sm::Mesh::FaceEdge old_fe, new_fe; 261 | old_fe.face = b.face; new_fe.face = a.face; 262 | old_fe.edge = (b.edge + k + 1)%smobj.faces[b.face].size(); 263 | new_fe.edge = face.size()-1; 264 | old_fe_to_new_fe[old_fe] = new_fe; 265 | } 266 | // a second half: 267 | for(uint32_t k = a.edge + 1; k < smobj.faces[a.face].size(); ++k){ 268 | face.emplace_back(smobj.faces[a.face][k]); 269 | // replace any connection with a.face, k with a.face, face.size()-1 270 | sm::Mesh::FaceEdge old_fe, new_fe; 271 | old_fe.face = a.face; new_fe.face = a.face; 272 | old_fe.edge = k; new_fe.edge = face.size()-1; 273 | old_fe_to_new_fe[old_fe] = new_fe; 274 | } 275 | for(auto &cc : smobj.connections){ 276 | if(old_fe_to_new_fe.count(cc.a)) cc.a = old_fe_to_new_fe[cc.a]; 277 | if(old_fe_to_new_fe.count(cc.b)) cc.b = old_fe_to_new_fe[cc.b]; 278 | } 279 | std::cout << "total " << face.size() << " expected-total " << expected_total << std::endl; 280 | assert(face.size() == expected_total); 281 | smobj.faces[a.face] = face; // update "a" 282 | } 283 | 284 | // create a new library face and assign the face type of a.face as that library face 285 | // this creates way too many temps, but that is probably okay 286 | library_name_to_index[library.faces.back().key()] = library.faces.size()-1; 287 | smobj.library.emplace_back(library.faces.back().key()); 288 | 289 | // update library_name_to_index[] 290 | 291 | // create a combined library face and add it to the end of the list 292 | // add this face name to smobj.library and update face a's type to point to this type 293 | // std::cout <<"... done merging two faces. " << std::endl; 294 | } 295 | std::cout << "fixing the rest of the mesh.. " << std::endl; 296 | // get rid of all connections 297 | smobj.connections.clear(); 298 | // faces don't get used anywhere else, so just delete faces to be deleted: 299 | smobj.faces.erase(std::remove_if(smobj.faces.begin(), 300 | smobj.faces.end(), 301 | [&deleted_faces, &smobj](sm::Mesh::Face const &f){return deleted_faces.count(&f - &smobj.faces[0]);}), 302 | smobj.faces.end()); 303 | 304 | // ensure that there is only one face left 305 | { 306 | if(smobj.faces.size() != 1){ 307 | std::cerr << "Faces have not been reduced to one face! Total faces = " << smobj.faces.size() << std::endl; 308 | } 309 | } 310 | 311 | smobj.faces[0].type = 0; 312 | smobj.library.clear(); 313 | std::string label = library.faces.back().key(); 314 | smobj.library.emplace_back(label); 315 | 316 | // get rid of any unused vertices and re-index 317 | { 318 | 319 | auto vertices = smobj.vertices; 320 | smobj.vertices.clear(); 321 | 322 | for(uint32_t x = 0; x < smobj.faces[0].size(); ++x){ 323 | smobj.vertices.emplace_back(vertices[smobj.faces[0][x]]); 324 | smobj.faces[0][x] = x; 325 | } 326 | 327 | } 328 | 329 | // TODO make sure hints are updated, for now erased.. 330 | smobj.hints.clear(); 331 | 332 | // generate a template face based on smobj face, keep track edge symbols and yarn values 333 | smobj.save(out_smobj); 334 | library.faces.erase(library.faces.begin(), library.faces.begin() + library.faces.size()-1); 335 | library.save(out_sf); 336 | 337 | std::cout << "Input .sf " << in_sf << " smobj " << in_smobj << " Output .sf " << out_sf << " smobj " << out_smobj << std::endl; 338 | 339 | return 0; 340 | } 341 | -------------------------------------------------------------------------------- /utilities/simplify-yarns.cpp: -------------------------------------------------------------------------------- 1 | #include "sm.hpp" 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | std::vector< glm::vec3 > simplify(std::vector< glm::vec3 > const &pts, float tolerance) { 12 | //too short to simplify: 13 | if (pts.size() <= 2) return pts; 14 | 15 | float tol2 = tolerance * tolerance; 16 | 17 | //where points actually map given the spline-between-midpoints of the yarn: 18 | std::vector< glm::vec3 > spline_pts; 19 | spline_pts.reserve(pts.size()); 20 | spline_pts.emplace_back(pts[0]); 21 | for (uint32_t i = 1; i + 1 < pts.size(); ++i) { 22 | glm::vec3 s = 0.5f * (pts[i-1] + pts[i]); 23 | glm::vec3 const &m = pts[i]; 24 | glm::vec3 e = 0.5f * (pts[i] + pts[i+1]); 25 | glm::vec3 sm = glm::mix(s, m, 0.5f); 26 | glm::vec3 me = glm::mix(m, e, 0.5f); 27 | spline_pts.emplace_back(glm::mix(sm, me, 0.5f)); 28 | } 29 | spline_pts.emplace_back(pts.back()); 30 | 31 | //compute the fit given points a,b,c selected: 32 | auto fit_dis2 = [&pts, &spline_pts](uint32_t a, uint32_t b, uint32_t c) -> float { 33 | assert(a < b); 34 | assert(b < c); 35 | assert(c < pts.size()); 36 | 37 | glm::vec3 s = glm::mix(pts[a], pts[b], 0.5f); 38 | glm::vec3 const &m = pts[b]; 39 | glm::vec3 e = glm::mix(pts[b], pts[c], 0.5f); 40 | 41 | float max_dis2 = 0.0f; 42 | auto check = [&s, &m, &e, &spline_pts, &max_dis2](uint32_t i, float t) { 43 | glm::vec3 const &pt = spline_pts[i]; 44 | glm::vec3 test = glm::mix( glm::mix(s,m,t), glm::mix(m,e,t), t); 45 | float dis2 = glm::length2(test - pt); 46 | max_dis2 = std::max(max_dis2, dis2); 47 | 48 | }; 49 | //check all interior points: 50 | for (uint32_t i = a + (b-a+1)/2; i < b; ++i) { 51 | float t = float(i - a) / float(b - a) - 0.5f; 52 | assert(t >= 0.0f && t <= 1.0f); //N.b. might slightly miss owning to fp precision 53 | check(i,t); 54 | } 55 | check(b, 0.5f); 56 | for (uint32_t i = b + 1; i <= b + (c-b)/2; ++i) { 57 | float t = float(i - b) / float(c - b) + 0.5f; 58 | assert(t >= 0.0f && t <= 1.0f); //N.b. might slightly miss owning to fp precision 59 | check(i,t); 60 | } 61 | 62 | return max_dis2; 63 | }; 64 | 65 | //Search for best path, where steps go from pairs of points to pairs of points (extend spline by one segment): 66 | std::unordered_map< glm::uvec2, uint32_t > distance; //distance == # of points to get to pair 67 | std::multimap< std::pair< uint32_t, uint32_t >, glm::uvec2 > to_expand; //to expand sorted by heuristic & distance 68 | 69 | auto queue = [&distance, &to_expand](glm::uvec2 at, uint32_t dis) { 70 | auto ret = distance.emplace(at, dis); 71 | if (ret.second || ret.first->second > dis) { 72 | ret.first->second = dis; 73 | uint32_t heuristic = dis; // + (pts.size() - 1 - at.y); //<-- NOTE: inadmissable heuristic 74 | to_expand.emplace(std::make_pair(heuristic, dis), at); 75 | } 76 | }; 77 | 78 | queue(glm::uvec2(0, 1), 2); 79 | 80 | uint32_t best_dis = -1U; 81 | glm::uvec2 best_end = glm::uvec2(-1U); 82 | 83 | constexpr uint32_t MaxStep = 80; 84 | 85 | while (!to_expand.empty()) { 86 | uint32_t dis = to_expand.begin()->first.second; 87 | glm::uvec2 at = to_expand.begin()->second; 88 | to_expand.erase(to_expand.begin()); 89 | { 90 | auto f = distance.find(at); 91 | assert(f != distance.end()); 92 | assert(f->second <= dis); 93 | if (f->second < dis) continue; 94 | } 95 | 96 | //NOTE: could relax condition on at.x if we had a checking function for line segments 97 | if (at.x + 2 == pts.size() && at.y + 1 == pts.size()) { 98 | if (dis < best_dis) { 99 | std::cout << "Reached end in " << dis << " steps." << std::endl; 100 | best_dis = dis; 101 | best_end = at; 102 | } 103 | } 104 | 105 | for (uint32_t s = 1; s < MaxStep; ++s) { 106 | if (at.y + s >= pts.size()) break; 107 | if (fit_dis2(at.x, at.y, at.y + s) <= tol2) { 108 | queue(glm::uvec2(at.y, at.y + s), dis + 1); 109 | } 110 | } 111 | } 112 | 113 | assert(best_end.x < best_end.y && best_end.y < pts.size()); 114 | std::vector< uint32_t > path; 115 | { //read back whole path (in reverse): 116 | path.emplace_back(best_end.y); 117 | path.emplace_back(best_end.x); 118 | 119 | uint32_t dis = best_dis; 120 | 121 | while (path.back() != 0) { 122 | uint32_t b = path[path.size()-1]; 123 | bool found = false; 124 | for (uint32_t s = 1; s < MaxStep; ++s) { 125 | if (s > b) break; 126 | uint32_t a = b - s; 127 | auto f = distance.find(glm::uvec2(a,b)); 128 | if (f == distance.end()) continue; 129 | if (f->second + 1 > dis) continue; 130 | assert(f->second + 1 == dis); 131 | //step back: 132 | path.emplace_back(a); 133 | dis -= 1; 134 | found = true; 135 | break; 136 | } 137 | assert(found); 138 | } 139 | std::reverse(path.begin(), path.end()); 140 | std::cout << "Read out path of length " << path.size() << "." << std::endl; 141 | } 142 | 143 | std::vector< glm::vec3 > new_pts; 144 | new_pts.reserve(path.size()); 145 | for (auto &i : path) { 146 | new_pts.emplace_back(pts[i]); 147 | } 148 | 149 | return new_pts; 150 | } 151 | 152 | int main(int argc, char **argv) { 153 | if (argc != 4) { 154 | std::cerr << "Usage:\n\t./simplify-yarns " << std::endl; 155 | return 1; 156 | } 157 | std::string in_yarns = argv[1]; 158 | float tolerance; 159 | bool tolerance_is_percent; 160 | std::string out_yarns = argv[3]; 161 | try { 162 | std::string tol = argv[2]; 163 | if (tol.size() > 0 && tol[tol.size()-1] == '%') { 164 | tolerance = std::stof(tol.substr(0,tol.size()-1)); 165 | tolerance_is_percent = true; 166 | } else { 167 | tolerance = std::stof(tol); 168 | tolerance_is_percent = false; 169 | } 170 | } catch (std::exception &e) { 171 | std::cerr << "Failed to parse tolerance '" << argv[2] << "'." << std::endl; 172 | return 1; 173 | } 174 | 175 | std::cout << "Will simply yarns in '" << in_yarns << "' by making a path that remains within " << tolerance << (tolerance_is_percent ? " percent" : " units") << " and write to '" << out_yarns << "'." << std::endl; 176 | 177 | sm::Yarns yarns = sm::Yarns::load(in_yarns); 178 | 179 | { 180 | uint32_t total_points = 0; 181 | uint32_t total_checkpoints = 0; 182 | for (auto const &yarn : yarns.yarns) { 183 | total_points += yarn.points.size(); 184 | total_checkpoints += yarn.checkpoints.size(); 185 | } 186 | std::cout << "Input has " << yarns.yarns.size() << " yarns with a total of " << total_points << " points and " << total_checkpoints << " checkpoints." << std::endl; 187 | if (total_checkpoints != 0) { 188 | std::cerr << "WARNING: checkpoint simplification code not yet written." << std::endl; 189 | } 190 | } 191 | 192 | for (auto &yarn : yarns.yarns) { 193 | std::cout << "Simplifying yarn " << (&yarn - &yarns.yarns[0]) << " (radius " << yarn.radius << ", " << yarn.points.size() << " points)..."; std::cout.flush(); 194 | std::vector< uint32_t > subset; 195 | float yarn_tol = (tolerance_is_percent ? yarn.radius * tolerance / 100.0f : tolerance); 196 | yarn.points = simplify(yarn.points, yarn_tol); 197 | yarn.sources.assign(yarn.points.size(), -1U); //NOTE: source info lost :-( 198 | } 199 | 200 | { 201 | uint32_t total_points = 0; 202 | uint32_t total_checkpoints = 0; 203 | for (auto const &yarn : yarns.yarns) { 204 | total_points += yarn.points.size(); 205 | total_checkpoints += yarn.checkpoints.size(); 206 | } 207 | std::cout << "Output has " << yarns.yarns.size() << " yarns with a total of " << total_points << " points and " << total_checkpoints << " checkpoints." << std::endl; 208 | } 209 | 210 | yarns.save(out_yarns); 211 | 212 | return 0; 213 | } 214 | -------------------------------------------------------------------------------- /utilities/smobj-to-yarns.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "sm.hpp" 3 | 4 | #include 5 | #include 6 | 7 | int main(int argc, char **argv) { 8 | 9 | if (argc != 4) { 10 | std::cerr << "Usage:\n\t./smobj-to-yarns " << std::endl; 11 | return 1; 12 | } 13 | 14 | std::string in_smobj = argv[1]; 15 | std::string in_library = argv[2]; 16 | std::string out_yarns = argv[3]; 17 | std::cout << "Will elaborate faces of smobj '" << in_smobj << "' using yarn paths from library '" << in_library << "' and write resulting yarns to '" << out_yarns << "'" << std::endl; 18 | 19 | sm::Mesh mesh = sm::Mesh::load(in_smobj); 20 | 21 | sm::Library library = sm::Library::load(in_library); 22 | 23 | 24 | sm::Yarns yarns; 25 | 26 | sm::mesh_and_library_to_yarns(mesh, library, &yarns); 27 | 28 | yarns.save(out_yarns); 29 | 30 | } 31 | 32 | -------------------------------------------------------------------------------- /utilities/test-code.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "sm.hpp" 4 | #include "hinters.hpp" 5 | 6 | int main(int argc, char *argv[]){ 7 | if(argc < 4){ 8 | std::cout << "Usage: ./test-code input.code input.sf input.smobj" << std::endl; 9 | return 0; 10 | } 11 | std::cout << "Loading code from " << argv[1] << std::endl; 12 | std::cout << "Loading library from " << argv[2] << std::endl; 13 | std::cout << "Loading mesh from " << argv[3] << std::endl; 14 | sm::Code code; 15 | code = sm::Code::load(argv[1]); 16 | sm::Library lib = sm::Library::load(argv[2]); 17 | sm::Mesh mesh = sm::Mesh::load(argv[3]); 18 | 19 | // ----- yarns ----- 20 | { 21 | sm::Yarns yarns; 22 | std::map fe_to_y; 23 | sm::mesh_and_library_to_yarns(mesh, lib, &yarns, &fe_to_y); 24 | 25 | } 26 | 27 | std::cout << "------------- loaded files --------------- " << std::endl; 28 | if(!sm::compute_code_graph(code)){ 29 | return 0; 30 | } 31 | std::cout << "------------- code graph computed --------------- " << std::endl; 32 | 33 | 34 | 35 | std::vector offenders; 36 | //if(sm::verify(mesh, lib, code, &offenders) && sm::compute_total_order(mesh, code)){ 37 | if( sm::verify(mesh, lib, code, &offenders, true)){ 38 | std::string knitout = sm::knitout(mesh, lib, code); 39 | std::ofstream kw("out.knitout"); 40 | kw << knitout; 41 | kw.close(); 42 | 43 | std::cout << knitout << std::endl; 44 | std::cout << "Successfully generated knitout instructions. Total order: " << std::endl; 45 | for(auto const &fi : mesh.total_order){ 46 | std::cout << fi.first << "/" << fi.second << std::endl; 47 | } 48 | } 49 | { 50 | if(!sm::compute_total_order(mesh, code, lib)){ 51 | std::cerr << "\tTotal order doesn't exist. " << std::endl; 52 | } 53 | if(!sm::verify(mesh, lib, code, &offenders, true)){ 54 | std::cerr << "\tCould not verify mesh. " << std::endl; 55 | std::cerr << "\tOffenders: " << offenders.size() << std::endl; 56 | } 57 | } 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /utilities/text-to-smobj.cpp: -------------------------------------------------------------------------------- 1 | #include "sm.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | int main(int argc, char **argv) { 11 | if (argc != 4) { 12 | std::cerr << 13 | "Usage:\n\t./text-to-smobj \n" 14 | " Where in.txt looks something like this:\n" 15 | " face-name e1 e2 e3 e4\n" 16 | " face-name e2 e3 . .\n" 17 | " ...\n" 18 | " That is, each line has a face name followed by variables indicating\n" 19 | " where that face's edge connect. '.' is a special variable meaning\n" 20 | " 'does not connect'" 21 | << std::endl; 22 | return 1; 23 | } 24 | std::string in_text = argv[1]; 25 | std::string in_library = argv[2]; 26 | std::string out_smobj = argv[3]; 27 | std::cout << "Will use connections in '" << in_text << "' and faces in library '" << in_library << "' to create smobj '" << out_smobj << "'" << std::endl; 28 | 29 | //------------------------- 30 | 31 | sm::Library library = sm::Library::load(in_library); 32 | 33 | std::unordered_map< std::string, sm::Library::Face const * > name_to_face; 34 | for (auto const &f : library.faces) { 35 | auto ret = name_to_face.insert(std::make_pair(f.name, &f)); 36 | assert(ret.second && "No duplicate face names."); 37 | } 38 | 39 | //library templates, to be used in layout: 40 | std::vector< std::vector< glm::vec2 > > templates; 41 | 42 | sm::Mesh mesh; 43 | 44 | 45 | //---------------------------- 46 | 47 | { //parse text file: 48 | std::unordered_map< std::string, uint32_t > name_to_L; 49 | auto get_L = [&mesh,&name_to_L,&templates](sm::Library::Face const &face) -> uint32_t { 50 | auto f = name_to_L.find(face.name); 51 | if (f != name_to_L.end()) return f->second; 52 | name_to_L.insert(std::make_pair(face.name, mesh.library.size())); 53 | mesh.library.emplace_back(face.key()); 54 | templates.emplace_back(); 55 | for (auto const &e : face.edges) { 56 | templates.back().emplace_back(e.vertex); 57 | } 58 | return mesh.library.size()-1; 59 | }; 60 | 61 | std::unordered_map< std::string, uint32_t > open_edges; 62 | 63 | std::ifstream text(in_text); 64 | std::string line; 65 | while (std::getline(text, line)) { 66 | { //trim comments: 67 | auto idx = line.find('#'); 68 | if (idx != std::string::npos) line = line.substr(0,idx); 69 | } 70 | std::vector< std::string > toks; 71 | { 72 | std::string tok; 73 | std::istringstream str(line); 74 | while (str >> tok) toks.emplace_back(tok); 75 | } 76 | if (toks.empty()) continue; 77 | std::string face_name = toks[0]; 78 | toks.erase(toks.begin()); 79 | 80 | auto f = name_to_face.find(face_name); 81 | if (f == name_to_face.end()) { 82 | std::cerr << "ERROR: face '" << face_name << "' does not appear in library." << std::endl; 83 | return 1; 84 | } 85 | sm::Library::Face const &face = *f->second; 86 | 87 | if (toks.size() != face.edges.size()) { 88 | std::cerr << "ERROR: face '" << face.name << "' has " << face.edges.size() << " edges, but only lists " << toks.size() << " attachments." << std::endl; 89 | return 1; 90 | } 91 | 92 | mesh.faces.emplace_back(); 93 | sm::Mesh::Face &m_face = mesh.faces.back(); 94 | m_face.type = get_L(face); 95 | 96 | for (uint32_t i = 0; i < face.edges.size(); ++i) { 97 | m_face.emplace_back(mesh.vertices.size()); 98 | mesh.vertices.emplace_back(std::numeric_limits< float >::quiet_NaN()); 99 | } 100 | 101 | for (uint32_t i = 0; i < face.edges.size(); ++i) { 102 | auto c = open_edges.find(toks[i]); 103 | if (c != open_edges.end()) { 104 | assert(c->second < mesh.connections.size()); 105 | sm::Mesh::Connection &con = mesh.connections[c->second]; 106 | assert(con.b.face == -1U); 107 | assert(con.b.edge == -1U); 108 | con.b.face = mesh.faces.size() - 1; 109 | con.b.edge = i; 110 | open_edges.erase(c); 111 | } else if (toks[i] != ".") { 112 | mesh.connections.emplace_back(); 113 | sm::Mesh::Connection &con = mesh.connections.back(); 114 | con.a.face = mesh.faces.size() - 1; 115 | con.a.edge = i; 116 | con.flip = true; //by default, flat connections 117 | auto ret = open_edges.insert(std::make_pair(toks[i], mesh.connections.size()-1)); 118 | assert(ret.second); 119 | } 120 | } 121 | 122 | } 123 | 124 | if (!open_edges.empty()) { 125 | std::cerr << "WARNING: the following open edges are not connected:\n"; 126 | for (auto const &oe : open_edges) { 127 | std::cerr << " " << oe.first << "\n"; 128 | } 129 | std::cerr.flush(); 130 | } 131 | uint32_t removed = 0; 132 | for (uint32_t i = 0; i < mesh.connections.size(); /* later */) { 133 | if (mesh.connections[i].b.face == -1U) { 134 | std::swap(mesh.connections[i], mesh.connections.back()); 135 | mesh.connections.pop_back(); 136 | ++removed; 137 | } else { 138 | ++i; 139 | } 140 | } 141 | if (removed != 0) { 142 | std::cout << "WARNING: trimmed " << removed << " incomplete connections." << std::endl; 143 | } 144 | assert(removed == open_edges.size()); 145 | } 146 | 147 | std::cout << "Created mesh with " << mesh.vertices.size() << " vertices, " << mesh.faces.size() << " faces, and " << mesh.connections.size() << " connections." << std::endl; 148 | 149 | //---------------------------- 150 | 151 | //center templates: 152 | for (auto &t : templates) { 153 | glm::vec2 avg = glm::vec2(0.0f); 154 | for (auto const &p : t) { 155 | avg += p; 156 | } 157 | avg /= t.size(); 158 | for (auto &p : t) { 159 | p -= avg; 160 | } 161 | } 162 | 163 | 164 | { //basic (2d) position/orientation relaxation for positions: 165 | assert(templates.size() == mesh.library.size()); 166 | 167 | std::vector< glm::vec2 > pts; 168 | struct Face : std::vector< uint32_t > { 169 | uint32_t type = -1U; 170 | float angle = 0.0f; 171 | glm::vec2 center = glm::vec2(0.0f); 172 | }; 173 | std::vector< Face > faces; 174 | 175 | { //set up pts/faces from mesh vertices and connections: 176 | std::vector< uint32_t > verts_to_ids; 177 | verts_to_ids.reserve(mesh.vertices.size()); 178 | for (uint32_t i = 0; i < mesh.vertices.size(); ++i) { 179 | verts_to_ids.emplace_back(i); 180 | } 181 | 182 | auto unify = [&verts_to_ids](uint32_t i, uint32_t j){ 183 | assert(i < verts_to_ids.size()); 184 | assert(j < verts_to_ids.size()); 185 | uint32_t a = i; 186 | while (verts_to_ids[a] != a) a = verts_to_ids[a]; 187 | uint32_t b = j; 188 | while (verts_to_ids[b] != b) b = verts_to_ids[b]; 189 | if (a < b) { 190 | verts_to_ids[b] = a; 191 | } else if (b < a) { 192 | verts_to_ids[a] = b; 193 | } 194 | //NOTE: this is not efficient; efficient code would clean up the other pointers during unification. 195 | }; 196 | 197 | for (auto const &c : mesh.connections) { 198 | assert(c.a.face < mesh.faces.size()); 199 | assert(c.a.edge < mesh.faces[c.a.face].size()); 200 | uint32_t a0 = mesh.faces[c.a.face][c.a.edge]; 201 | uint32_t a1 = mesh.faces[c.a.face][(c.a.edge + 1)%mesh.faces[c.a.face].size()]; 202 | assert(c.b.face < mesh.faces.size()); 203 | assert(c.b.edge < mesh.faces[c.b.face].size()); 204 | uint32_t b0 = mesh.faces[c.b.face][c.b.edge]; 205 | uint32_t b1 = mesh.faces[c.b.face][(c.b.edge + 1)%mesh.faces[c.b.face].size()]; 206 | if (c.flip) { 207 | unify(a0, b1); unify(a1, b0); 208 | } else { 209 | unify(a0, b0); unify(a1, b1); 210 | } 211 | } 212 | 213 | std::vector< uint32_t > ids_to_pts(verts_to_ids.size(), -1U); 214 | std::vector< uint32_t > verts_to_pts; 215 | verts_to_pts.reserve(mesh.vertices.size()); 216 | for (uint32_t i = 0; i < mesh.vertices.size(); ++i) { 217 | uint32_t id = i; 218 | while (verts_to_ids[id] != id) id = verts_to_ids[id]; 219 | assert(id < ids_to_pts.size()); 220 | if (ids_to_pts[id] == -1U) { 221 | ids_to_pts[id] = pts.size(); 222 | pts.emplace_back(glm::vec2(0.0f)); 223 | } 224 | verts_to_pts.emplace_back(ids_to_pts[id]); 225 | } 226 | 227 | faces.reserve(mesh.faces.size()); 228 | for (auto const &f : mesh.faces) { 229 | faces.emplace_back(); 230 | faces.back().type = f.type; 231 | for (auto const &v : f) { 232 | faces.back().emplace_back(verts_to_pts[v]); 233 | } 234 | } 235 | } //end of setup 236 | 237 | //brain-dead iterative solve: 238 | for (uint32_t pass = 0; pass < 2; ++pass) { 239 | std::vector< glm::vec2 > old_pts = pts; 240 | bool converged = false; 241 | 242 | for (uint32_t iter = 0; iter < 100000; ++iter) { 243 | 244 | //update point positions: 245 | std::vector< glm::vec3 > votes(pts.size(), glm::vec3(0.0f)); 246 | for (auto &f : faces) { 247 | //regularization: 248 | if (pass == 0) { 249 | f.angle = 0.0f; //<-- HACK: ignore rotation during first pass 250 | } else { 251 | f.angle *= 0.999f; 252 | } 253 | 254 | glm::vec2 right = glm::vec2(std::cos(f.angle), std::sin(f.angle)); 255 | glm::vec2 up = glm::vec2(-right.y, right.x); 256 | std::vector< glm::vec2 > const &t = templates[f.type]; 257 | assert(t.size() == f.size()); 258 | for (uint32_t i = 0; i < t.size(); ++i) { 259 | votes[f[i]] += glm::vec3(right * t[i].x + up * t[i].y + f.center, 1.0f); 260 | } 261 | } 262 | 263 | std::swap(old_pts, pts); //store old point positions 264 | 265 | glm::vec2 pts_center = glm::vec2(0.0f); 266 | for (uint32_t i = 0; i < pts.size(); ++i) { 267 | pts[i] = glm::vec2(votes[i]) / votes[i].z; 268 | pts_center += pts[i]; 269 | } 270 | pts_center /= pts.size(); 271 | for (auto &p : pts) { 272 | p -= pts_center; 273 | } 274 | double absolute_movement = 0.0; 275 | for (uint32_t i = 0; i < pts.size(); ++i) { 276 | absolute_movement += std::abs(pts[i].x - old_pts[i].x); 277 | absolute_movement += std::abs(pts[i].y - old_pts[i].y); 278 | } 279 | if (absolute_movement < 1e-4) { 280 | std::cout << "Pass " << (pass+1) << " converged at iteration " << iter << "." << std::endl; 281 | converged = true; 282 | break; 283 | } 284 | 285 | for (auto &f : faces) { 286 | //update face centers: 287 | glm::vec2 avg = glm::vec2(0.0f); 288 | for (auto i : f) { 289 | avg += pts[i]; 290 | } 291 | f.center = avg /= f.size(); 292 | 293 | //determine angles: 294 | //Port of (javascript) code I used in a lunch talk once: 295 | float coefCos = 0.0; 296 | float coefSin = 0.0; 297 | float coefSinCos = 0.0; 298 | float coefCos2 = 0.0; 299 | float coefSin2 = 0.0; 300 | auto addDeriv = [&](float c, float s, float o) { 301 | //add derivative of (c * cos(t) + s * sin(t) + o * 1)^2 302 | //== 2 * (c * cos(t) + s * sin(t) + o * 1) * (c *-sin(t) + s * cos(t)) 303 | coefCos += o * s; 304 | coefSin += o * -c; 305 | coefCos2 += c * s; 306 | coefSin2 += s * -c; 307 | coefSinCos += (c * -c + s * s); 308 | }; 309 | std::vector< glm::vec2 > const &t = templates[f.type]; 310 | for (uint32_t i = 0; i < f.size(); ++i) { 311 | // (offsets[i].x * cos(t) + offsets[i].y *-sin(t) - [real offset].x)^2 312 | //+(offsets[i].x * sin(t) + offsets[i].y * cos(t) - [real offset].y)^2 313 | addDeriv(t[i].x, -t[i].y, -pts[f[i]].x + f.center.x); 314 | addDeriv(t[i].y, t[i].x, -pts[f[i]].y + f.center.y); 315 | } 316 | //end up with *just* coefCos, coefSin. 317 | if (std::abs(coefSinCos) > 1e-6 || std::abs(coefCos2) > 1e-6 || std::abs(coefSin2) > 1e-6) { 318 | std::cout << "Unexpected coefs: " << coefCos << " " << coefSin << " " << coefSinCos << " " << coefCos2 << " " << coefSin2 << std::endl; 319 | } 320 | if (coefCos == 0.0 && coefSin == 0.0) { 321 | f.angle = 0.0f; 322 | } else { 323 | //Want: 324 | //coefCos * cos + coefSin * sin = 0.0 [deriv == 0] 325 | //also: 326 | //coefSin * cos + -coefCos * sin > 0 [second deriv > 0] 327 | 328 | //let len = Math.sqrt(coefCos * coefCos + coefSin * coefSin); 329 | //f.right.x = coefSin / len; 330 | //f.right.y =-coefCos / len; 331 | f.angle = std::atan2(-coefCos, coefSin); 332 | } 333 | } 334 | } //for (iteration) 335 | if (!converged) { 336 | std::cout << "Pass " << (pass+1) << " did not converge; continuing anyway." << std::endl; 337 | } 338 | } //for (pass) 339 | 340 | //copy results back to mesh: 341 | assert(faces.size() == mesh.faces.size()); 342 | for (uint32_t f = 0; f < faces.size(); ++f) { 343 | assert(mesh.faces[f].size() == faces[f].size()); 344 | for (uint32_t i = 0; i < faces[f].size(); ++i) { 345 | mesh.vertices[mesh.faces[f][i]] = glm::vec3(pts[faces[f][i]], 0.0f); 346 | } 347 | } 348 | 349 | } 350 | 351 | std::cout << "Writing '" << out_smobj << "'." << std::endl; 352 | mesh.save(out_smobj); 353 | 354 | return 0; 355 | } 356 | -------------------------------------------------------------------------------- /utilities/yarn-units.cpp: -------------------------------------------------------------------------------- 1 | #include "sm.hpp" 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | int main(int argc, char **argv) { 12 | bool usage = false; 13 | std::string in_yarns = ""; 14 | std::string out_yarns = ""; 15 | std::map< std::string, float > set; 16 | bool sum = false; 17 | bool print = false; 18 | 19 | for (int argi = 1; argi < argc; ++argi) { 20 | std::string arg = argv[argi]; 21 | if (arg == "--help") { 22 | usage = true; 23 | } else if (arg == "--set") { 24 | if (argi + 2 < argc) { 25 | argi += 1; 26 | std::string name = argv[argi]; 27 | argi += 1; 28 | float length = std::stoi(argv[argi]); 29 | if (set.count(name)) { 30 | std::cerr << "ERROR: attempting to '--set " << name << "' twice." << std::endl; 31 | usage = true; 32 | } 33 | set[name] = length; 34 | } else { 35 | std::cerr << "ERROR: '--set' should be followed by a unit name and a length" << std::endl; 36 | usage = true; 37 | } 38 | } else if (arg == "--sum") { 39 | sum = true; 40 | } else if (arg == "--print") { 41 | print = true; 42 | } else if (arg == "--write") { 43 | if (argi + 1 < argc) { 44 | if (out_yarns != "") { 45 | std::cerr << "ERROR: multiple output files given." << std::endl; 46 | usage = true; 47 | } 48 | argi += 1; 49 | out_yarns = argv[argi]; 50 | } else { 51 | std::cerr << "Expecting output filename after '--write'" << std::endl; 52 | usage = true; 53 | } 54 | } else if (arg == "--") { 55 | if (argi + 2 != argc) { 56 | std::cerr << "ERROR: expecting '--' to be followed by exactly the input filename and nothing more." << std::endl; 57 | usage = true; 58 | } else { 59 | if (in_yarns != "") { 60 | std::cerr << "ERROR: multiple input files ('" << in_yarns << "', '" << argv[argi+1] << "') given." << std::endl; 61 | usage = true; 62 | } 63 | in_yarns = argv[argi+1]; 64 | } 65 | break; //no argument parsing past '-- input.yarns' 66 | } else { 67 | if (in_yarns != "") { 68 | std::cerr << "ERROR: multiple input files ('" << in_yarns << "', '" << arg << "') given." << std::endl; 69 | usage = true; 70 | } 71 | in_yarns = arg; 72 | } 73 | } 74 | if (in_yarns == "") { 75 | std::cerr << "ERROR: no input file specified." << std::endl; 76 | usage = true; 77 | } 78 | if (!(print || out_yarns != "" || usage)) { 79 | std::cerr << "ERROR: utility asked to produce no output." << std::endl; 80 | usage = true; 81 | } 82 | if (usage) { 83 | std::cerr << "Usage:\n\t./yarn-units [--set unit length] [--set unit length] [--sum] [--print] [--write out.yarns] [--] \n" 84 | << " --set unit length set the length factor for 'unit' to length\n" 85 | << " --sum sum all lengths so file only contains checkpoints in terms of the '1' unit\n" 86 | << " --print print out all units, their default values, and the total of that unit in the file\n" 87 | << " --write out.yarns write output file\n" 88 | << " --help print this text\n" 89 | << std::endl; 90 | return 1; 91 | } 92 | 93 | std::cerr << "Loading '" << in_yarns << "' ..."; std::cerr.flush(); 94 | sm::Yarns yarns = sm::Yarns::load(in_yarns); 95 | std::cerr << " done." << std::endl; 96 | 97 | //---------------------------------------------- 98 | for (auto const &[name, length] : set) { 99 | bool found = false; 100 | for (auto &unit : yarns.units) { 101 | if (unit.name == name) { 102 | std::cerr << "set '" << name << "' to " << length << "\n"; 103 | if (unit.name == "1" && length != 1.0) { 104 | std::cerr << "WARNING: changing the length of the '1' unit to anything other than 1.0 is not allowed or expected by the specification (but doing it anyway because you asked)." << std::endl; 105 | } 106 | unit.length = length; 107 | found = true; 108 | } 109 | } 110 | if (!found) { 111 | std::cerr << "WARNING: cannot set '" << name << "' because it doesn't appear in the file." << std::endl; 112 | } 113 | } 114 | 115 | //---------------------------------------------- 116 | if (sum) { 117 | std::cerr << "Summing all checkpoints using current unit values..."; std::cerr.flush(); 118 | for (auto &yarn : yarns.yarns) { 119 | std::map< uint32_t, float > new_lengths; 120 | for (auto const &cp : yarn.checkpoints) { 121 | new_lengths.emplace(cp.point, 0.0f).first->second += cp.length * yarns.units.at(cp.unit).length; 122 | } 123 | yarn.checkpoints.clear(); 124 | yarn.checkpoints.reserve(new_lengths.size()); 125 | for (auto const &[point, length] : new_lengths) { 126 | yarn.checkpoints.emplace_back(); 127 | yarn.checkpoints.back().point = point; 128 | yarn.checkpoints.back().length = length; 129 | yarn.checkpoints.back().unit = 0; 130 | } 131 | } 132 | yarns.units.clear(); 133 | yarns.units.emplace_back(); 134 | yarns.units.back().name = "1"; 135 | yarns.units.back().length = 1.0f; 136 | std::cerr << " done." << std::endl; 137 | } 138 | 139 | //---------------------------------------------- 140 | if (print) { 141 | std::vector< std::vector< float > > amounts(yarns.units.size()); 142 | for (auto const &yarn : yarns.yarns) { 143 | for (auto const &cp : yarn.checkpoints) { 144 | assert(cp.unit < amounts.size()); 145 | amounts[cp.unit].emplace_back(cp.length); 146 | } 147 | } 148 | std::vector< std::vector< std::string > > table; 149 | std::vector< float > totals; 150 | for (uint32_t i = 0; i < yarns.units.size(); ++i) { 151 | 152 | //could be a lot of small values, so do a careful sum by adding the two smallest lengths first: 153 | std::make_heap(amounts[i].begin(), amounts[i].end(), std::greater< float >()); 154 | while (amounts[i].size() > 1) { 155 | std::pop_heap(amounts[i].begin(), amounts[i].end(), std::greater< float >()); 156 | std::pop_heap(amounts[i].begin(), amounts[i].end()-1, std::greater< float >()); 157 | *(amounts[i].end()-2) += *(amounts[i].end()-1); 158 | amounts[i].pop_back(); 159 | } 160 | assert(amounts.size() <= 1); 161 | 162 | float total = (amounts[i].empty() ? 0.0f : amounts[i][0]); 163 | 164 | totals.emplace_back(total * yarns.units[i].length); 165 | table.emplace_back(); 166 | table.back().emplace_back(yarns.units[i].name); 167 | table.back().emplace_back(": "); 168 | table.back().emplace_back(std::to_string(total)); 169 | table.back().emplace_back(" * "); 170 | table.back().emplace_back(std::to_string(yarns.units[i].length)); 171 | table.back().emplace_back(" = "); 172 | table.back().emplace_back(std::to_string(total * yarns.units[i].length)); 173 | //std::cout << yarns.units[i].name << ": " << total << " (* " << yarns.units[i].length << ")" << "\n"; 174 | } 175 | { //overall total: 176 | std::sort(totals.begin(), totals.end()); 177 | float total = 0.0f; 178 | for (float a : totals) { 179 | total += a; 180 | } 181 | table.emplace_back(); 182 | table.back().emplace_back("total"); 183 | table.back().emplace_back(""); 184 | table.back().emplace_back(""); 185 | table.back().emplace_back(""); 186 | table.back().emplace_back(""); 187 | table.back().emplace_back(""); 188 | table.back().emplace_back(std::to_string(total)); 189 | } 190 | 191 | for (uint32_t col = 0; col < table[0].size(); ++col) { 192 | size_t max = 0; 193 | for (uint32_t row = 0; row < table.size(); ++row) { 194 | max = std::max(max, table[row].at(col).size()); 195 | } 196 | for (uint32_t row = 0; row < table.size(); ++row) { 197 | auto &val = table[row][col]; 198 | if (col == 0) { 199 | while (val.size() < max) val = ' ' + val; 200 | } else { 201 | while (val.size() < max) val = ' ' + val; 202 | } 203 | } 204 | } 205 | for (auto const &row : table) { 206 | for (auto const &val : row) { 207 | std::cout << val; 208 | } 209 | std::cout << '\n'; 210 | } 211 | std::cout.flush(); 212 | } 213 | 214 | if (out_yarns != "") { 215 | std::cerr << "INFO: writing '" << out_yarns << "'..."; std::cerr.flush(); 216 | yarns.save(out_yarns); 217 | std::cerr << " done." << std::endl; 218 | } 219 | 220 | return 0; 221 | } 222 | -------------------------------------------------------------------------------- /utilities/yarns-to-bccx.cpp: -------------------------------------------------------------------------------- 1 | #include "sm.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | 15 | //convert a quadratic bezier through midpoints (i.e., a quadratic b-spline, if I recall correctly) to a Cubic Catmull-Rom Spline, preserving marked points, and keeping the curves within 'tol' of each-other [at all test points] 16 | void midpoint_bezier_to_catmull_rom(std::vector< glm::vec3 > const &yarn, std::vector< uint32_t > yarn_marked, std::vector< glm::vec3 > *rom, std::vector< uint32_t > *rom_marked, const float tol); 17 | 18 | int main(int argc, char **argv) { 19 | if (argc != 3) { 20 | std::cerr << "Usage:\n\t./yarns-to-bccx " << std::endl; 21 | return 1; 22 | } 23 | std::string in_yarns = argv[1]; 24 | std::string out_bccx = argv[2]; 25 | 26 | std::cout << "Will convert yarns in '" << in_yarns << "' to a bccx-formatted file '" << out_bccx << "'." << std::endl; 27 | 28 | sm::Yarns yarns = sm::Yarns::load(in_yarns); 29 | 30 | { 31 | uint32_t total_points = 0; 32 | uint32_t total_checkpoints = 0; 33 | for (auto const &yarn : yarns.yarns) { 34 | total_points += yarn.points.size(); 35 | total_checkpoints += yarn.checkpoints.size(); 36 | } 37 | std::cout << "Input has " << yarns.yarns.size() << " yarns with a total of " << total_points << " points and " << total_checkpoints << " checkpoints." << std::endl; 38 | if (total_checkpoints != 0) { 39 | std::cerr << "WARNING: checkpoint conversion code not yet written." << std::endl; 40 | } 41 | } 42 | 43 | //convert yarns-style splines to bccx-style splines: 44 | std::vector< std::vector< glm::vec3 > > rom_points; 45 | std::vector< std::vector< uint32_t > > rom_checkpoints; 46 | rom_points.reserve(yarns.yarns.size()); 47 | rom_checkpoints.reserve(yarns.yarns.size()); 48 | for (auto const &yarn : yarns.yarns) { 49 | //make a list of checkpoint locations to preserve in the conversion: 50 | std::vector< uint32_t > checkpoints; 51 | checkpoints.reserve(yarn.checkpoints.size()); 52 | for (auto const &cp : yarn.checkpoints) { 53 | if (checkpoints.empty() || cp.point != checkpoints.back()) { 54 | checkpoints.emplace_back(cp.point); 55 | } 56 | } 57 | //do the conversion: 58 | std::vector< glm::vec3 > rom; 59 | std::vector< uint32_t > rom_cp; 60 | midpoint_bezier_to_catmull_rom(yarn.points, checkpoints, &rom, &rom_cp, 0.1 * yarn.radius); 61 | assert(rom_cp.size() == checkpoints.size()); 62 | for (auto cp : rom_cp) { 63 | assert(cp < rom.size()); 64 | } 65 | 66 | rom_points.emplace_back(std::move(rom)); 67 | rom_checkpoints.emplace_back(std::move(rom_cp)); 68 | 69 | } 70 | 71 | 72 | std::ofstream out(out_bccx, std::ios::binary); 73 | 74 | //BCC(x) format is based on 'sim.h' and 'bcc.cpp' from YarnBallSim 75 | // as well as http://www.cemyuksel.com/cyCodeBase/soln/using_bcc_files.html 76 | struct BCCHeader { 77 | char magic[3] = {'B', 'C', 'C'}; 78 | uint8_t bytes = 0x44; //4-byte integers, 4-byte floating point 79 | char format[2] = {'C', '0'}; //uniform catmull-rom splines 80 | uint8_t dimensions = 3; //3d points 81 | uint8_t up_direction = 2; //1 is y-up, 2 is z-up 82 | uint64_t num_yarns; 83 | uint64_t num_nodes; 84 | char info[40]; 85 | } header; 86 | static_assert(sizeof(BCCHeader) == 64, "BCC header should be 64 bytes."); 87 | 88 | header.num_yarns = yarns.yarns.size(); 89 | header.num_nodes = 0; 90 | for (auto const &points : rom_points) { 91 | header.num_nodes += points.size(); 92 | } 93 | { //copy source filename into info: 94 | memset(header.info, '\0', sizeof(header.info)); 95 | std::string info = "from '" + in_yarns + "'"; 96 | if (info.size() > 40) info = info.substr(0, 40); 97 | memcpy(header.info, info.data(), info.size()); 98 | } 99 | out.write(reinterpret_cast< const char * >(&header), sizeof(header)); 100 | 101 | //Actually, we fixed that: 102 | //std::cerr << "WARNING: copying control points directly from yarns to bccx file -- this is technically incorrect in that yarns uses quadratic bezier curves between midpoints of yarns polylines, while bccx files use uniform cubic catmull-rom splines through yarn points." << std::endl; 103 | for (auto &yarn : yarns.yarns) { 104 | uint32_t index = &yarn - &yarns.yarns[0]; 105 | int32_t count = rom_points[index].size(); 106 | //NOTE: if count is negative, yarn is a closed loop; yarns format doesn't store closed loops 107 | //though, if yarns ever were used to store closed loops, it would be by having the first and last point in the yarn occupy exactly the same position: 108 | if (!yarn.points.empty() && yarn.points[0] == yarn.points.back()) { 109 | count = -count; 110 | } 111 | out.write(reinterpret_cast< const char * >(&count), sizeof(count)); 112 | static_assert(sizeof(rom_points[index][0]) == 12, "yarn points are 3-vectors of floating point values"); 113 | out.write(reinterpret_cast< const char * >(rom_points[index].data()), rom_points[index].size() * sizeof(rom_points[index][0])); 114 | } 115 | 116 | { //bccx stuff: 117 | //yarn radius: 118 | float radius = 0.1f; 119 | if (!yarns.yarns.empty()) { 120 | radius = yarns.yarns[0].radius; 121 | for (auto const &yarn : yarns.yarns) { 122 | if (yarn.radius != radius) { 123 | std::cerr << "WARNING: bccx supports only a single radius, but yarns[0] has radius " << radius << " and yarns[" << (&yarn - &yarns.yarns[0]) << "] has radius " << yarn.radius << ". (Using yarns[0] radius.)" << std::endl; 124 | } 125 | } 126 | } 127 | out.write(reinterpret_cast< const char * >(&radius), sizeof(radius)); 128 | //yarn point velocities: 129 | for (auto &yarn : yarns.yarns) { 130 | uint32_t index = &yarn - &yarns.yarns[0]; 131 | for ([[maybe_unused]] auto const &point : rom_points[index]) { 132 | glm::vec3 velocity = glm::vec3(0.0f, 0.0f, 0.0f); 133 | out.write(reinterpret_cast< const char * >(&velocity), sizeof(velocity)); 134 | } 135 | } 136 | //yarn point rest lengths: 137 | // (YarnBallSim's bcc.cpp initializes these to distance-to-next-control-point, so that's what I will use for now; could use checkpoints for this in the future.) 138 | for (auto &yarn : yarns.yarns) { 139 | uint32_t index = &yarn - &yarns.yarns[0]; 140 | auto &rp = rom_points[index]; 141 | //auto &cp = rom_checkpoints[index]; //<-- eventually, for checkpoints 142 | if (yarn.checkpoints.size()) { 143 | std::cerr << "WARNING: ignoring checkpoints in yarn[" << (&yarn - &yarns.yarns[0]) << "] -- reading lengths from checkpoints is not yet supported by this conversion code." << std::endl; 144 | } 145 | for (size_t i = 0; i < rp.size(); ++i) { 146 | float l = glm::length(rp[i] - rp[(i + 1) % rp.size()]); 147 | out.write(reinterpret_cast< const char * >(&l), sizeof(l)); 148 | } 149 | } 150 | } 151 | 152 | return 0; 153 | } 154 | 155 | 156 | //based on 'simplify()' function from simplify-yarns.cpp 157 | void midpoint_bezier_to_catmull_rom(std::vector< glm::vec3 > const &yarn, std::vector< uint32_t > yarn_marked, std::vector< glm::vec3 > *rom_, std::vector< uint32_t > *rom_marked_, const float tol) { 158 | assert(rom_); 159 | auto &rom = *rom_; 160 | assert(rom_marked_); 161 | auto &rom_marked = *rom_marked_; 162 | 163 | rom.clear(); 164 | rom_marked.clear(); 165 | 166 | if (yarn.size() == 0) { 167 | return; //already done! 168 | } else if (yarn.size() <= 2) { 169 | //too simple to approximate, just make a straight line: 170 | rom.emplace_back(yarn[0]); 171 | rom.insert(rom.end(), yarn.begin(), yarn.end()); 172 | rom.emplace_back(yarn.back()); 173 | 174 | rom_marked = yarn_marked; 175 | for (auto &m : rom_marked) { 176 | m += 1; 177 | } 178 | return; 179 | } 180 | 181 | const float tol2 = tol*tol; 182 | 183 | //overall idea: 184 | // (1) establish list of "test points" that are on the yarn and have associated parameter values 185 | // (2) search through space of possible catmull-rom splines by looking for best spline 186 | // - location in search is given by last three control points; 187 | // - action in search is picking one new control point; 188 | // - cost is number of control points picked. 189 | // (could use a heuristic here if something admissible existed...) 190 | 191 | std::vector< glm::vec3 > pts; 192 | std::vector< uint32_t > pts_marked; 193 | { //dice spline into pts: 194 | 195 | float max_step = 10.0f * tol; 196 | 197 | auto line_to = [&pts, &max_step](glm::vec3 const &to) { 198 | glm::vec3 from = pts.back(); 199 | //NOTE: variable sampling rate is going to do weird things with catmull-rom spline parameter speed (or, hmm, is going to favor nice uniform parameter speed which is maybe fine) 200 | float length = glm::length(to - from); 201 | uint32_t steps = std::max(1, int32_t(std::ceil(length / max_step))); 202 | for (uint32_t i = 1; i < steps; ++i) { 203 | pts.emplace_back(glm::mix(from, to, float(i) / float(steps))); 204 | } 205 | pts.emplace_back(to); 206 | }; 207 | 208 | auto curve_to = [&pts, &max_step](glm::vec3 const &m, glm::vec3 const &e) { 209 | glm::vec3 s = pts.back(); 210 | 211 | //NOTE: using a length approximation *certainly* will mess with catmull-rom spline speed: 212 | float approx_length = glm::length(m - s) + glm::length(e - m); 213 | uint32_t steps = std::max(1, int32_t(std::ceil(approx_length / max_step))); 214 | 215 | for (uint32_t i = 1; i < steps; ++i) { 216 | float t = float(i) / float(steps); 217 | pts.emplace_back(glm::mix( glm::mix(s,m,t), glm::mix(m,e,t), t)); 218 | } 219 | pts.emplace_back(e); 220 | }; 221 | 222 | 223 | std::vector< uint32_t >::iterator next_marked = yarn_marked.begin(); 224 | 225 | //first part (is a straight line): 226 | if (next_marked != yarn_marked.end() && *next_marked == 0) { 227 | pts_marked.emplace_back(0); 228 | ++next_marked; 229 | } 230 | pts.emplace_back(yarn[0]); 231 | line_to(glm::mix(yarn[0], yarn[1], 0.5f)); 232 | 233 | //next part (is quadratic segments): 234 | for (uint32_t i = 1; i + 1 < yarn.size(); ++i) { 235 | glm::vec3 s = pts.back(); 236 | glm::vec3 m = yarn[i]; 237 | glm::vec3 e = glm::mix(yarn[i], yarn[i+1], 0.5f); 238 | 239 | glm::vec3 sm = glm::mix(s,m,0.5f); 240 | glm::vec3 me = glm::mix(m,e,0.5f); 241 | glm::vec3 sme = glm::mix(sm,me,0.5f); 242 | 243 | //first half of curve: 244 | curve_to(sm, sme); 245 | //marked point: 246 | if (next_marked != yarn_marked.end() && *next_marked == i) { 247 | pts_marked.emplace_back(pts.size()-1); 248 | ++next_marked; 249 | } 250 | //second half of curve: 251 | curve_to(me, e); 252 | } 253 | 254 | //final part (is also a straight line): 255 | line_to(yarn.back()); 256 | if (next_marked != yarn_marked.end() && *next_marked == yarn.size()-1) { 257 | pts_marked.emplace_back(pts.size()-1); 258 | ++next_marked; 259 | } 260 | assert(next_marked == yarn_marked.end()); 261 | assert(pts_marked.size() == yarn_marked.size()); 262 | } 263 | std::vector< bool > is_marked(pts.size(), false); 264 | for (auto m : pts_marked) { 265 | is_marked[m] = true; 266 | } 267 | 268 | std::cout << "Sampled " << yarn.size() << " (" << yarn_marked.size() << " marked) into " << pts.size() << " test points; fitting..." << std::endl; 269 | 270 | //Now approximate test points with catmull-rom spline: 271 | 272 | //helper to check distance of points in [i1,i2] given control points [i0,i1,i2,i3] have been selected. 273 | //special cases: 274 | // if i0 == -1U: (i1 must be 0) start of spline, point for a is reflection of i2 over i1 275 | // if i3 == -1U: (i2 must be pts.size()-1) end of spline, point for i3 is reflection of i1 over i2 276 | auto check_dis2 = [&pts](uint32_t i0, uint32_t i1, uint32_t i2, uint32_t i3) { 277 | //look up control points, handling edge conditions: 278 | assert(i1 < pts.size()); 279 | glm::vec3 p1 = pts[i1]; 280 | assert(i2 < pts.size()); 281 | glm::vec3 p2 = pts[i2]; 282 | glm::vec3 p0; 283 | if (i0 == -1U) { 284 | assert(i1 == 0); 285 | p0 = p1 - (p2 - p1); 286 | } else { 287 | assert(i0 < pts.size()); 288 | p0 = pts[i0]; 289 | } 290 | glm::vec3 p3; 291 | if (i3 == -1U) { 292 | assert(i2 == pts.size()-1); 293 | p3 = p2 - (p1 - p2); 294 | } else { 295 | assert(i3 < pts.size()); 296 | p3 = pts[i3]; 297 | } 298 | 299 | float max_dis2 = 0.0f; 300 | //Note: spline meets i1, i2 exactly, so only testing internal points 301 | for (uint32_t i = i1 + 1; i < i2; ++i) { 302 | /* pyramid method: 303 | //compute point on spline as per https://en.wikipedia.org/wiki/Centripetal_Catmull%E2%80%93Rom_spline 304 | //time relative to knots at 0 (pa), 1 (pb), 2 (pc), 3 (pd): 305 | float t = 1.0f + float(i - i1) / float(i2 - i1); 306 | glm::vec3 a1 = glm::mix(p0,p1, (t-0.0f) / (1.0f - 0.0f)); 307 | glm::vec3 a2 = glm::mix(p1,p2, (t-1.0f) / (2.0f - 1.0f)); 308 | glm::vec3 a3 = glm::mix(p2,p3, (t-2.0f) / (3.0f - 2.0f)); 309 | glm::vec3 b1 = glm::mix(a1,a2, (t-0.0f) / (2.0f - 0.0f)); 310 | glm::vec3 b2 = glm::mix(a2,a3, (t-1.0f) / (3.0f - 1.0f)); 311 | glm::vec3 at = glm::mix(b1,b2, (t-1.0f) / (2.0f - 1.0f)); 312 | */ 313 | 314 | //compute point on spline as per https://www.mvps.org/directx/articles/catmull/ 315 | float s = float(i-i1) / float(i2-i1); 316 | glm::vec4 coefs = 0.5f * glm::vec4(1.0f, s, s*s, s*s*s); 317 | /* 318 | glm::vec3 at = (coefs * glm::transpose(glm::mat4( 319 | 0.0f, 2.0f, 0.0f, 0.0f, 320 | -1.0f, 0.0f, 1.0f, 0.0f, 321 | 2.0f,-5.0f, 4.0f,-1.0f, 322 | -1.0f, 3.0f,-3.0f, 1.0f 323 | ))) * glm::transpose(glm::mat4x3(p0, p1, p2, p3)); 324 | */ 325 | 326 | //basis polynomial method (without matrices): 327 | // -- seems fastest in my [very rough] tests 328 | glm::vec3 at = 329 | (-coefs[1] + 2.0f * coefs[2] - coefs[3]) * p0 330 | + (2.0f * coefs[0] - 5.0f * coefs[2] + 3.0f * coefs[3]) * p1 331 | + (coefs[1] + 4.0f * coefs[2] - 3.0f * coefs[3]) * p2 332 | + (-coefs[2] + coefs[3]) * p3; 333 | 334 | //assert(glm::length2(at - at2) < 0.001f); 335 | 336 | float dis2 = glm::length2(at - pts[i]); 337 | max_dis2 = std::max(dis2, max_dis2); 338 | } 339 | 340 | return max_dis2; 341 | }; 342 | 343 | //Search for best path, where steps go from triples of points to triples of points (extend spline by one segment): 344 | struct DistanceFrom { 345 | DistanceFrom(uint32_t distance_, uint32_t from_) : distance(distance_), from(from_) { } 346 | uint32_t distance; 347 | uint32_t from; 348 | }; 349 | std::unordered_map< glm::uvec3, DistanceFrom > distance; //distance == # of points to get to pair 350 | std::multimap< std::pair< uint32_t, uint32_t >, glm::uvec3 > to_expand; //to expand sorted by heuristic & distance 351 | 352 | auto queue = [&distance, &to_expand](glm::uvec3 at, DistanceFrom df) { 353 | auto ret = distance.emplace(at, df); 354 | if (ret.second || ret.first->second.distance > df.distance) { 355 | ret.first->second = df; 356 | uint32_t heuristic = df.distance; // + (pts.size() - 1 - at.y); //<-- NOTE: inadmissable heuristic 357 | to_expand.emplace(std::make_pair(heuristic, df.distance), at); 358 | } 359 | }; 360 | 361 | constexpr uint32_t MaxStep = 80; //hmm, might want to adjust this? 362 | 363 | //try a bunch of different starting strides: 364 | for (uint32_t s = 1; s <= MaxStep; ++s) { 365 | queue(glm::uvec3(-1U, 0, s), DistanceFrom(2, -1U)); 366 | } 367 | 368 | uint32_t best_dis = -1U; 369 | glm::uvec3 best_end = glm::uvec3(-1U); 370 | 371 | 372 | while (!to_expand.empty()) { 373 | uint32_t dis = to_expand.begin()->first.second; 374 | glm::uvec3 at = to_expand.begin()->second; 375 | to_expand.erase(to_expand.begin()); 376 | { 377 | auto f = distance.find(at); 378 | assert(f != distance.end()); 379 | assert(f->second.distance <= dis); 380 | if (f->second.distance < dis) continue; 381 | } 382 | 383 | if (at.z + 1 == pts.size()) { 384 | if (dis < best_dis) { 385 | std::cout << "Reached end in " << dis << " points." << std::endl; 386 | best_dis = dis; 387 | best_end = at; 388 | } 389 | } 390 | 391 | 392 | for (uint32_t s = 1; s < MaxStep; ++s) { 393 | if (at.z + s >= pts.size()) break; 394 | //TODO: must also not skip marked points! 395 | if (check_dis2(at.x, at.y, at.z, at.z + s) <= tol2) { 396 | //have to also check ending: 397 | if (at.z + s + 1 != pts.size() || check_dis2(at.y, at.z, at.z + s, -1U) <= tol2) { 398 | queue(glm::uvec3(at.y, at.z, at.z + s), DistanceFrom(dis + 1, at.x)); 399 | } 400 | } 401 | if (is_marked[at.z + s]) break; //can't skip over marked points 402 | } 403 | } 404 | 405 | assert(best_end.x < best_end.y && best_end.y < best_end.z && best_end.z < pts.size()); 406 | std::vector< uint32_t > path; 407 | { //read back whole path (in reverse): 408 | path.emplace_back(best_end.z); 409 | path.emplace_back(best_end.y); 410 | path.emplace_back(best_end.x); 411 | 412 | uint32_t dis = best_dis; 413 | 414 | while (path.back() != 0) { 415 | auto f = distance.find(glm::uvec3( 416 | path[path.size()-1], 417 | path[path.size()-2], 418 | path[path.size()-3] 419 | )); 420 | assert(f != distance.end()); 421 | path.emplace_back(f->second.from); 422 | } 423 | std::reverse(path.begin(), path.end()); 424 | std::cout << "Read out path of length " << path.size() << "." << std::endl; 425 | assert(dis == path.size()); 426 | } 427 | 428 | rom.reserve(path.size()+2); 429 | rom.emplace_back(glm::mix(pts[path[0]], pts[path[1]], -1.0f)); 430 | for (auto &i : path) { 431 | if (is_marked[i]) rom_marked.emplace_back(rom.size()); 432 | rom.emplace_back(pts[i]); 433 | } 434 | rom.emplace_back(glm::mix(pts[path[path.size()-2]], pts[path[path.size()-1]], 2.0f)); 435 | assert(rom_marked.size() == yarn_marked.size()); 436 | 437 | } 438 | -------------------------------------------------------------------------------- /web/renderers.lines.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | (function(){ 3 | 4 | window.renderers = window.renderers || {}; 5 | 6 | window.renderers.lines = {}; 7 | console.log("Set lines."); 8 | 9 | const colorProgram = initShaderProgram( 10 | ` 11 | uniform mat4 mvp_mat4; 12 | 13 | attribute vec4 Position; 14 | attribute vec4 Color; 15 | 16 | varying vec4 color; 17 | 18 | void main() { 19 | gl_Position = mvp_mat4 * Position; 20 | color = Color; 21 | } 22 | `,` 23 | varying lowp vec4 color; 24 | void main() { 25 | gl_FragColor = color; 26 | } 27 | `); 28 | 29 | const yarnsBuffer = gl.createBuffer(); 30 | const yarnStarts = []; 31 | 32 | window.renderers.lines.uploadYarns = function lines_uploadYarns() { 33 | //clear yarnStarts array: 34 | yarnStarts.splice(0,yarnStarts.length); 35 | 36 | //accmulate Position attribs for all yarns: 37 | let Positions = []; 38 | yarns.yarns.forEach(function(yarn){ 39 | yarnStarts.push(Positions.length / 3); 40 | Positions = Positions.concat(yarn.points); 41 | }); 42 | yarnStarts.push(Positions.length / 3); 43 | 44 | gl.bindBuffer(gl.ARRAY_BUFFER, yarnsBuffer); 45 | gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(Positions), gl.STATIC_DRAW); 46 | }; 47 | 48 | window.renderers.lines.redraw = function lines_redraw() { 49 | 50 | gl.clearColor(0.1, 0.1, 0.1, 1.0); 51 | gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); 52 | 53 | gl.useProgram(colorProgram.program); 54 | gl.bindBuffer(gl.ARRAY_BUFFER, yarnsBuffer); 55 | 56 | gl.vertexAttrib4f(colorProgram.attribLocations.Color, 1.0, 0.0, 1.0, 1.0); 57 | gl.disableVertexAttribArray(colorProgram.attribLocations.Color); 58 | 59 | gl.vertexAttribPointer(colorProgram.attribLocations.Position, 60 | 3, //size 61 | gl.FLOAT, //type 62 | false, //normalize 63 | 12, //stride 64 | 0 //offset 65 | ); 66 | gl.enableVertexAttribArray(colorProgram.attribLocations.Position); 67 | 68 | gl.uniformMatrix4fv( 69 | colorProgram.uniformLocations.mvp_mat4, 70 | false, 71 | computeMVP() 72 | ); 73 | 74 | for (let i = 0; i + 1 < yarnStarts.length; ++i) { 75 | gl.drawArrays(gl.LINE_STRIP, yarnStarts[i], yarnStarts[i+1]-yarnStarts[i]); 76 | } 77 | }; 78 | 79 | 80 | })(); 81 | -------------------------------------------------------------------------------- /web/sm.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | (function(){ 3 | 4 | const sm = (typeof(module) === 'undefined' ? (window.sm = {}) : module.exports ); 5 | 6 | sm.Yarns = function() { 7 | this.yarns = []; 8 | this.units = []; //{name:'1', length:1.0} ]; 9 | }; 10 | 11 | /* 12 | * Return yarns object created from ArrayBuffer, 13 | * throw on error. 14 | */ 15 | 16 | sm.Yarns.fromArrayBuffer = function(buffer) { 17 | const yarns = new sm.Yarns(); 18 | 19 | const view = new DataView(buffer); 20 | 21 | let offset = 0; 22 | 23 | //helpers: read value and update offset 24 | function getUint8() { 25 | const got = view.getUint8(offset); 26 | offset += 1; 27 | return got; 28 | } 29 | function getUint32() { 30 | const got = view.getUint32(offset, true); 31 | offset += 4; 32 | return got; 33 | } 34 | function getFloat32() { 35 | const got = view.getFloat32(offset, true); 36 | offset += 4; 37 | return got; 38 | } 39 | 40 | //helper: read chunk header from view 41 | function getCount(fourcc, itemSize) { 42 | console.assert(fourcc.length === 4, "fourcc supplied to getCount should have four characters"); 43 | let gotFourcc = ''; 44 | gotFourcc += String.fromCharCode(getUint8()); 45 | gotFourcc += String.fromCharCode(getUint8()); 46 | gotFourcc += String.fromCharCode(getUint8()); 47 | gotFourcc += String.fromCharCode(getUint8()); 48 | if (gotFourcc !== fourcc) { 49 | throw new Error("Expecting chunk fourcc '" + fourcc + "', got fourcc '" + gotFourcc + "'."); 50 | } 51 | let gotSize = getUint32(); 52 | if (gotSize % itemSize !== 0) { 53 | throw new Error("Expecting chunk size (" + gotSize + ") to be a multiple of item size (" + itemSize + ")."); 54 | } 55 | return gotSize / itemSize; 56 | } 57 | 58 | const pointsCount = getCount('f3..', 12); 59 | console.log(pointsCount + " points."); 60 | const points = []; 61 | for (let i = 0; i < pointsCount; ++i) { 62 | let x = getFloat32(); 63 | let y = getFloat32(); 64 | let z = getFloat32(); 65 | points.push(x,y,z); 66 | } 67 | //helper: get points from range 68 | function getPoints(begin, end) { 69 | return points.slice(3*begin, 3*end); 70 | } 71 | 72 | const sourcesCount = getCount('src.', 4); 73 | console.log(sourcesCount + " sources."); 74 | const sources = []; 75 | for (let i = 0; i < sourcesCount; ++i) { 76 | const source = getUint32(); 77 | sources.push(source); 78 | } 79 | if (3*sources.length !== points.length) { 80 | throw new Error("Yarns file should have as many sources as points."); 81 | } 82 | 83 | //helper: get sources from range 84 | function getSources(begin, end) { 85 | return sources.slice(begin, end); 86 | } 87 | 88 | //build map for checkpoint sorting: 89 | const pointToYarnIndex = new Array(points.length); 90 | const yarnPointBegin = []; 91 | 92 | const yarnInfosCount = getCount('yarn', 16); 93 | console.log(yarnInfosCount + " yarnInfos."); 94 | for (let i = 0; i < yarnInfosCount; ++i) { 95 | const pointBegin = getUint32(); 96 | const pointEnd = getUint32(); 97 | const radius = getFloat32(); 98 | const r = getUint8(); 99 | const g = getUint8(); 100 | const b = getUint8(); 101 | const a = getUint8(); 102 | if (!(pointBegin <= pointEnd && pointEnd < points.length)) { 103 | throw new Error("Invalid point indices [" + pointBegin + ", " + pointEnd + ") of " + points.length + " in yarn info."); 104 | } 105 | yarns.yarns.push({ 106 | points:getPoints(pointBegin, pointEnd), 107 | sources:getSources(pointBegin, pointEnd), 108 | radius:radius, 109 | color:{ r:r, g:g, b:b, a:a }, 110 | checkpoints:[] 111 | }); 112 | 113 | //update checkpoint lookup map: 114 | yarnPointBegin.push(pointBegin); 115 | for (let p = pointBegin; p < pointEnd; ++p) { 116 | pointToYarnIndex[p] = i; 117 | } 118 | } 119 | 120 | const stringsBytes = getCount('strs', 1); 121 | console.log(stringsBytes + " bytes of strings."); 122 | const strings = new Uint8Array(buffer, offset, stringsBytes); 123 | offset += stringsBytes; 124 | //helper: get string from byte range 125 | function getString(begin, end) { 126 | //TODO: consider utf8 decode 127 | let string = ''; 128 | for (let i = begin; i < end; ++i) { 129 | string += String.fromCharCode(strings[i]); 130 | } 131 | return string; 132 | } 133 | 134 | const unitsCount = getCount('unit', 12); 135 | console.log(unitsCount + " units."); 136 | for (let i = 0; i < unitsCount; ++i) { 137 | const nameBegin = getUint32(); 138 | const nameEnd = getUint32(); 139 | const length = getFloat32(); 140 | yarns.units.push({ 141 | name:getString(nameBegin, nameEnd), 142 | length:length 143 | }); 144 | } 145 | 146 | const checkpointsCount = getCount('chk.', 12); 147 | console.log(checkpointsCount + " checkpoints."); 148 | for (let i = 0; i < checkpointsCount; ++i) { 149 | const point = getUint32(); 150 | const length = getFloat32(); 151 | const unit = getUint32(); 152 | if (unit >= yarns.units.length) { 153 | throw new Error("Checkpoint with out-of-range unit index " + unit + "."); 154 | } 155 | //store checkpoint in proper yarn: 156 | const yarnIndex = pointToYarnIndex[point]; 157 | if (typeof(yarnIndex) !== 'number') { 158 | throw new Error("Checkpoint " + point + " doesn't lie in a yarn."); 159 | } 160 | yarns.yarns[yarnIndex].checkpoints.push({ 161 | point:point-yarnPointBegin[yarnIndex], 162 | length:length, 163 | unit:unit 164 | }); 165 | } 166 | 167 | 168 | yarns.yarns.forEach(function(yarn){ 169 | yarn.sources = sources.slice(yarn.pointsBegin, yarn.pointsEnd); 170 | delete yarn.pointsBegin; 171 | delete yarn.pointsEnd; 172 | }); 173 | 174 | 175 | return yarns; 176 | }; 177 | 178 | })(); 179 | -------------------------------------------------------------------------------- /web/view-yarns.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | '.yarns' viewer 5 | 93 | 94 | 95 | 96 | 97 |
98 | 99 | 100 |
101 |

No File Loaded

102 | 103 | 104 | 109 | 110 | 111 |
112 | 113 | 114 |
115 | 116 |
117 | 118 | 119 |
120 |

Units:

121 |
    122 |
123 |
124 | 125 |
126 | 127 | 128 |
129 | 130 | 217 | 218 | 221 | 222 | 595 | 596 | 597 | 598 | 742 | 743 | 744 | --------------------------------------------------------------------------------