Wild Witch Project - Um game que você nunca viu

Neste jogo você precisa ajudar uma bruxa adolescente a salvar seu mundo da Mortífera Bunda Assassina do Espaço Sideral

Mais um fruto, ferramenta de simetria

Motivado pela preguiça e pelo fato de mais tarde ter que fazer o mesmo esforço em outros elementos do jogo, eu sentei o dedo no Python nessa ultima sexta.
Basicamente este script pega o objeto selecionado e verifica se ele se encontra transpondo as bordas da imagem que irá ser rendida. Como a camera é isométrica e em escala 2x esses limites são de -1 até 1, ou seja, o sistema de cordenadas padrão em uma tela de jogo 3D. Quando o objeto sangra o limite o script o duplica e o coloca na aresta oposta do quadrado. Pode-se pensar que é facil fazer a mão, mas esperimente fazer issu sem ter que fazer conta na calculadora. Assim, surge o terceiro filho do projeto, uma pequena ferramenta para ajudar nas texturas de tile em normalmap.
Observe que o funcionamento deu certinho no resultado final não se percebe emenda.
Não achei nada parecido nas ferramentas ja inclusas, tão pouco tive passiênia para procurar, ha coisas tão específicas que é melhor agente por a mão na massa mesmo.

O código funciona apenas com a biblioteca nativa do Blender, sem necessidade de instalar o Python em si. E não sofreu otimização, ainda apresenta falhas quando se seleciona multiplos objetos, mas já reduz em muito qualquer trabalho.
import Blender
from Blender import *

def simetrize( ob ):
print ob.name
loc = ob.getLocation()
box = ob.getBoundBox()
for b in box: print b

#checa bounds independente da rotacao
minX = 10000
maxX = -10000
minY = 10000
maxY = -10000
print "#" * 8
for v in box:
if (v[0]<minX): minX = v[0]
if (v[0]>maxX): maxX = v[0]
if (v[1]<minY): minY = v[1]
if (v[1]>maxY): maxY = v[1]
print " %s %s %s %s " % (minX, maxX, minY, maxY )

#fora do box 2x2 ?
if (minX<-1 or maxX>1 or minY<-1 or maxY>1):
if (minX<-1 or maxX>1) and (minY<-1 or maxY>1):
#solucao p 2 eixos
if (loc[0]<0):
mvX = -(-2 - loc[0])
else:
mvX = -1+(-1 + loc[0])
if (loc[1]<0):
mvY = -(-2 - loc[1])
else:
mvY = -1+(-1 + loc[1])
#duplica
Object.Duplicate()
sel = Object.GetSelected()[0]
atualLoc = sel.getLocation()
sel.setLocation(mvX, atualLoc[1], atualLoc[2])
#duplica
Object.Duplicate()
sel = Object.GetSelected()[0]
sel.setLocation(atualLoc[0], mvY, atualLoc[2])
#duplica
Object.Duplicate()
sel = Object.GetSelected()[0]
sel.setLocation(mvX, mvY, atualLoc[2])
ob.select(1)
else:
#solucao para 1 unico eixo
#analiza eixo x
if (minX<-1 or maxX>1):
if (loc[0]<0):
mv = -(-2 - loc[0])
else:
mv = -1+(-1 + loc[0])
#duplica para eixo X
Object.Duplicate()
sel = Object.GetSelected()[0]
atualLoc = sel.getLocation()
sel.setLocation(mv, atualLoc[1], atualLoc[2])
ob.select(1)
#analiza euxo y
if (minY<-1 or maxY>1):
if (loc[1]<0):
mv = -(-2 - loc[1])
else:
mv = -1+(-1 + loc[1])
Object.Duplicate()
sel = Object.GetSelected()[0]
atualLoc = sel.getLocation()
sel.setLocation(atualLoc[0], mv, atualLoc[2])
ob.select(1)
Blender.Redraw()

list = Object.GetSelected()
for ob in list:
simetrize( ob )