47f3ad59c589e19d600476d645511b42716acb85
1 #! /usr/bin/env python
2 '''
3 Copyright (C) 2009 Aurelio A. Heckert <aurium (a) gmail dot com>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 '''
20 __version__ = "0.2"
22 import inkex, simplestyle
23 from math import *
24 from simplepath import formatPath
26 class FoldableBox(inkex.Effect):
28 def __init__(self):
29 inkex.Effect.__init__(self)
30 self.OptionParser.add_option("-x", "--width",
31 action="store", type="float",
32 dest="width", default=10.0,
33 help="The Box Width - in the X dimension")
34 self.OptionParser.add_option("-y", "--height",
35 action="store", type="float",
36 dest="height", default=15.0,
37 help="The Box Height - in the Y dimension")
38 self.OptionParser.add_option("-z", "--depth",
39 action="store", type="float",
40 dest="depth", default=3.0,
41 help="The Box Depth - in the Z dimension")
42 self.OptionParser.add_option("-u", "--unit",
43 action="store", type="string",
44 dest="unit", default="cm",
45 help="The unit of the box dimensions")
46 self.OptionParser.add_option("-p", "--paper-thickness",
47 action="store", type="float",
48 dest="thickness", default=0.01,
49 help="Paper Thickness - sometimes that is important")
50 self.OptionParser.add_option("-t", "--tab-proportion",
51 action="store", type="float",
52 dest="tabProportion", default=0.6,
53 help="Inner tab propotion for upper tab")
54 self.OptionParser.add_option("-g", "--guide-line",
55 action="store", type="inkbool",
56 dest="guideLine", default=True,
57 help="Add guide lines to help the drawing limits")
59 def effect(self):
61 docW = inkex.unittouu(self.document.getroot().get('width'))
62 docH = inkex.unittouu(self.document.getroot().get('height'))
64 boxW = inkex.unittouu( str(self.options.width) + self.options.unit )
65 boxH = inkex.unittouu( str(self.options.height) + self.options.unit )
66 boxD = inkex.unittouu( str(self.options.depth) + self.options.unit )
67 tabProp = self.options.tabProportion
68 tabH = boxD * tabProp
70 box_id = self.uniqueId('box')
71 self.box = g = inkex.etree.SubElement(self.current_layer, 'g', {'id':box_id})
73 line_style = simplestyle.formatStyle({ 'stroke': '#000000', 'fill': 'none' })
75 #self.createGuide( 0, docH, 0 );
77 # Inner Close Tab
78 line_path = [
79 [ 'M', [ boxW-(tabH*0.7), 0 ] ],
80 [ 'C', [ boxW-(tabH*0.25), 0, boxW, tabH*0.3, boxW, tabH*0.9 ] ],
81 [ 'L', [ boxW, tabH ] ],
82 [ 'L', [ 0, tabH ] ],
83 [ 'L', [ 0, tabH*0.9 ] ],
84 [ 'C', [ 0, tabH*0.3, tabH*0.25, 0, tabH*0.7, 0 ] ],
85 [ 'Z', [] ]
86 ]
87 line_atts = { 'style':line_style, 'id':box_id+'-inner-close-tab', 'd':formatPath(line_path) }
88 inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts )
90 lower_pos = boxD+tabH
91 left_pos = 0
93 #self.createGuide( 0, docH-tabH, 0 );
95 # Upper Close Tab
96 line_path = [
97 [ 'M', [ left_pos, tabH ] ],
98 [ 'L', [ left_pos + boxW, tabH ] ],
99 [ 'L', [ left_pos + boxW, lower_pos ] ],
100 [ 'L', [ left_pos + 0, lower_pos ] ],
101 [ 'Z', [] ]
102 ]
103 line_atts = { 'style':line_style, 'id':box_id+'-upper-close-tab', 'd':formatPath(line_path) }
104 inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts )
106 left_pos += boxW
108 # Upper Right Tab
109 sideTabH = lower_pos - (boxW/2)
110 if sideTabH < tabH: sideTabH = tabH
111 line_path = [
112 [ 'M', [ left_pos, sideTabH ] ],
113 [ 'L', [ left_pos + (boxD*0.8), sideTabH ] ],
114 [ 'L', [ left_pos + boxD, ((lower_pos*3)-sideTabH)/3 ] ],
115 [ 'L', [ left_pos + boxD, lower_pos ] ],
116 [ 'L', [ left_pos + 0, lower_pos ] ],
117 [ 'Z', [] ]
118 ]
119 line_atts = { 'style':line_style, 'id':box_id+'-upper-right-tab', 'd':formatPath(line_path) }
120 inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts )
122 left_pos += boxW + boxD
124 # Upper Left Tab
125 line_path = [
126 [ 'M', [ left_pos + boxD, sideTabH ] ],
127 [ 'L', [ left_pos + (boxD*0.2), sideTabH ] ],
128 [ 'L', [ left_pos, ((lower_pos*3)-sideTabH)/3 ] ],
129 [ 'L', [ left_pos, lower_pos ] ],
130 [ 'L', [ left_pos + boxD, lower_pos ] ],
131 [ 'Z', [] ]
132 ]
133 line_atts = { 'style':line_style, 'id':box_id+'-upper-left-tab', 'd':formatPath(line_path) }
134 inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts )
136 left_pos = 0
138 #self.createGuide( 0, docH-tabH-boxD, 0 );
140 # Right Tab
141 line_path = [
142 [ 'M', [ left_pos, lower_pos ] ],
143 [ 'L', [ left_pos - (boxD/2), lower_pos + (boxD/4) ] ],
144 [ 'L', [ left_pos - (boxD/2), lower_pos + boxH - (boxD/4) ] ],
145 [ 'L', [ left_pos, lower_pos + boxH ] ],
146 [ 'Z', [] ]
147 ]
148 line_atts = { 'style':line_style, 'id':box_id+'-left-tab', 'd':formatPath(line_path) }
149 inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts )
151 # Front
152 line_path = [
153 [ 'M', [ left_pos, lower_pos ] ],
154 [ 'L', [ left_pos + boxW, lower_pos ] ],
155 [ 'L', [ left_pos + boxW, lower_pos + boxH ] ],
156 [ 'L', [ left_pos, lower_pos + boxH ] ],
157 [ 'Z', [] ]
158 ]
159 line_atts = { 'style':line_style, 'id':box_id+'-front', 'd':formatPath(line_path) }
160 inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts )
162 left_pos += boxW
164 # Right
165 line_path = [
166 [ 'M', [ left_pos, lower_pos ] ],
167 [ 'L', [ left_pos + boxD, lower_pos ] ],
168 [ 'L', [ left_pos + boxD, lower_pos + boxH ] ],
169 [ 'L', [ left_pos, lower_pos + boxH ] ],
170 [ 'Z', [] ]
171 ]
172 line_atts = { 'style':line_style, 'id':box_id+'-right', 'd':formatPath(line_path) }
173 inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts )
175 left_pos += boxD
177 # Back
178 line_path = [
179 [ 'M', [ left_pos, lower_pos ] ],
180 [ 'L', [ left_pos + boxW, lower_pos ] ],
181 [ 'L', [ left_pos + boxW, lower_pos + boxH ] ],
182 [ 'L', [ left_pos, lower_pos + boxH ] ],
183 [ 'Z', [] ]
184 ]
185 line_atts = { 'style':line_style, 'id':box_id+'-back', 'd':formatPath(line_path) }
186 inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts )
188 left_pos += boxW
190 # Left
191 line_path = [
192 [ 'M', [ left_pos, lower_pos ] ],
193 [ 'L', [ left_pos + boxD, lower_pos ] ],
194 [ 'L', [ left_pos + boxD, lower_pos + boxH ] ],
195 [ 'L', [ left_pos, lower_pos + boxH ] ],
196 [ 'Z', [] ]
197 ]
198 line_atts = { 'style':line_style, 'id':box_id+'-left', 'd':formatPath(line_path) }
199 inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts )
201 lower_pos += boxH
202 left_pos = 0
203 bTab = lower_pos + boxD
204 if bTab > boxW / 2.5: bTab = boxW / 2.5
206 # Bottom Front Tab
207 line_path = [
208 [ 'M', [ left_pos, lower_pos ] ],
209 [ 'L', [ left_pos, lower_pos + (boxD/2) ] ],
210 [ 'L', [ left_pos + boxW, lower_pos + (boxD/2) ] ],
211 [ 'L', [ left_pos + boxW, lower_pos ] ],
212 [ 'Z', [] ]
213 ]
214 line_atts = { 'style':line_style, 'id':box_id+'-bottom-front-tab', 'd':formatPath(line_path) }
215 inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts )
217 left_pos += boxW
219 # Bottom Right Tab
220 line_path = [
221 [ 'M', [ left_pos, lower_pos ] ],
222 [ 'L', [ left_pos, lower_pos + bTab ] ],
223 [ 'L', [ left_pos + boxD, lower_pos + bTab ] ],
224 [ 'L', [ left_pos + boxD, lower_pos ] ],
225 [ 'Z', [] ]
226 ]
227 line_atts = { 'style':line_style, 'id':box_id+'-bottom-right-tab', 'd':formatPath(line_path) }
228 inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts )
230 left_pos += boxD
232 # Bottom Back Tab
233 line_path = [
234 [ 'M', [ left_pos, lower_pos ] ],
235 [ 'L', [ left_pos, lower_pos + (boxD/2) ] ],
236 [ 'L', [ left_pos + boxW, lower_pos + (boxD/2) ] ],
237 [ 'L', [ left_pos + boxW, lower_pos ] ],
238 [ 'Z', [] ]
239 ]
240 line_atts = { 'style':line_style, 'id':box_id+'-bottom-back-tab', 'd':formatPath(line_path) }
241 inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts )
243 left_pos += boxW
245 # Bottom Left Tab
246 line_path = [
247 [ 'M', [ left_pos, lower_pos ] ],
248 [ 'L', [ left_pos, lower_pos + bTab ] ],
249 [ 'L', [ left_pos + boxD, lower_pos + bTab ] ],
250 [ 'L', [ left_pos + boxD, lower_pos ] ],
251 [ 'Z', [] ]
252 ]
253 line_atts = { 'style':line_style, 'id':box_id+'-bottom-left-tab', 'd':formatPath(line_path) }
254 inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts )
256 left_pos += boxD
257 lower_pos += bTab
259 g.set( 'transform', 'translate(%f,%f)' % ( (docW-left_pos)/2, (docH-lower_pos)/2 ) )
261 if __name__ == '__main__': #pragma: no cover
262 e = FoldableBox()
263 e.affect()
265 # vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 encoding=utf-8 textwidth=99