| 1 |
|
|---|
| 2 |
|
|---|
| 3 |
|
|---|
| 4 |
|
|---|
| 5 |
|
|---|
| 6 |
|
|---|
| 7 |
''' |
|---|
| 8 |
Copyright (C) 2005 Andrea Lo Pumo aka AlpT <alpt@freaknet.org> |
|---|
| 9 |
|
|---|
| 10 |
This source code is free software; you can redistribute it and/or |
|---|
| 11 |
modify it under the terms of the GNU General Public License as published |
|---|
| 12 |
by the Free Software Foundation; either version 2 of the License, |
|---|
| 13 |
or (at your option) any later version. |
|---|
| 14 |
|
|---|
| 15 |
This source code is distributed in the hope that it will be useful, |
|---|
| 16 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 17 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|---|
| 18 |
Please refer to the GNU Public License for more details. |
|---|
| 19 |
|
|---|
| 20 |
You should have received a copy of the GNU Public License along with |
|---|
| 21 |
this source code; if not, write to: |
|---|
| 22 |
Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
|---|
| 23 |
''' |
|---|
| 24 |
|
|---|
| 25 |
|
|---|
| 26 |
|
|---|
| 27 |
|
|---|
| 28 |
|
|---|
| 29 |
|
|---|
| 30 |
import inkex, T, stylevariation |
|---|
| 31 |
import random, copy, sys |
|---|
| 32 |
from math import sqrt |
|---|
| 33 |
|
|---|
| 34 |
|
|---|
| 35 |
HSBO_PRECISION=1000.0 |
|---|
| 36 |
|
|---|
| 37 |
def weighted_random_index(weights): |
|---|
| 38 |
'''Given a list of weights, chooses a random weighted integer |
|---|
| 39 |
from [0, len(weights)-1]''' |
|---|
| 40 |
weights = [ int(w*100) for w in weights ] |
|---|
| 41 |
wsum = int(sum(weights)) |
|---|
| 42 |
wi = random.randint(1, wsum) |
|---|
| 43 |
i=ws=0 |
|---|
| 44 |
for w in weights: |
|---|
| 45 |
ws+=w |
|---|
| 46 |
if wi <= ws: break |
|---|
| 47 |
i+=1 |
|---|
| 48 |
return i |
|---|
| 49 |
|
|---|
| 50 |
class Gdadin(inkex.Effect): |
|---|
| 51 |
def svg_nodefromid(self, id): |
|---|
| 52 |
return self.document.xpath('//*[@id="%s"]' % id, namespaces=inkex.NSS)[0] |
|---|
| 53 |
|
|---|
| 54 |
def svg_prefixfromtag(self, name): |
|---|
| 55 |
if '{' in name and '}' in name: |
|---|
| 56 |
prefix = name.split('}')[-1] |
|---|
| 57 |
else: |
|---|
| 58 |
prefix = name[0] |
|---|
| 59 |
return prefix |
|---|
| 60 |
|
|---|
| 61 |
def svg_appendnewnode(self, node, name, attrib={}): |
|---|
| 62 |
if not attrib or 'id' not in attrib: |
|---|
| 63 |
attrib['id'] = self.newid(self.svg_prefixfromtag(name)) |
|---|
| 64 |
return inkex.etree.SubElement(node, name, attrib) |
|---|
| 65 |
|
|---|
| 66 |
def svg_appendnode(self, node, child): |
|---|
| 67 |
node.append(child) |
|---|
| 68 |
|
|---|
| 69 |
def svg_getattr(self, node, attribname): |
|---|
| 70 |
|
|---|
| 71 |
return node.get(attribname) |
|---|
| 72 |
|
|---|
| 73 |
def svg_setattr(self, node, attribname, value): |
|---|
| 74 |
return node.set(attribname, value) |
|---|
| 75 |
|
|---|
| 76 |
def svg_remattr(self, node, attribname): |
|---|
| 77 |
del node.attrib[attribname] |
|---|
| 78 |
|
|---|
| 79 |
def svg_remnode(self, node): |
|---|
| 80 |
parent=node.getparent() |
|---|
| 81 |
parent.remove(node) |
|---|
| 82 |
|
|---|
| 83 |
def svg_subnodeslist(self, node, id=None): |
|---|
| 84 |
return [ child for child in node if not id or child.get('id') == id ] |
|---|
| 85 |
|
|---|
| 86 |
def svg_nodename(self, node): |
|---|
| 87 |
return node.tag |
|---|
| 88 |
|
|---|
| 89 |
def svg_appendnewlink(self, node, hrefid): |
|---|
| 90 |
self.svg_appendnewnode(node, inkex.addNS('use', 'svg'), |
|---|
| 91 |
{ inkex.addNS('href','xlink'):'#'+hrefid }) |
|---|
| 92 |
|
|---|
| 93 |
def newid(self, prefix): |
|---|
| 94 |
|
|---|
| 95 |
while 1: |
|---|
| 96 |
id = prefix+str(random.randint(0, 2**53)) |
|---|
| 97 |
if not id in self.doc_ids: |
|---|
| 98 |
self.doc_ids[id]=1 |
|---|
| 99 |
return id |
|---|
| 100 |
|
|---|
| 101 |
def __init__(self): |
|---|
| 102 |
inkex.Effect.__init__(self) |
|---|
| 103 |
|
|---|
| 104 |
self.rdepth_counter = {} |
|---|
| 105 |
self.shape_dimension = {} |
|---|
| 106 |
self.gdadin_shapeids = None |
|---|
| 107 |
self.cache_nodebyname = {} |
|---|
| 108 |
self.cache_idbyname = {} |
|---|
| 109 |
self.shape_bbox={} |
|---|
| 110 |
self.render_groups=[] |
|---|
| 111 |
|
|---|
| 112 |
inkex.NSS[u'gdadin']=u'http://www.inkscape.org/namespaces/inkscape' |
|---|
| 113 |
|
|---|
| 114 |
self.OptionParser.add_option("--shapename", |
|---|
| 115 |
action="store", type="string", |
|---|
| 116 |
dest="shapename", default="shape"+str(random.randint(0, 2**32-1)), |
|---|
| 117 |
help="Shape's name") |
|---|
| 118 |
self.OptionParser.add_option("--shapeweight", |
|---|
| 119 |
action="store", type="float", |
|---|
| 120 |
dest="shapeweight", default=1.0, |
|---|
| 121 |
help="Shape's weight. Used for random calls.") |
|---|
| 122 |
|
|---|
| 123 |
self.OptionParser.add_option("--scprdepth", |
|---|
| 124 |
action="store", type="int", |
|---|
| 125 |
dest="scprdepth", default=1, |
|---|
| 126 |
help="Recursion depth (0 is infinite)") |
|---|
| 127 |
|
|---|
| 128 |
self.OptionParser.add_option("--scphue", |
|---|
| 129 |
action="store", type="int", |
|---|
| 130 |
dest="scphue", default=0, |
|---|
| 131 |
help="Relative hue change") |
|---|
| 132 |
self.OptionParser.add_option("--scphuefloor", |
|---|
| 133 |
action="store", type="int", |
|---|
| 134 |
dest="scphuefloor", default=-1, |
|---|
| 135 |
help="Minimum hue value (<0 is disabled)") |
|---|
| 136 |
self.OptionParser.add_option("--scphueceil", |
|---|
| 137 |
action="store", type="int", |
|---|
| 138 |
dest="scphueceil", default=-1, |
|---|
| 139 |
help="Maximum hue value (<0 is disabled)") |
|---|
| 140 |
|
|---|
| 141 |
self.OptionParser.add_option("--scpsat", |
|---|
| 142 |
action="store", type="int", |
|---|
| 143 |
dest="scpsat", default=0, |
|---|
| 144 |
help="Relative saturation change") |
|---|
| 145 |
self.OptionParser.add_option("--scpsatfloor", |
|---|
| 146 |
action="store", type="int", |
|---|
| 147 |
dest="scpsatfloor", default=-1, |
|---|
| 148 |
help="Minimum sat value (<0 is disabled)") |
|---|
| 149 |
self.OptionParser.add_option("--scpsatceil", |
|---|
| 150 |
action="store", type="int", |
|---|
| 151 |
dest="scpsatceil", default=-1, |
|---|
| 152 |
help="Maximum sat value (<0 is disabled)") |
|---|
| 153 |
|
|---|
| 154 |
|
|---|
| 155 |
self.OptionParser.add_option("--scpbri", |
|---|
| 156 |
action="store", type="int", |
|---|
| 157 |
dest="scpbri", default=0, |
|---|
| 158 |
help="Relative brightness change") |
|---|
| 159 |
self.OptionParser.add_option("--scpbrifloor", |
|---|
| 160 |
action="store", type="int", |
|---|
| 161 |
dest="scpbrifloor", default=-1, |
|---|
| 162 |
help="Minimum bri value (<0 is disabled)") |
|---|
| 163 |
self.OptionParser.add_option("--scpbriceil", |
|---|
| 164 |
action="store", type="int", |
|---|
| 165 |
dest="scpbriceil", default=-1, |
|---|
| 166 |
help="Maximum bri value (<0 is disabled)") |
|---|
| 167 |
|
|---|
| 168 |
|
|---|
| 169 |
self.OptionParser.add_option("--scpopa", |
|---|
| 170 |
action="store", type="int", |
|---|
| 171 |
dest="scpopa", default=0, |
|---|
| 172 |
help="Relative opacity change") |
|---|
| 173 |
self.OptionParser.add_option("--scpopafloor", |
|---|
| 174 |
action="store", type="int", |
|---|
| 175 |
dest="scpopafloor", default=0, |
|---|
| 176 |
help="Minimum opa value (<0 is disabled)") |
|---|
| 177 |
self.OptionParser.add_option("--scpopaceil", |
|---|
| 178 |
action="store", type="int", |
|---|
| 179 |
dest="scpopaceil", default=1000, |
|---|
| 180 |
help="Maximum opa value (<0 is disabled)") |
|---|
| 181 |
|
|---|
| 182 |
|
|---|
| 183 |
chars = ''.join([chr(i) for i in range(65,91)+range(48,58)]) |
|---|
| 184 |
randomstring = ''.join([random.choice(chars) for i in range(9)]) |
|---|
| 185 |
self.OptionParser.add_option("--renderseed", |
|---|
| 186 |
action="store", type="string", |
|---|
| 187 |
dest="renderseed", default=randomstring, |
|---|
| 188 |
help="Random seed") |
|---|
| 189 |
self.OptionParser.add_option("--rendermaxshapes", |
|---|
| 190 |
action="store", type="int", |
|---|
| 191 |
dest="rendermaxshapes", default=0, |
|---|
| 192 |
help="Maximum number of shapes (0 is infinite)") |
|---|
| 193 |
|
|---|
| 194 |
def effect(self): |
|---|
| 195 |
pass |
|---|
| 196 |
|
|---|
| 197 |
def set_gdadin_shapeids(self): |
|---|
| 198 |
if self.gdadin_shapeids: |
|---|
| 199 |
return self.gdadin_shapeids |
|---|
| 200 |
|
|---|
| 201 |
defs = self.xpathSingle('/svg:svg//svg:defs') |
|---|
| 202 |
if defs == None: |
|---|
| 203 |
defs = self.svg_appendnewnode(self.document.getroot(), inkex.addNS('defs','svg')) |
|---|
| 204 |
self.gdadin_shapeids = defs.find(inkex.addNS('shapeids','gdadin')) |
|---|
| 205 |
if self.gdadin_shapeids == None: |
|---|
| 206 |
self.gdadin_shapeids = self.svg_appendnewnode(defs, inkex.addNS('shapeids','gdadin')) |
|---|
| 207 |
else: |
|---|
| 208 |
self.rem_old_shapeids() |
|---|
| 209 |
return self.gdadin_shapeids |
|---|
| 210 |
|
|---|
| 211 |
def get_gdadin_shapeids(self): |
|---|
| 212 |
if self.gdadin_shapeids == None: |
|---|
| 213 |
inkex.debug('WARNING: No shape has been defined yet.') |
|---|
| 214 |
return None |
|---|
| 215 |
return self.gdadin_shapeids |
|---|
| 216 |
|
|---|
| 217 |
def add_shapeid(self, sname, sid, sweight): |
|---|
| 218 |
'''Adds the shape id `sid' in the gdadin_shapeids node''' |
|---|
| 219 |
|
|---|
| 220 |
gs = self.get_gdadin_shapeids() |
|---|
| 221 |
gss = self.svg_subnodeslist(gs, sname) |
|---|
| 222 |
if not gss: |
|---|
| 223 |
n = self.svg_appendnewnode(self.get_gdadin_shapeids(), inkex.addNS('shape','gdadin'), |
|---|
| 224 |
{'id':sname, inkex.addNS('shapeid','gdadin'):sid, |
|---|
| 225 |
inkex.addNS('weight','gdadin'): str(sweight)}) |
|---|
| 226 |
else: |
|---|
| 227 |
n = gss[0] |
|---|
| 228 |
self.svg_setattr(n, inkex.addNS('shapeid','gdadin'), self.svg_getattr(n, inkex.addNS('shapeid','gdadin')) + ';' + sid) |
|---|
| 229 |
self.svg_setattr(n, inkex.addNS('weight','gdadin'), self.svg_getattr(n, inkex.addNS('weight','gdadin')) + ';' + str(sweight)) |
|---|
| 230 |
|
|---|
| 231 |
def get_gss(self, sname): |
|---|
| 232 |
|
|---|
| 233 |
return self.svg_subnodeslist(self.get_gdadin_shapeids(), sname)[0] |
|---|
| 234 |
|
|---|
| 235 |
def get_allshapeid(self, sname, gss=None): |
|---|
| 236 |
|
|---|
| 237 |
if gss == None: |
|---|
| 238 |
gss = self.get_gss(sname) |
|---|
| 239 |
return self.svg_getattr(gss, inkex.addNS('shapeid','gdadin')).split(';') |
|---|
| 240 |
|
|---|
| 241 |
def get_allshapeweight(self, sname, gss=None): |
|---|
| 242 |
|
|---|
| 243 |
if gss == None: |
|---|
| 244 |
gss = self.get_gss(sname) |
|---|
| 245 |
return [float(n) for n in self.svg_getattr(gss, inkex.addNS('weight','gdadin')).split(';')] |
|---|
| 246 |
|
|---|
| 247 |
def rem_old_shapeids(self): |
|---|
| 248 |
for gss in self.svg_subnodeslist(self.get_gdadin_shapeids()): |
|---|
| 249 |
gshapeids = self.get_allshapeid(None, gss) |
|---|
| 250 |
weights = [ str(w) for w in self.get_allshapeweight(None, gss) ] |
|---|
| 251 |
d = dict(zip(gshapeids, weights)) |
|---|
| 252 |
|
|---|
| 253 |
def is_node_alive(id): |
|---|
| 254 |
try: |
|---|
| 255 |
self.svg_nodefromid(id) |
|---|
| 256 |
return True |
|---|
| 257 |
except: |
|---|
| 258 |
return False |
|---|
| 259 |
|
|---|
| 260 |
for id in d.keys(): |
|---|
| 261 |
if not is_node_alive(id): |
|---|
| 262 |
del d[id] |
|---|
| 263 |
|
|---|
| 264 |
if not len(d): |
|---|
| 265 |
|
|---|
| 266 |
self.svg_remnode(gss) |
|---|
| 267 |
else: |
|---|
| 268 |
self.svg_setattr(gss, inkex.addNS('shapeid','gdadin'), ';'.join(d.keys())) |
|---|
| 269 |
self.svg_setattr(gss, inkex.addNS('weight','gdadin'), ';'.join(d.values())) |
|---|
| 270 |
|
|---|
| 271 |
def init_shape_cache(self): |
|---|
| 272 |
allnodes = self.svg_subnodeslist(self.get_gdadin_shapeids()) |
|---|
| 273 |
cache_shapenames = [self.svg_getattr(sn, 'id') for sn in allnodes] |
|---|
| 274 |
|
|---|
| 275 |
cache_shapeids = [self.get_allshapeid(sname) for sname in cache_shapenames] |
|---|
| 276 |
cache_shapeweights = [self.get_allshapeweight(sname) for sname in cache_shapenames] |
|---|
| 277 |
cache_shapenodes = [[ self.svg_nodefromid(sid) for sid in sids ] for sids in cache_shapeids] |
|---|
| 278 |
|
|---|
| 279 |
self.cache_nodebyname = dict(zip(cache_shapenames, cache_shapenodes)) |
|---|
| 280 |
self.cache_idbyname = dict(zip(cache_shapenames, cache_shapeids)) |
|---|
| 281 |
self.cache_weightbyname = dict(zip(cache_shapenames, cache_shapeweights)) |
|---|
| 282 |
|
|---|
| 283 |
|
|---|
| 284 |
|
|---|
| 285 |
def get_shapenode(self, sname): |
|---|
| 286 |
|
|---|
| 287 |
if not self.cache_nodebyname: |
|---|
| 288 |
self.init_shape_cache() |
|---|
| 289 |
|
|---|
| 290 |
return self.cache_nodebyname[sname][weighted_random_index(self.cache_weightbyname[sname])] |
|---|
| 291 |
|
|---|
| 292 |
def at_least_one(self): |
|---|
| 293 |
if len(self.selected) < 1: |
|---|
| 294 |
inkex.debug('Nothing to do: you have to select at least one object.') |
|---|
| 295 |
return 1 |
|---|
| 296 |
return 0 |
|---|
| 297 |
|
|---|
| 298 |
def defshape(self): |
|---|
| 299 |
if self.at_least_one(): return |
|---|
| 300 |
|
|---|
| 301 |
self.set_gdadin_shapeids() |
|---|
| 302 |
|
|---|
| 303 |
|
|---|
| 304 |
firstnode=self.selected.items()[0][1] |
|---|
| 305 |
''' |
|---|
| 306 |
if len(self.selected) == 1 and self.svg_getattr(firstnode, inkex.addNS('shape','gdadin')): |
|---|
| 307 |
sgroup = firstnode |
|---|
| 308 |
del self.selected[self.selected.items()[0][0]] |
|---|
| 309 |
else: |
|---|
| 310 |
''' |
|---|
| 311 |
sgroup = self.svg_appendnewnode(firstnode.getparent(), |
|---|
| 312 |
inkex.addNS('g','svg'), |
|---|
| 313 |
{inkex.addNS('shape','gdadin'): self.options.shapename}) |
|---|
| 314 |
|
|---|
| 315 |
for id, node in self.selected.iteritems(): |
|---|
| 316 |
|
|---|
| 317 |
|
|---|
| 318 |
|
|---|
| 319 |
cn = copy.deepcopy(node) |
|---|
| 320 |
self.svg_setattr(cn, 'id', self.newid(self.svg_prefixfromtag(cn.tag))) |
|---|
| 321 |
self.svg_appendnode(sgroup, cn) |
|---|
| 322 |
|
|---|
| 323 |
|
|---|
| 324 |
sgroupid=self.svg_getattr(sgroup, 'id') |
|---|
| 325 |
self.add_shapeid(self.options.shapename, sgroupid, self.options.shapeweight) |
|---|
| 326 |
|
|---|
| 327 |
def foreach_selected(self, f, args=None): |
|---|
| 328 |
for id, node in self.selected.iteritems(): |
|---|
| 329 |
shapename = self.svg_getattr(node, inkex.addNS('shape','gdadin')) |
|---|
| 330 |
if not shapename: |
|---|
| 331 |
inkex.debug('WARNING: one of the selected objects isn\'t a defined shape (use Gdadin -> Define Shape). I\'ll ignore it.') |
|---|
| 332 |
continue |
|---|
| 333 |
|
|---|
| 334 |
if args: |
|---|
| 335 |
f(id, node, shapename, *args) |
|---|
| 336 |
else: |
|---|
| 337 |
f(id, node, shapename) |
|---|
| 338 |
|
|---|
| 339 |
def setshapecallparams(self): |
|---|
| 340 |
if self.at_least_one(): return |
|---|
| 341 |
|
|---|
| 342 |
self.set_gdadin_shapeids() |
|---|
| 343 |
|
|---|
| 344 |
def setallattr(id, node, shapename): |
|---|
| 345 |
self.svg_setattr(node, inkex.addNS('rdepth','gdadin'), str(self.options.scprdepth)) |
|---|
| 346 |
|
|---|
| 347 |
self.svg_setattr(node, inkex.addNS('hue','gdadin'), str(self.options.scphue/HSBO_PRECISION)) |
|---|
| 348 |
self.svg_setattr(node, inkex.addNS('huefloor','gdadin'), str(self.options.scphuefloor/HSBO_PRECISION)) |
|---|
| 349 |
self.svg_setattr(node, inkex.addNS('hueceil','gdadin'), str(self.options.scphueceil/HSBO_PRECISION)) |
|---|
| 350 |
|
|---|
| 351 |
self.svg_setattr(node, inkex.addNS('sat','gdadin'), str(self.options.scpsat/HSBO_PRECISION)) |
|---|
| 352 |
self.svg_setattr(node, inkex.addNS('satfloor','gdadin'), str(self.options.scpsatfloor/HSBO_PRECISION)) |
|---|
| 353 |
self.svg_setattr(node, inkex.addNS('satceil','gdadin'), str(self.options.scpsatceil/HSBO_PRECISION)) |
|---|
| 354 |
|
|---|
| 355 |
self.svg_setattr(node, inkex.addNS('bri','gdadin'), str(self.options.scpbri/HSBO_PRECISION)) |
|---|
| 356 |
self.svg_setattr(node, inkex.addNS('brifloor','gdadin'), str(self.options.scpbrifloor/HSBO_PRECISION)) |
|---|
| 357 |
self.svg_setattr(node, inkex.addNS('briceil','gdadin'), str(self.options.scpbriceil/HSBO_PRECISION)) |
|---|
| 358 |
|
|---|
| 359 |
self.svg_setattr(node, inkex.addNS('opa','gdadin'), str(self.options.scpopa/HSBO_PRECISION)) |
|---|
| 360 |
self.svg_setattr(node, inkex.addNS('opafloor','gdadin'), str(self.options.scpopafloor/HSBO_PRECISION)) |
|---|
| 361 |
self.svg_setattr(node, inkex.addNS('opaceil','gdadin'), str(self.options.scpopaceil/HSBO_PRECISION)) |
|---|
| 362 |
|
|---|
| 363 |
self.foreach_selected(setallattr) |
|---|
| 364 |
|
|---|
| 365 |
def apply_hsbo(self, node, pnode, rdata): |
|---|
| 366 |
stylevariation.apply_colmod(self, node, (rdata['hue'], rdata['sat'], rdata['bri']), rdata['opa'], rdata) |
|---|
| 367 |
|
|---|
| 368 |
def foreach_subshape(self, rootnode, f, args=None): |
|---|
| 369 |
for parentnode in self.svg_subnodeslist(rootnode): |
|---|
| 370 |
childsname = self.svg_getattr(parentnode, inkex.addNS('shape','gdadin')) |
|---|
| 371 |
if not childsname: |
|---|
| 372 |
continue |
|---|
| 373 |
try: |
|---|
| 374 |
childsnode = self.get_shapenode(childsname) |
|---|
| 375 |
except: |
|---|
| 376 |
continue |
|---|
| 377 |
|
|---|
| 378 |
|
|---|
| 379 |
if args: |
|---|
| 380 |
f(rootnode, parentnode, childsname, childsnode, *args) |
|---|
| 381 |
else: |
|---|
| 382 |
f(rootnode, parentnode, childsname, childsnode) |
|---|
| 383 |
|
|---|
| 384 |
def compute_shape_bbox(self, id, node, shapename): |
|---|
| 385 |
self.shape_bbox[id] = T.computeBBox(node) |
|---|
| 386 |
return self.shape_bbox[id] |
|---|
| 387 |
def bbox_diagonal_length(self, bbox): |
|---|
| 388 |
x1,y1,x2,y2=(bbox[0], bbox[2], bbox[1], bbox[3]) |
|---|
| 389 |
return sqrt((x1-x2)**2+(y1-y2)**2) |
|---|
| 390 |
def bbox_apply_mat(self, bbox, mat): |
|---|
| 391 |
A=[0,0] |
|---|
| 392 |
B=[0,0] |
|---|
| 393 |
A[0],A[1],B[0],B[1]=(bbox[0], bbox[2], bbox[1], bbox[3]) |
|---|
| 394 |
T.applyTransformToPoint(mat, A) |
|---|
| 395 |
T.applyTransformToPoint(mat, B) |
|---|
| 396 |
return min(A[0], B[0]), max(A[0], B[0]), min(A[1], B[1]), max(A[1], B[1]) |
|---|
| 397 |
|
|---|
| 398 |
def check_shape_size(self, id, mat): |
|---|
| 399 |
'''Returns 1 if the shape is too small to be seen''' |
|---|
| 400 |
bbox = self.bbox_apply_mat(self.shape_bbox[id], mat) |
|---|
| 401 |
if self.bbox_diagonal_length(bbox) < 1: |
|---|
| 402 |
return 1 |
|---|
| 403 |
return 0 |
|---|
| 404 |
|
|---|
| 405 |
def adjust_document_dim(self): |
|---|
| 406 |
bbox = T.computeBBox(self.render_groups) |
|---|
| 407 |
width = bbox[1] - bbox[0] + 100 |
|---|
| 408 |
height = bbox[3] - bbox[2] + 100 |
|---|
| 409 |
translateX = -bbox[0]+50 |
|---|
| 410 |
translateY= -bbox[2]+50 |
|---|
| 411 |
|
|---|
| 412 |
root = self.document.getroot() |
|---|
| 413 |
self.svg_setattr(root, 'width', str(width)) |
|---|
| 414 |
self.svg_setattr(root, 'height', str(height)) |
|---|
| 415 |
|
|---|
| 416 |
T.applyTransformToNode([[1,0,translateX],[0,1,translateY]], self.current_layer) |
|---|
| 417 |
|
|---|
| 418 |
def add_rendergroup(self, id, node, shapename): |
|---|
| 419 |
rgroup = self.svg_appendnewnode(node.getparent(), inkex.addNS('g','svg'), |
|---|
| 420 |
{inkex.addNS('render','gdadin'):'1', |
|---|
| 421 |
inkex.addNS('seed', 'gdadin'): self.options.renderseed} |
|---|
| 422 |
) |
|---|
| 423 |
self.svg_appendnode(rgroup, node) |
|---|
| 424 |
self.render_groups.append(rgroup) |
|---|
| 425 |
|
|---|
| 426 |
def render(self): |
|---|
| 427 |
if self.at_least_one(): return |
|---|
| 428 |
|
|---|
| 429 |
random.seed(self.options.renderseed) |
|---|
| 430 |
|
|---|
| 431 |
self.set_gdadin_shapeids() |
|---|
| 432 |
|
|---|
| 433 |
self.render_stack=[] |
|---|
| 434 |
|
|---|
| 435 |
recursedata = { 'firstid' : None, |
|---|
| 436 |
'mat' : None, |
|---|
| 437 |
'hue' : 0.0, |
|---|
| 438 |
'sat' : 0.0, |
|---|
| 439 |
'bri' : 0.0, |
|---|
| 440 |
'opa' : 0.0, |
|---|
| 441 |
|
|---|
| 442 |
'hf' : -1, |
|---|
| 443 |
'hc' : -1, |
|---|
| 444 |
'sf' : -1, |
|---|
| 445 |
'sc' : -1, |
|---|
| 446 |
'bf' : -1, |
|---|
| 447 |
'bc' : -1, |
|---|
| 448 |
'of' : 0, |
|---|
| 449 |
'oc' : 1 |
|---|
| 450 |
} |
|---|
| 451 |
|
|---|
| 452 |
def doit(id, node, shapename, rdata): |
|---|
| 453 |
self.compute_shape_bbox(id, node, shapename) |
|---|
| 454 |
self.add_rendergroup(id, node, shapename) |
|---|
| 455 |
self.render_shape(id, node, shapename, rdata) |
|---|
| 456 |
self.foreach_selected(doit, (recursedata,)) |
|---|
| 457 |
|
|---|
| 458 |
nshapes=0 |
|---|
| 459 |
maxnshapes=int(self.options.rendermaxshapes) |
|---|
| 460 |
while len(self.render_stack): |
|---|
| 461 |
if maxnshapes and nshapes > maxnshapes: |
|---|
| 462 |
inkex.debug('Maximum number of shapes reached ('+str(maxnshapes)+')') |
|---|
| 463 |
break |
|---|
| 464 |
args=self.render_stack.pop(0) |
|---|
| 465 |
self._render_shape(*args) |
|---|
| 466 |
nshapes+=1 |
|---|
| 467 |
|
|---|
| 468 |
if nshapes: |
|---|
| 469 |
self.adjust_document_dim() |
|---|
| 470 |
|
|---|
| 471 |
def render_shape(self, id, node, shapename, rdata): |
|---|
| 472 |
self.render_stack.append((id, node, shapename, rdata)) |
|---|
| 473 |
|
|---|
| 474 |
def _render_shape(self, id, node, shapename, rdata): |
|---|
| 475 |
|
|---|
| 476 |
if rdata['firstid'] == None: rdata['firstid'] = id |
|---|
| 477 |
|
|---|
| 478 |
|
|---|
| 479 |
nmat = T.parseTransform(node.get('transform')) |
|---|
| 480 |
if rdata['mat']: |
|---|
| 481 |
rdata['mat'] = T.composeTransform(rdata['mat'], nmat) |
|---|
| 482 |
T.writeTransformToNode(rdata['mat'], node) |
|---|
| 483 |
else: |
|---|
| 484 |
rdata['mat'] = nmat |
|---|
| 485 |
|
|---|
| 486 |
if self.check_shape_size(rdata['firstid'], rdata['mat']): |
|---|
| 487 |
return |
|---|
| 488 |
|
|---|
| 489 |
self.foreach_subshape(node, self.call_shape, (rdata,)) |
|---|
| 490 |
|
|---|
| 491 |
def check_rdepth(self, parentnode): |
|---|
| 492 |
pid = self.svg_getattr(parentnode, 'id') |
|---|
| 493 |
try: |
|---|
| 494 |
rdepth_max = int(self.svg_getattr(parentnode, inkex.addNS('rdepth','gdadin'))) |
|---|
| 495 |
except: |
|---|
| 496 |
|
|---|
| 497 |
return 1 |
|---|
| 498 |
|
|---|
| 499 |
if not pid in self.rdepth_counter: |
|---|
| 500 |
self.rdepth_counter[pid]=0 |
|---|
| 501 |
if rdepth_max and self.rdepth_counter[pid] >= rdepth_max-1: |
|---|
| 502 |
return 0 |
|---|
| 503 |
self.rdepth_counter[pid]+=1 |
|---|
| 504 |
return 1 |
|---|
| 505 |
|
|---|
| 506 |
def call_shape(self, rootnode, parentnode, childsname, childsnode, rdata): |
|---|
| 507 |
'''Inside `rootnode', substitute the `parentnode' with |
|---|
| 508 |
`childsnode', but keep the transformation attribute''' |
|---|
| 509 |
|
|---|
| 510 |
if not self.check_rdepth(parentnode): |
|---|
| 511 |
return |
|---|
| 512 |
|
|---|
| 513 |
nrdata = dict(rdata) |
|---|
| 514 |
|
|---|
| 515 |
childid = self.svg_getattr(childsnode, 'id') |
|---|
| 516 |
if childid in self.rdepth_counter: |
|---|
| 517 |
self.rdepth_counter[self.svg_getattr(childsnode, 'id')]+=1 |
|---|
| 518 |
|
|---|
| 519 |
newchild = copy.deepcopy(childsnode) |
|---|
| 520 |
self.svg_setattr(newchild, 'id', self.newid(self.svg_prefixfromtag(childsnode.tag))) |
|---|
| 521 |
try: |
|---|
| 522 |
self.svg_remattr(newchild, inkex.addNS('shape','gdadin')) |
|---|
| 523 |
self.svg_remattr(newchild, 'transform') |
|---|
| 524 |
except: |
|---|
| 525 |
pass |
|---|
| 526 |
|
|---|
| 527 |
|
|---|
| 528 |
|
|---|
| 529 |
pmat = T.parseTransform(self.svg_getattr(parentnode, 'transform')) |
|---|
| 530 |
nrdata['mat'] = T.composeTransform(nrdata['mat'], pmat) |
|---|
| 531 |
|
|---|
| 532 |
|
|---|
| 533 |
try: |
|---|
| 534 |
nrdata['hue']+=float(self.svg_getattr(parentnode, inkex.addNS('hue','gdadin'))) |
|---|
| 535 |
nrdata['sat']+=float(self.svg_getattr(parentnode, inkex.addNS('sat','gdadin'))) |
|---|
| 536 |
nrdata['bri']+=float(self.svg_getattr(parentnode, inkex.addNS('bri','gdadin'))) |
|---|
| 537 |
nrdata['opa']+=float(self.svg_getattr(parentnode, inkex.addNS('opa','gdadin'))) |
|---|
| 538 |
nrdata['hf'] = float(self.svg_getattr(parentnode, inkex.addNS('huefloor','gdadin'))) |
|---|
| 539 |
nrdata['hc'] = float(self.svg_getattr(parentnode, inkex.addNS('hueceil','gdadin'))) |
|---|
| 540 |
nrdata['sf'] = float(self.svg_getattr(parentnode, inkex.addNS('satfloor','gdadin'))) |
|---|
| 541 |
nrdata['sc'] = float(self.svg_getattr(parentnode, inkex.addNS('satceil','gdadin'))) |
|---|
| 542 |
nrdata['bf'] = float(self.svg_getattr(parentnode, inkex.addNS('brifloor','gdadin'))) |
|---|
| 543 |
nrdata['bc'] = float(self.svg_getattr(parentnode, inkex.addNS('briceil','gdadin'))) |
|---|
| 544 |
nrdata['of'] = float(self.svg_getattr(parentnode, inkex.addNS('opafloor','gdadin'))) |
|---|
| 545 |
nrdata['oc'] = float(self.svg_getattr(parentnode, inkex.addNS('opaceil','gdadin'))) |
|---|
| 546 |
except: |
|---|
| 547 |
pass |
|---|
| 548 |
|
|---|
| 549 |
|
|---|
| 550 |
if nrdata['hue'] or nrdata['sat'] or nrdata['bri'] or nrdata['opa']: |
|---|
| 551 |
self.apply_hsbo(newchild, parentnode, nrdata) |
|---|
| 552 |
hsbo = 1 |
|---|
| 553 |
else: |
|---|
| 554 |
hsbo = 0 |
|---|
| 555 |
|
|---|
| 556 |
|
|---|
| 557 |
if not hsbo: |
|---|
| 558 |
for sn in self.svg_subnodeslist(newchild): |
|---|
| 559 |
if not self.svg_getattr(sn, inkex.addNS('shape','gdadin')): |
|---|
| 560 |
self.xlinkify(newchild, sn) |
|---|
| 561 |
|
|---|
| 562 |
self.svg_appendnode(rootnode.getparent(), newchild) |
|---|
| 563 |
if self.svg_getattr(rootnode, 'id') != nrdata['firstid']: |
|---|
| 564 |
self.svg_remnode(parentnode) |
|---|
| 565 |
|
|---|
| 566 |
|
|---|
| 567 |
self.render_shape(None, newchild, None, nrdata) |
|---|
| 568 |
|
|---|
| 569 |
def xlinkify(self, node, subnode): |
|---|
| 570 |
id = self.svg_getattr(subnode, 'id') |
|---|
| 571 |
self.svg_appendnewlink(node, id) |
|---|
| 572 |
self.svg_remnode(subnode) |
|---|
| 573 |
|
|---|
| 574 |
if __name__ == '__main__': |
|---|
| 575 |
e = Gdadin() |
|---|
| 576 |
e.affect() |
|---|