Scripts updated:

- Jean-Michel Soler: paths import -- ai and svg modules;
- Jean-Baptiste PERIN: bvh to armatures (note: should not work until we re-wrap armatures in bpython);
- Campbell Barton: obj importer.

Thanks guys, excuse me the delay.

- tiny doc update.
This commit is contained in:
Willian Padovani Germano 2005-07-11 02:41:08 +00:00
parent c015d52d76
commit 399f670ac7
5 changed files with 411 additions and 243 deletions

@ -1,19 +1,32 @@
"""
#----------------------------------------------
# (c) jm soler juillet 2004, released under Blender Artistic Licence
# (c) jm soler juillet 2004-juin 2005,
# released under Blender Artistic Licence
# for the Blender 2.34 Python Scripts Bundle.
#----------------------------------------------
# Page officielle :
# http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_import_ai.htm
# http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_import_ai_en.htm
# Communiquer les problemes et erreurs sur:
# http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender
#
# 0.1.1 : 2004/08/03, bug in boudingbox reading when Value are negative
# 0.1.2 : 2005/06/12, gmove tranformation properties
# 0.1.3 : 2005/06/25, added a __name__ test to use the script alone
# 0.1.4 : 2005/06/25, closepath improvements
# 0.1.5 : 2005/06/25, ...
# 0.1.6 : 2005/06/26, warning for compacted file
compatibility increased up to AI 10.0 plain text
# 0.1.7 : 2005/06/25, two more closepath improvements
#
"""
SHARP_IMPORT=0
SCALE=1
DEVELOPPEMENT=0
NOTHING_TODO=1
AI_VERSION=''
GSTACK = []
GSCALE = []
GTRANSLATE = []
import sys
#oldpath=sys.path
@ -62,11 +75,11 @@ def filtreFICHIER(nom):
t=f.readlines()
f.close()
if len(t)>1:
if len(t)>1 and t[0].find('EPSF')==-1:
return t
else:
name = "OK?%t| Not a valid file or an empty file ... " # if no %xN int is set, indices start from 1
result = Draw.PupMenu(name)
result = Blender.Draw.PupMenu(name)
return 'false'
@ -85,6 +98,7 @@ class Bez:
def __init__(self):
self.co=[]
self.ha=[0,0]
self.tag=''
class ITEM:
def __init__(self):
@ -124,6 +138,23 @@ n0=0
#=====================================================================
CP=[0.0,0.0] #currentPoint
# modifs 12/06/2005
#=====================================================================
#====================== current transform ============================
#=====================================================================
class transform:
def __init__(self,matrix=[1,0,01],x=0.0,y=0.0):
self.matrix=matrix[:]
self.xy=[x,y]
def G_move(l,a):
global GSCALE, GTRANSLATE, GSTACK
#print GSCALE, GTRANSLATE, GSTACK
return str((float(l)+GTRANSLATE[a]+GSTACK[-1].xy[a])*GSCALE[a])
# modifs 12/06/2005
#=====================================================================
#===== to compare last position to the original move to displacement =
#===== needed for cyclic efinition =================================
@ -142,6 +173,7 @@ def Open_GEOfile(dir,nom):
Blender.Load(dir+nom+'OOO.obj', 1)
BO=Blender.Object.Get()
BO[-1].RotY=0.0
BO[-1].RotX=1.57
BO[-1].makeDisplayList()
Blender.Window.RedrawAll()
else:
@ -166,20 +198,23 @@ def create_GEOtext(courbes):
t.append(courbes.matrix+'\n')
for k in courbes.ITEM.keys():
t.append("%s\n"%courbes.ITEM[k].type)
t.append("%s %s \n"%(courbes.ITEM[k].pntsUV[0],courbes.ITEM[k].pntsUV[1]))
t.append("%s %s \n"%(courbes.ITEM[k].resolUV[0],courbes.ITEM[k].resolUV[1]))
t.append("%s %s \n"%(courbes.ITEM[k].orderUV[0],courbes.ITEM[k].orderUV[1]))
t.append("%s %s \n"%(courbes.ITEM[k].flagUV[0],courbes.ITEM[k].flagUV[1]))
if len(courbes.ITEM[k].beziers_knot)>1 :
t.append("%s\n"%courbes.ITEM[k].type)
t.append("%s %s \n"%(courbes.ITEM[k].pntsUV[0],courbes.ITEM[k].pntsUV[1]))
t.append("%s %s \n"%(courbes.ITEM[k].resolUV[0],courbes.ITEM[k].resolUV[1]))
t.append("%s %s \n"%(courbes.ITEM[k].orderUV[0],courbes.ITEM[k].orderUV[1]))
t.append("%s %s \n"%(courbes.ITEM[k].flagUV[0],courbes.ITEM[k].flagUV[1]))
flag =courbes.ITEM[k].flagUV[0]
flag =courbes.ITEM[k].flagUV[0]
for k2 in range(flag,len(courbes.ITEM[k].beziers_knot)):
k1 =courbes.ITEM[k].beziers_knot[k2]
t.append("%4f 0.0 %4f \n"%(float(k1.co[0])/SCALE,float(k1.co[1])/SCALE))
t.append("%4f 0.0 %4f \n"%(float(k1.co[2])/SCALE,float(k1.co[3])/SCALE))
t.append("%4f 0.0 %4f \n"%(float(k1.co[4])/SCALE,float(k1.co[5])/SCALE))
t.append(str(k1.ha[0])+' '+str(k1.ha[1])+'\n')
for k2 in range(len(courbes.ITEM[k].beziers_knot)):
#print k2
k1 =courbes.ITEM[k].beziers_knot[k2]
t.append("%4f 0.0 %4f \n"%(float(k1.co[2])/SCALE,float(k1.co[3])/SCALE))
t.append("%4f 0.0 %4f \n"%(float(k1.co[4])/SCALE,float(k1.co[5])/SCALE))
t.append("%4f 0.0 %4f \n"%(float(k1.co[0])/SCALE,float(k1.co[1])/SCALE))
t.append(str(k1.ha[0])+' '+str(k1.ha[1])+'\n')
return t
def save_GEOfile(dir,nom,t):
@ -195,18 +230,17 @@ def save_GEOfile(dir,nom,t):
#=====================================================================
def mouvement_vers(l,n0,CP):
if n0 in courbes.ITEM.keys():
#if test_egalitedespositions(courbes.ITEM[n0].Origine,CP):
# courbes.ITEM[n0].flagUV[0]=1
n0+=1
else:
CP=[l[-3].replace('d',''),l[-2]]
#i=
CP=[l[-3].replace('d',''),l[-2]]
courbes.ITEM[n0]=ITEM()
courbes.ITEM[n0].Origine=[l[-3].replace('d',''),l[-2]]
B=Bez()
B.co=[CP[0],CP[1],CP[0],CP[1],CP[0],CP[1]]
B.ha=[0,0]
B.ha=[0,0]
B.tag=l[-1]
courbes.ITEM[n0].beziers_knot.append(B)
return courbes,n0,CP
@ -214,64 +248,75 @@ def mouvement_vers(l,n0,CP):
def courbe_vers_c(l,l2, n0,CP): #c,C
B=Bez()
B.co=[l[2],l[3],l[4],l[5],l[0],l[1]]
if len(courbes.ITEM[n0].beziers_knot)==1:
CP=[l[0],l[1]]
courbes.ITEM[n0].Origine=[l[0],l[1]]
if l[-1]=='C':
B.ha=[2,2]
else:
B.ha=[0,0]
B.co=[l[4],l[5],l[2],l[3],l[4],l[5]]
B.tag=l[-1]
B.ha=[0,0]
BP=courbes.ITEM[n0].beziers_knot[-1]
BP.co[0]=l[0]
BP.co[1]=l[1]
courbes.ITEM[n0].beziers_knot.append(B)
if len(l2)>1 and l2[-1] in Actions.keys():
B.co[-2]=l2[0]
B.co[-1]=l2[1]
else:
#B.co[-2]=courbes.ITEM[n0].beziers_knot[-1].co[0]
#B.co[-1]=courbes.ITEM[n0].beziers_knot[-].co[1]
B.co[-2]=CP[0]
B.co[-1]=CP[1]
CP=[B.co[4],B.co[5]]
return courbes,n0,CP
def courbe_vers_v(l,n0,CP): #v-V
B=Bez()
B.tag=l[-1]
B.co=[l[2],l[3],l[0],l[1],l[2],l[3]]
if l[-1]=='V':
B.ha=[2,2]
else:
B.ha=[0,0]
courbes.ITEM[n0].beziers_knot.append(B)
CP=[l[0],l[1]]
B.ha=[0,0]
courbes.ITEM[n0].beziers_knot.append(B)
CP=[B.co[4],B.co[5]]
return courbes,n0,CP
def courbe_vers_y(l,n0,CP): #y
B=Bez()
B.co=[l[2],l[3],l[0],l[1],l[2],l[3]]
if l[-1]=='Y':
B.ha=[2,2]
else:
B.ha=[0,0]
B.tag=l[-1]
B.co=[l[2],l[3],l[2],l[3],l[2],l[3]]
B.ha=[0,0]
BP=courbes.ITEM[n0].beziers_knot[-1]
BP.co[0]=l[0]
BP.co[1]=l[1]
courbes.ITEM[n0].beziers_knot.append(B)
CP=[l[2],l[3]]
CP=[B.co[4],B.co[5]]
return courbes,n0,CP
def ligne_tracee_l(l,n0,CP):
B=Bez()
B.tag=l[-1]
B.co=[l[0],l[1],l[0],l[1],l[0],l[1]]
if l[-1]=='L':
B.ha=[2,2]
else:
B.ha=[0,0]
courbes.ITEM[n0].beziers_knot.append(B)
CP=[l[0],l[1]]
B.ha=[0,0]
BP=courbes.ITEM[n0].beziers_knot[-1]
courbes.ITEM[n0].beziers_knot.append(B)
CP=[B.co[4],B.co[5]]
return courbes,n0,CP
def ligne_fermee(l,n0,CP):
courbes.ITEM[n0].flagUV[0]=1
if len(courbes.ITEM[n0].beziers_knot)>1:
BP=courbes.ITEM[n0].beziers_knot[-1]
BP0=courbes.ITEM[n0].beziers_knot[0]
if BP.tag not in ['l','L']:
BP.co[0]=BP0.co[0] #4-5 point prec
BP.co[1]=BP0.co[1]
del courbes.ITEM[n0].beziers_knot[0]
return courbes,n0,CP
Actions= { "C" : courbe_vers_c,
"c" : courbe_vers_c,
"V" : courbe_vers_v,
@ -280,13 +325,25 @@ Actions= { "C" : courbe_vers_c,
"y" : courbe_vers_y,
"m" : mouvement_vers,
"l" : ligne_tracee_l,
"L" : ligne_tracee_l}
"L" : ligne_tracee_l,
"f" : ligne_fermee,
"b" : ligne_fermee,
"s" : ligne_fermee,
"N" : ligne_fermee,
}
TAGcourbe=Actions.keys()
def pik_pattern(t,l):
global npat, PATTERN, BOUNDINGBOX
while t[l].find('%%EndSetup')!=0:
global npat, PATTERN, BOUNDINGBOX, AI_VERSION
while t[l].find('%%EndSetup')!=0:
if t[l].find('%%Creator: Adobe Illustrator(R)')!=-1:
print t[l]
AI_VERSION=t[l].split()[-1]
print AI_VERSION
if t[l].find('%%BoundingBox:')!=-1:
t[l]=t[l][t[l].find(':')+1:]
l0=t[l].split()
@ -312,7 +369,7 @@ def pik_pattern(t,l):
return 1,l
def scan_FILE(nom):
global CP, courbes, SCALE
global CP, courbes, SCALE, NOTHING_TODO
dir,name=split(nom)
name=name.split('.')
n0=0
@ -331,10 +388,19 @@ def scan_FILE(nom):
if not do:
do,l=pik_pattern(t,l)
#print 'len(t)',len(t)
t[l].replace('\n','')
t[l].replace('\n','')
if t[l].find('%%EOF')==0:
break
if t[l][0]!='%':
l0=t[l].split()
#print l0
if l0[0][0] in ['F','f','N','n','B','b']:
l3=l0[0][0]
courbes,n0,CP=Actions[l3](l3,n0,CP)
l0[0]=l0[1:]
if l0[-1] in TAGcourbe:
NOTHING_TODO=0
if l0[-1] in ['C','c']:
l2=t[l+1].split()
courbes,n0,CP=Actions[l0[-1]](l0,l2,n0,CP)
@ -342,15 +408,12 @@ def scan_FILE(nom):
courbes,n0,CP=Actions[l0[-1]](l0,n0,CP)
l=l+1; #print l
t=[]
courbes.number_of_items=len(courbes.ITEM.keys())
courbes.number_of_items=len(courbes.ITEM.keys())
for k in courbes.ITEM.keys():
courbes.ITEM[k].pntsUV[0] =len(courbes.ITEM[k].beziers_knot)
if test_egalitedespositions(courbes.ITEM[k].Origine,
[courbes.ITEM[k].beziers_knot[-1].co[-2],
courbes.ITEM[k].beziers_knot[-1].co[-1]]):
courbes.ITEM[k].flagUV[0]=1
courbes.ITEM[k].pntsUV[0] -=1
courbes.ITEM[k].pntsUV[0] =len(courbes.ITEM[k].beziers_knot)
if courbes.number_of_items>0:
if len(PATTERN.keys() )>0:
@ -375,8 +438,12 @@ def scan_FILE(nom):
# et de documenter les variables Window.FileSelector
#=========================================================
def fonctionSELECT(nom):
global NOTHING_TODO,AI_VERSION
scan_FILE(nom)
if NOTHING_TODO==1:
warning = "AI %s compatible file "%AI_VERSION+" but nothing to do ? %t| Perhaps a compacted file ... "
NOTHING = Blender.Draw.PupMenu(warning)
if DEVELOPPEMENT==1:
if __name__=="__main__":
Blender.Window.FileSelector (fonctionSELECT, 'SELECT AI FILE')
#sys.path=oldpath

