1#!/usr/bin/env python
2
3"""gen_pattern.py
4Usage example:
5python gen_pattern.py -o out.svg -r 11 -c 8 -T circles -s 20.0 -R 5.0 -u mm -w 216 -h 279
6
7-o, --output - output file (default out.svg)
8-r, --rows - pattern rows (default 11)
9-c, --columns - pattern columns (default 8)
10-T, --type - type of pattern, circles, acircles, checkerboard (default circles)
11-s, --square_size - size of squares in pattern (default 20.0)
12-R, --radius_rate - circles_radius = square_size/radius_rate (default 5.0)
13-u, --units - mm, inches, px, m (default mm)
14-w, --page_width - page width in units (default 216)
15-h, --page_height - page height in units (default 279)
16-H, --help - show help
17"""
18
19from svgfig import *
20
21import sys
22import getopt
23
24class PatternMaker:
25  def __init__(self, cols,rows,output,units,square_size,radius_rate,page_width,page_height):
26    self.cols = cols
27    self.rows = rows
28    self.output = output
29    self.units = units
30    self.square_size = square_size
31    self.radius_rate = radius_rate
32    self.width = page_width
33    self.height = page_height
34    self.g = SVG("g") # the svg group container
35
36  def makeCirclesPattern(self):
37    spacing = self.square_size
38    r = spacing / self.radius_rate
39    for x in range(1,self.cols+1):
40      for y in range(1,self.rows+1):
41        dot = SVG("circle", cx=x * spacing, cy=y * spacing, r=r, fill="black")
42        self.g.append(dot)
43
44  def makeACirclesPattern(self):
45    spacing = self.square_size
46    r = spacing / self.radius_rate
47    for i in range(0,self.rows):
48      for j in range(0,self.cols):
49        dot = SVG("circle", cx= ((j*2 + i%2)*spacing) + spacing, cy=self.height - (i * spacing + spacing), r=r, fill="black")
50        self.g.append(dot)
51
52  def makeCheckerboardPattern(self):
53    spacing = self.square_size
54    for x in range(1,self.cols+1):
55      for y in range(1,self.rows+1):
56        if x%2 == y%2:
57          dot = SVG("rect", x=x * spacing, y=y * spacing, width=spacing, height=spacing, stroke_width="0", fill="black")
58          self.g.append(dot)
59
60  def save(self):
61    c = canvas(self.g,width="%d%s"%(self.width,self.units),height="%d%s"%(self.height,self.units),viewBox="0 0 %d %d"%(self.width,self.height))
62    c.inkview(self.output)
63
64
65def main():
66    # parse command line options, TODO use argparse for better doc
67    try:
68        opts, args = getopt.getopt(sys.argv[1:], "Ho:c:r:T:u:s:R:w:h:", ["help","output=","columns=","rows=",
69                                                                      "type=","units=","square_size=","radius_rate=",
70                                                                      "page_width=","page_height="])
71    except getopt.error, msg:
72        print msg
73        print "for help use --help"
74        sys.exit(2)
75    output = "out.svg"
76    columns = 8
77    rows = 11
78    p_type = "circles"
79    units = "mm"
80    square_size = 20.0
81    radius_rate = 5.0
82    page_width = 216    #8.5 inches
83    page_height = 279   #11 inches
84    # process options
85    for o, a in opts:
86        if o in ("-H", "--help"):
87            print __doc__
88            sys.exit(0)
89        elif o in ("-r", "--rows"):
90            rows = int(a)
91        elif o in ("-c", "--columns"):
92            columns = int(a)
93        elif o in ("-o", "--output"):
94            output = a
95        elif o in ("-T", "--type"):
96            p_type = a
97        elif o in ("-u", "--units"):
98            units = a
99        elif o in ("-s", "--square_size"):
100            square_size = float(a)
101        elif o in ("-R", "--radius_rate"):
102            radius_rate = float(a)
103        elif o in ("-w", "--page_width"):
104            page_width = float(a)
105        elif o in ("-h", "--page_height"):
106            page_height = float(a)
107    pm = PatternMaker(columns,rows,output,units,square_size,radius_rate,page_width,page_height)
108    #dict for easy lookup of pattern type
109    mp = {"circles":pm.makeCirclesPattern,"acircles":pm.makeACirclesPattern,"checkerboard":pm.makeCheckerboardPattern}
110    mp[p_type]()
111    #this should save pattern to output
112    pm.save()
113
114if __name__ == "__main__":
115    main()
116