@ -1,10 +1,12 @@
"""
SVG 2 OBJ translater, 0.3.1
(c) jm soler juillet/novembre 2004, released under Blender Artistic Licence
for the Blender 2.34/33 Python Scripts Bundle.
SVG 2 OBJ translater, 0.3.3
(c) jm soler juillet/novembre 2004-juin 2005,
# released under Blender Artistic Licence
for the Blender 2.37/36/35/34/33 Python Scripts Bundle.
#---------------------------------------------------------------------------
# Page officielle :
# http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_import_svg.htm
# http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_import_svg_en.htm
# Communiquer les problemes et erreurs sur:
# http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender
#---------------------------------------------------------------------------
@ -72,9 +74,18 @@ Changelog:
0.2.6 : - correction for illustrator 10 SVG
0.2.7 : - correction for inskape 0.40 cvs SVG
0.2.8 : - correction for inskape plain SVG
0.3 : - transform properties added
0.3 : - reading of the transform properties added :
translate
0.3.1 : - compatibility restored with gimp
0.3.2 : - transform properties added (june, 15-16):
scale,
rotate,
matrix,
skew
- added a test on __name__ to load the script
outside from the blender menu
0.3.3 : - controle du contenu des transformation de type matrix
0.3.4 : - restructuration de la lecture des donnes paths (19/06/05)
==================================================================================
=================================================================================="""
@ -85,8 +96,9 @@ DEBUG =0 #print
DEVELOPPEMENT=0
import sys
#oldpath=sys.path
from math import cos,sin,tan
import Blender
from Blender import Mathutils
BLversion=Blender.Get('version')
try:
@ -275,6 +287,7 @@ def save_GEOfile(dir,nom,t):
def filtre_DATA(c,D,n):
global DEBUG,TAGcourbe
#print 'c',c,'D',D,'n',n
l=[]
if len(c[0])==1 and D[c[1]+1].find(',')!=-1:
for n2 in range(1,n+1):
@ -372,7 +385,8 @@ def courbe_vers_t(c,D,n0,CP): #T
def courbe_vers_c(c, D, n0,CP): #c,C
l=filtre_DATA(c,D,3)
#print l, c, CP
print '\n','l',l, 'c',c,'CP', CP
if c[0]=='c':
l=["%4s"%(float(l[0])+float(CP[0])),
@ -437,12 +451,11 @@ def ligne_tracee_l(c, D, n0,CP): #L,l
def ligne_tracee_h(c,D,n0,CP): #H,h
#print '|',c[0],'|',len(c[0]),' --> ',CP[0]
#print 'D :',D,' \n CP :', CP
if c[0]=='h':
l=["%4s"%(float(D[c[1]+1])+float(CP[0])),
"%4s"%float(CP[1])]
l=["%4s"%(float(D[c[1]+1])+float(CP[0])),"%4s"%float(CP[1])]
else:
l=["%4s"%float(D[c[1]+1]),
"%4s"%float(CP[1])]
l=["%4s"%float(D[c[1]+1]),"%4s"%float(CP[1])]
B=Bez()
B.co=[l[0],l[1],l[0],l[1],l[0],l[1]]
B.ha=[0,0]
@ -511,32 +524,22 @@ def get_content(val,t0):
t=t[t.find(' '+val+'="')+len(' '+val+'="'):]
val=t[:t.find('"')]
t=t[t.find('"'):]
#----------------------------------------------------------------
#print t[:10], val
#wait=raw_input('wait:' )
return t0,val
else:
return t0,0
def get_tag(val,t):
t=t[t.find('<'+val):]
val=t[:t.find('>')+1]
t=t[t.find('>')+1:]
t=t[t.find('>')+1:]
if DEBUG==3 : print t[:10], val
return t,val
def get_data(val,t):
t=t[t.find('<'+val):]
val=t[:t.find('</'+val+'>')]
t=t[t.find('</'+val+'>')+3+len(val):]
if DEBUG==3 : print t[:10], val
return t,val
def get_val(val,t):
@ -561,6 +564,8 @@ def get_val(val,t):
d=0.0
return d
def get_BOUNDBOX(BOUNDINGBOX,SVG,viewbox):
if viewbox==0:
h=get_val('height',SVG)
@ -579,88 +584,152 @@ def get_BOUNDBOX(BOUNDINGBOX,SVG,viewbox):
return BOUNDINGBOX
# 0.2.8 : - correction for inskape 0.40 cvs SVG
def repack_DATA(DATA):
def repack_DATA2(DATA):
for d in Actions.keys():
DATA=DATA.replace(d,d+' ')
return DATA
def unpack_DATA(DATA):
DATA[0]=DATA[0].replace('-',',-')
def wash_DATA(ndata):
print 'ndata', ndata, len(ndata)
if ndata!='':
while ndata[0]==' ':
ndata=ndata[1:]
while ndata[-1]==' ':
ndata=ndata[:-1]
if ndata[0]==',':ndata=ndata[1:]
if ndata[-1]==',':ndata=ndata[:-1]
if ndata.find('-')!=-1 and ndata[ndata.find('-')-1] not in [' ',' ']:
ndata=ndata.replace('-',',-')
ndata=ndata.replace(',,',',')
ndata=ndata.replace(' ',',')
ndata=ndata.split(',')
for n in ndata :
if n=='' : ndata.remove(n)
return ndata
# 0.3.4 : - restructuration de la lecture des donnes paths
def list_DATA(DATA):
"""
cette fonction doit retourner une liste proposant
une suite correcte de commande avec le nombre de valeurs
attendu pour chacune d'entres-elles .
Par exemple :
d="'M0,14.0 z" devient ['M','0.0','14.0','z']
"""
while DATA.count(' ')!=0 :
DATA=DATA.replace(' ',' ')
tagplace=[]
DATA=DATA.replace('\n','')
for d in Actions.keys():
DATA[0]=DATA[0].replace(d,', '+d+',')
b1=0
b2=len(DATA)
while DATA.find(d,b1,b2)!=-1 :
#print d, b1
tagplace.append(DATA.find(d,b1,b2))
b1=DATA.find(d,b1,b2)+1
tagplace.sort()
tpn=range(len(tagplace)-1)
DATA2=[]
DATA[0]=DATA[0].replace(',,',',')
if DATA[0][0]==',':DATA[0]=DATA[0][1:]
if DATA[0][-1]==',':DATA[0]=DATA[0][:-1]
for t in tpn:
DATA2.append(DATA[tagplace[t]:tagplace[t]+1])
print DATA2[-1]
DATA[0]=DATA[0].replace('\n','')
DATA[0]=DATA[0].replace('\t','')
DATA[0]=DATA[0].split(',')
ndata=DATA[tagplace[t]+1:tagplace[t+1]]
if DATA2[-1] not in ['z','Z'] :
ndata=wash_DATA(ndata)
for n in ndata : DATA2.append(n)
DATA2.append(DATA[tagplace[t+1]:tagplace[t+1]+1])
print DATA2[-1]
if DATA2[-1] not in ['z','Z'] and len(DATA)-1>=tagplace[t+1]+1:
ndata=DATA[tagplace[t+1]+1:-1]
ndata=wash_DATA(ndata)
for n in ndata : DATA2.append(n)
D2=[]
D1=DATA[0]
for cell in range(len(D1)):
if D1[cell] in Actions.keys():
D2.append(D1[cell])
n=1
if D1[cell] not in ['h','v','H','V','a','A']:
while cell+n+1<len(D1) and (D1[cell+n] not in Actions.keys()):
D2.append(D1[cell+n]+','+D1[cell+n+1])
n+=2
elif D1[cell] in ['h','v','H','V']:
while cell+n+1<len(D1) and (D1[cell+n] not in Actions.keys()):
D2.append(D1[cell+n])
n+=1
elif D1[cell] in ['a','A']:
#(rx ry rotation-axe-x drapeau-arc-large drapeau-balayage x y)
#150,150 0 1,0 150,-150
D2.append(D1[cell+n]+','+D1[cell+n+1])
D2.append(D1[cell+n+2])
D2.append(D1[cell+n+3]+','+D1[cell+n+4])
D2.append(D1[cell+n+5]+','+D1[cell+n+6])
n+=7
return D2
return DATA2
def translate(a,b):
return [a,b]
# 0.3
def translate(tx,ty):
return [1, 0, tx], [0, 1, ty],[0,0,1]
# 0.3.2
def scale(sx,sy):
return [sx, 0, 0], [0, sy, 0],[0,0,1]
# 0.3.2
def rotate(a):
return [cos(a), -sin(a), 0], [sin(a), cos(a),0],[0,0,1]
# 0.3.2
def skewX(a):
return [1, tan(a), 0], [0, 1, 0],[0,0,1]
# 0.3.2
def skewX(a):
return [1, 0, 0], [tan(a), 1 , 0],[0,0,1]
# 0.3.2
def matrix(a,b,c,d,e,f):
return [a,b,e],[c,d,f],[0,0,1]
# 0.3.3
def controle_CONTENU(val,t):
"""
une matrice peut s'ecrire : matrix(a,b,c,d,e,f) ou matrix(a b c d e f)
"""
if val.find('matrix') and t.find(val+'(')!=-1 and t.find(val+',')==-1:
t0=t[t.find(val+'(')+len(val+'('):]
t0=t0[:t0.find(')')]
val=t0[:]
while val.find(' ')!=-1:
val=val.replace(' ',' ')
val=val.replace(' ',',')
t=t.replace(t0,val)
return val
else:
return -1
# 0.3
def get_TRANSFORM(STRING):
STRING,TRANSFORM=get_content('transform',STRING)
if TRANSFORM.find('translate')!=-1:
exec "TRANSFORM=%s"%TRANSFORM
return TRANSFORM
#print 'TRANSFORM 1 :', TRANSFORM
for t in ['translate','scale','rotate','matrix','skewX','skewY'] :
if TRANSFORM.find(t)!=-1 and TRANSFORM.count('(')==1:
#print 'TRANSFORM 2 :', TRANSFORM
print ' getcontent ', t,' ',controle_CONTENU(t,TRANSFORM)
exec "a,b,c=%s;T=Mathutils.Matrix(a,b,c)"%TRANSFORM
return T
# 0.3
def G_move(l,a,t):
if a!=-1:
return str(float(l)+float(t[a]))
if a==0:
v=Mathutils.Vector([float(l[0]),float(l[1]),1.0])
v=Mathutils.MatMultVec(t, v)
return str(v[0]),str(v[1])
else :
#print 'l', l ,'t', t, 'a', a
l=l.split(',')
return str(float(l[0])+float(t[0]))+','+str(float(l[1])+float(t[1]))
v=Mathutils.Vector([float(l[0]),float(l[1]),1.0])
v=Mathutils.MatMultVec(t, v)
return str(v[0])+','+str(v[1])
# 0.3
def transform_DATA(D1,TRANSFORM):
for cell in range(len(D1)):
if D1[cell] in TAGtransform:
try:
if D1[cell] == 'C': #6 valeurs
D1[cell+1]=G_move(D1[cell+1],0,TRANSFORM)
D1[cell+2]=G_move(D1[cell+2],1,TRANSFORM)
D1[cell+3]=G_move(D1[cell+3],0,TRANSFORM)
D1[cell+4]=G_move(D1[cell+4],1,TRANSFORM)
D1[cell+5]=G_move(D1[cell+5],0,TRANSFORM)
D1[cell+6]=G_move(D1[cell+6],1,TRANSFORM)
elif D1[cell] in ['M','L','T']: #2 valeurs
D1[cell+1]=G_move(D1[cell+1],0,TRANSFORM)
D1[cell+2]=G_move(D1[cell+2],1,TRANSFORM)
elif D1[cell] == ['S','Q']: #4 valeurs
D1[cell+1]=G_move(D1[cell+1],0,TRANSFORM)
D1[cell+2]=G_move(D1[cell+2],1,TRANSFORM)
D1[cell+3]=G_move(D1[cell+3],0,TRANSFORM)
D1[cell+4]=G_move(D1[cell+4],1,TRANSFORM)
except :
if D1[cell+1].find(',')==-1:
if D1[cell] in ['C', 'S','Q', 'M','L','T',]: #2 valeurs
D1[cell+1],D1[cell+2]=G_move([D1[cell+1],D1[cell+2]],0,TRANSFORM)
if D1[cell] in ['C', 'S','Q'] :
D1[cell+3],D1[cell+4]=G_move([D1[cell+3],D1[cell+4]],0,TRANSFORM)
if D1[cell] in ['C']:
D1[cell+5],D1[cell+6]=G_move([D1[cell+5],D1[cell+6]],0,TRANSFORM)
else :
if D1[cell] == 'C': #6 valeurs
D1[cell+1]=G_move(D1[cell+1],-1,TRANSFORM)
D1[cell+2]=G_move(D1[cell+2],-1,TRANSFORM)
@ -685,8 +754,9 @@ def format_PATH(t,TRANSFORM):
if PATH.find(' transform="')!=-1:
TRANSFORM2=get_TRANSFORM(PATH)
TRANSFORM[0]+=TRANSFORM2[0]
TRANSFORM[1]+=TRANSFORM2[1]
# 0.3.3
TRANSFORM=TRANSFORM*TRANSFORM2
#TRANSFORM[1]+=TRANSFORM2[1]
tagTRANSFORM+=1
if PATH.find(' id="')!=-1:
@ -703,29 +773,9 @@ def format_PATH(t,TRANSFORM):
if PATH.find(' d="')!=-1:
PATH,D=get_content('d',PATH)
# 0.2.8 : - correction for inskape plain SVG
if D.find(',')==-1:
D=repack_DATA(D)
# 0.2.8 : end
D=D.split(' ')
D=list_DATA(D)
if tagTRANSFORM in [1,2] : D=transform_DATA(D,TRANSFORM)
try:
while D.index(''):
del D[D.index('')]
except:
pass
if len(D)==1 or len(D[0])>1 :
D1=[]
for D0 in D:
D1+=unpack_DATA([D0])[:]
D=D1
return t,D
@ -760,22 +810,25 @@ def scan_FILE(nom):
while t.find('<g')!=-1:
t,G=get_data('g',t)
TRANSFORM=[0.0,0.0]
TRANSFORM=Mathutils.Matrix([1.0,0.0,0.0],[0.0,1.0,0.0],[0,0,1])
tagTRANSFORM=0
if G.find(' transform="')!=-1:
TRANSFORM=get_TRANSFORM(G)
tagTRANSFORM=1
while G.find('path')!=-1:
G,D=format_PATH(G,TRANSFORM)
#print D
cursor=0
for cell in D:
if DEBUG==2 : print 'cell : ',cell ,' --'
if len(cell)>=1 and cell[0] in TAGcourbe:
courbes,n0,CP=Actions[cell]([cell,cursor], D, n0,CP)
cursor+=1
# 0.3.1
while t.find('path')!=-1:
TRANSFORM=[0.0,0.0]
TRANSFORM=Mathutils.Matrix([1.0,0.0,0.0],[0.0,1.0,0.0],[0,0,1])
t,D=format_PATH(t,TRANSFORM)
cursor=0
for cell in D:

@ -1,24 +1,24 @@
#!BPY
"""
Name: 'BVH Empties to Armature'
Blender: 234
Blender: 237
Group: 'Animation'
Tooltip: 'Create Armature from Empties created by the BVH import script'
Tooltip: 'Create Armature from Empties created by BVH importer'
"""
__author__ = " Jean-Baptiste PERIN (jb_perin(at)yahoo.fr)"
__url__ = ("blender", "elysiun",
"BVH 2 ARMATURE, http://www.zoo-logique.org/3D.Blender/index.php3?zoo=dld&rep=zip ",
"Communicate problems and errors, http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender")
__version__ = "2.0"
__version__ = "2.2"
__bpydoc__ = """ BVH2ARM.py v2.0
__bpydoc__ = """ BVH2ARM.py v2.2
Script for generating armature from BVH empties.
This script generates an armature and makes bones
follow empties created by the BVH import script.
Script for generating armature on BVH empties.
This script generates an armature and make bones
follow empties created by Blender BVH import script.
Usage:<br>
- Import a bvh in Blender (File->Import->BVH);<br>
- Launch this script (Alt-P);<br>
@ -26,13 +26,13 @@ Usage:<br>
"hipbonename": the name of the main bone;<br>
"startframe": the first frame of your anim;<br>
"endframe": the last frame of your anim;<br>
"decimation": the frequency (in number of frames) to which the armature is updated;<br>
"scale": to size the created armature.
"decimation": the frequency (in number of frame) to which the armature is updated;<br>
"scale" to size the created armature.<br>
- Press "Create Armature".
"""
#----------------------------------------------
# (c) Jean-Baptiste PERIN octobre 2004, released under Blender Artistic Licence
# (c) Jean-Baptiste PERIN june 2005, released under Blender Artistic Licence
# for the Blender 2.34-2.36 Python Scripts Bundle.
#----------------------------------------------
@ -346,7 +346,7 @@ def f_createBone (armData, empty, bone, empties):
dicBoneRestInvEmpRest[b.getName()]=b.getRestMatrix()*invmatrice*invmatricet
dicEmpRestInvBoneRest[b.getName()]=matrice*invbonerest
dicBone[b.getName()]=b
print "Ajout de ", b.getName()," au dictionnaire"
#print "Ajout de ", b.getName()," au dictionnaire"
f_createBone(armData, ch, b, empties)
@ -415,7 +415,7 @@ def f_createArmature (rootEmpty, empties, armData):
dicBoneRestInvEmpRest[b.getName()]=b.getRestMatrix()*invmatrice*invmatricet
dicEmpRestInvBoneRest[b.getName()]=matrice*invbonerest
dicBone[b.getName()]=b
print "Ajout de ", b.getName()," au dictionnaire"
#print "Ajout de ", b.getName()," au dictionnaire"
f_createBone(armData, ch, b, empties)
@ -632,26 +632,22 @@ def button_event(evt):
hipbonename = HBName.val
framedecimation = FrameDecimation.val
scalef= eval(str(ScaleF.val))
print "scalef = ", scalef
#print "scalef = ", scalef
if startframe>=endframe:
Msg = 'Start frame must be lower than End frame'
Blender.Draw.PupMenu("ERROR: %s" % Msg)
else:
ob = getEmpty(hipbonename)
if (ob!=None):
if ob.getParent()!=None:
Msg = 'Empty '+hipbonename+ ' is not a root bone.'
Blender.Draw.PupMenu("ERROR: %s" % Msg)
else:
if (0.0 > scalef):
Msg = 'Scale factor must be greater than 0'
Blender.Draw.PupMenu("ERROR: %s" % Msg)
else:
#Blender.Draw.Exit()
Main()
else:
Msg = 'Empty '+ hipbonename+ ' not found'
Blender.Draw.PupMenu("ERROR: %s" % Msg)
#Blender.Draw.Redraw(1)
elif evt==2:
@ -660,13 +656,11 @@ def button_event(evt):
if (ob!=None):
if ob.getParent()!=None:
Msg = 'Empty '+hipbonename+ ' is not a root bone.'
Blender.Draw.PupMenu("ERROR: %s" % Msg)
else:
#Blender.Draw.Exit()
RemoveEmpties()
else:
Msg = 'Empty '+ hipbonename+ ' not found'
Blender.Draw.PupMenu("ERROR: %s" % Msg)
#else:
# print "evt = ",evt
@ -677,13 +671,13 @@ def GUI():
Blender.BGL.glClear(Blender.BGL.GL_COLOR_BUFFER_BIT)
Blender.BGL.glColor3f(1,1,1)
Blender.BGL.glRasterPos2i(20,200)
Blender.Draw.Text ("BVH 2 ARMATURE v2.0 by Jean-Baptiste PERIN", 'normal')
HBName = Blender.Draw.String("HipBoneName: ", -1, 20, 175, 250, 20, '_Hips', 100)
SFrame2 = Blender.Draw.Number("Startframe: ", -1, 20, 150, 250, 20, 1, 1,3000,"")
EFrame = Blender.Draw.Number("Endframe: ", -1, 20, 125, 250, 20, Blender.Get("endframe"), 1,3000,"")
#IFrame = Blender.Draw.Number("Insertionframe: ", -1, 20, 100, 250, 20, Blender.Get("staframe"), 1,3000,"")
FrameDecimation = Blender.Draw.Number("FrameDecimation: ", -1, 20, 75, 250, 20,5, 1,10,'')
ScaleF = Blender.Draw.Number("Scale: ", -1, 20, 50, 250, 20, 0.03, 0.0, 10.0, 'Scale Factor')
Blender.Draw.Text ("BVH 2 ARMATURE v2.2 by Jean-Baptiste PERIN", 'normal')
HBName = Blender.Draw.String("HipBoneName: ", 0, 20, 175, 250, 20, '_Hips', 100)
SFrame2 = Blender.Draw.Number("Startframe: ", 0, 20, 150, 250, 20, 1, 1,3000,"Start frame of anim")
EFrame = Blender.Draw.Number("Endframe: ", 0, 20, 125, 250, 20, Blender.Get("endframe"), 1,3000,"Last frame of anim")
#IFrame = Blender.Draw.Number("Insertionframe: ", 0, 20, 100, 250, 20, Blender.Get("staframe"), 1,3000,"")
FrameDecimation = Blender.Draw.Number("FrameDecimation: ", 0, 20, 75, 250, 20,5, 1,10,'number of frame to skip between two action keys')
ScaleF = Blender.Draw.Number("Scale: ", 0, 20, 50, 250, 20, 1.0, 0.0, 10.0, 'Scale Factor')
Blender.Draw.Toggle("Create Armature", 1, 20, 10, 100, 20, 0, "Create Armature")
#Blender.Draw.Toggle("Remove Empties", 2, 200, 10, 100, 20, 0, "Remove Empties")
Blender.BGL.glRasterPos2i(20,40)

@ -80,29 +80,55 @@ from Blender import *
#==================================================================================#
# This function sets textures defined in .mtl file #
#==================================================================================#
def getImg(img_fileName):
def getImg(img_fileName, dir):
img_fileName_strip = stripPath(img_fileName)
for i in Image.Get():
if stripPath(i.filename) == stripPath(img_fileName):
if stripPath(i.filename) == img_fileName_strip:
return i
try: # Absolute dir
return Image.Load(img_fileName)
except IOError:
pass
# Relative dir
if img_fileName.startswith('/'):
img_fileName = img_fileName[1:]
elif img_fileName.startswith('./'):
img_fileName = img_fileName[2:]
elif img_fileName.startswith('\\'):
img_fileName = img_fileName[1:]
elif img_fileName.startswith('.\\'):
img_fileName = img_fileName[2:]
# if we are this far it means the image hasnt been loaded.
try:
return Image.Load(img_fileName)
return Image.Load( dir + img_fileName)
except IOError:
print '\tunable to open image file: "%s"' % img_fileName
return
pass
# Its unlikely but the image might be with the OBJ file, and the path provided not relevent.
# if the user extracted an archive with no paths this could happen.
try:
return Image.Load( dir + img_fileName_strip)
except IOError:
pass
print '\tunable to open image file: "%s"' % img_fileName
return None
#==================================================================================#
# This function sets textures defined in .mtl file #
#==================================================================================#
def loadMaterialImage(mat, img_fileName, type, meshDict):
def loadMaterialImage(mat, img_fileName, type, meshDict, dir):
TEX_ON_FLAG = NMesh.FaceModes['TEX']
texture = Texture.New(type)
texture.setType('Image')
image = getImg(img_fileName)
# Absolute path - c:\.. etc would work here
image = getImg(img_fileName, dir)
if image:
texture.image = image
@ -120,11 +146,19 @@ def loadMaterialImage(mat, img_fileName, type, meshDict):
# adds textures for materials (rendering)
elif type == 'Ka':
mat.setTexture(0, texture, Texture.TexCo.UV, Texture.MapTo.CMIR)
mat.setTexture(0, texture, Texture.TexCo.UV, Texture.MapTo.CMIR) # TODO- Add AMB to BPY API
elif type == 'Kd':
mat.setTexture(1, texture, Texture.TexCo.UV, Texture.MapTo.COL)
elif type == 'Ks':
mat.setTexture(2, texture, Texture.TexCo.UV, Texture.MapTo.SPEC)
elif type == 'Bump': # New Additions
mat.setTexture(3, texture, Texture.TexCo.UV, Texture.MapTo.NOR)
elif type == 'D':
mat.setTexture(4, texture, Texture.TexCo.UV, Texture.MapTo.ALPHA)
elif type == 'refl':
mat.setTexture(5, texture, Texture.TexCo.UV, Texture.MapTo.REF)
#==================================================================================#
# This function loads materials from .mtl file (have to be defined in obj file) #
@ -138,10 +172,12 @@ def load_mtl(dir, mtl_file, meshDict, materialDict):
# Make a new mat
try:
return materialDict[matName]
except NameError:
#except NameError or KeyError:
except: # Better do any exception
# Do we realy need to keep the dict up to date?, not realy but keeps consuistant.
materialDict[matName] = Material.New(matName)
return materialDict[matName]
mtl_file = stripPath(mtl_file)
mtl_fileName = dir + mtl_file
@ -172,19 +208,34 @@ def load_mtl(dir, mtl_file, meshDict, materialDict):
currentMat.setSpecCol(float(l[1]), float(l[2]), float(l[3]))
elif l[0] == 'Ns':
currentMat.setHardness( int((float(l[1])*0.51)) )
elif l[0] == 'Ni': # Refraction index
currentMat.setIOR( max(1, min(float(l[1]), 3))) # Between 1 and 3
elif l[0] == 'd':
currentMat.setAlpha(float(l[1]))
elif l[0] == 'Tr':
currentMat.setAlpha(float(l[1]))
elif l[0] == 'map_Ka':
img_fileName = dir + ' '.join(l[1:])
loadMaterialImage(currentMat, img_fileName, 'Ka', meshDict)
img_fileName = ' '.join(l[1:])
loadMaterialImage(currentMat, img_fileName, 'Ka', meshDict, dir)
elif l[0] == 'map_Ks':
img_fileName = dir + ' '.join(l[1:])
loadMaterialImage(currentMat, img_fileName, 'Ks', meshDict)
img_fileName = ' '.join(l[1:])
loadMaterialImage(currentMat, img_fileName, 'Ks', meshDict, dir)
elif l[0] == 'map_Kd':
img_fileName = dir + ' '.join(l[1:])
loadMaterialImage(currentMat, img_fileName, 'Kd', meshDict)
img_fileName = ' '.join(l[1:])
loadMaterialImage(currentMat, img_fileName, 'Kd', meshDict, dir)
# new additions
elif l[0] == 'map_Bump': # Bumpmap
img_fileName = ' '.join(l[1:])
loadMaterialImage(currentMat, img_fileName, 'Bump', meshDict, dir)
elif l[0] == 'map_D': # Alpha map - Dissolve
img_fileName = ' '.join(l[1:])
loadMaterialImage(currentMat, img_fileName, 'D', meshDict, dir)
elif l[0] == 'refl': # Reflectionmap
img_fileName = ' '.join(l[1:])
loadMaterialImage(currentMat, img_fileName, 'refl', meshDict, dir)
lIdx+=1
except:
print '\tERROR: Unable to parse MTL file.'
@ -641,13 +692,12 @@ def load_obj(file):
currentImg = imageDict[newImgName]
except KeyError: # Not in dict, add for first time.
try: # Image has not been added, Try and load the image
currentImg = Image.Load( '%s%s' % (DIR, newImgName) ) # Use join in case of spaces
imageDict[newImgName] = currentImg
except IOError: # Cant load, just set blank.
imageDict[newImgName] = None
currentImg = None
# Image has not been added, Try and load the image
currentImg = getImg(newImgName, DIR) # Use join in case of spaces
imageDict[newImgName] = currentImg
# These may be None, thats okay.
# MATERIAL FILE
elif l[0] == 'mtllib':
@ -709,3 +759,4 @@ print "TOTAL IMPORT TIME: ", sys.time() - TIME
#load_obj('/obj/foot_bones.obj')
#load_obj('/obj/mba1.obj')
#load_obj('/obj/PixZSphere50.OBJ')
#load_obj('/obj/obj_test/LHand.obj')

@ -213,7 +213,7 @@ Introduction:
in Blender. The script receives the event B{before} it is further processed
by the program. An EVENT handler script should check Blender.event (compare
it against L{Draw} events) and either:
- process it (then set Blender.event to None);
- process it (the script must set Blender.event to None then);
- ignore it.
Setting C{Blender.event = None} tells Blender not to go on processing itself
@ -226,6 +226,7 @@ Introduction:
import Blender
from Blender import DRAW
evt = Blender.event
return_it = False
if evt == DRAW.LEFTMOUSE:
print "Swallowing the left mouse button press"
@ -233,10 +234,10 @@ Introduction:
print "Swallowing an 'a' character"
else:
print "Let the 3D View itself process this event:", evt
return
return_it = True
# if Blender should not process itself the passed event:
Blender.event = None
if not return_it: Blender.event = None
DRAW space handlers are called by that space's drawing callback in Blender.
The script is called B{after} the space has been drawn.
@ -254,14 +255,16 @@ Introduction:
B{Guidelines (important)}:
- EVENT handlers can access and change Blender objects just like any other
script, but they should not draw (images, polygons, etc.) to the screen,
B{use a DRAW handler to do that} and, if both scripts need to pass
information to each other, use the L{Registry} module.
script, but they should not draw to the screen, B{use a DRAW handler to do
that}. Specifically: L{Draw.Image} and the L{BGL} drawing functions
should not be used inside an EVENT handler.
- DRAW handlers should leave the space in the same state it was before they
executed. OpenGL attributes and the modelview and projection matrices are
automatically saved (pushed) before a DRAW handler runs and restored (poped)
after it finishes, no need to worry about that. Draw handlers should not
grab events;
were executed. OpenGL attributes and the modelview and projection matrices
are automatically saved (pushed) before a DRAW handler runs and restored
(poped) after it finishes, no need to worry about that. Draw handlers
should not grab events;
- If script handlers need to pass information to each other (for example an
EVENT handler passing info to a DRAW handler), use the L{Registry} module.
- in short: use the event handler to deal with events and the draw handler to
draw and your script will be following the recommended practices for
Blender code.