Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--release/scripts/UVpaint05.py442
-rw-r--r--release/scripts/ac3d_export.py2
-rw-r--r--release/scripts/ac3d_import.py2
-rw-r--r--release/scripts/disp_paint233f.py329
-rw-r--r--release/scripts/fixfromarmature.py37
-rw-r--r--release/scripts/lightwave_export.py528
-rw-r--r--release/scripts/lightwave_import.py172
-rw-r--r--release/scripts/mod_flags.py19
-rw-r--r--release/scripts/mod_meshtools.py406
-rw-r--r--release/scripts/nendo_export.py183
-rw-r--r--release/scripts/nendo_import.py205
-rw-r--r--release/scripts/obj_export.py161
-rw-r--r--release/scripts/obj_import.py245
-rw-r--r--release/scripts/off_export.py11
-rw-r--r--release/scripts/off_import.py11
-rw-r--r--release/scripts/radiosity_export.py18
-rw-r--r--release/scripts/radiosity_import.py15
-rw-r--r--release/scripts/raw_export.py14
-rw-r--r--release/scripts/raw_import.py13
-rw-r--r--release/scripts/rvk1_torvk2.py108
-rw-r--r--release/scripts/slp_import.py76
-rw-r--r--release/scripts/truespace_export.py265
-rw-r--r--release/scripts/truespace_import.py229
-rw-r--r--release/scripts/unweld044.py366
-rw-r--r--release/scripts/uv_export.py8
-rw-r--r--release/scripts/videoscape_export.py21
-rw-r--r--release/scripts/wings_export.py337
-rw-r--r--release/scripts/wings_import.py288
-rw-r--r--source/blender/python/BPY_menus.c6
-rw-r--r--source/blender/python/BPY_menus.h8
30 files changed, 4319 insertions, 206 deletions
diff --git a/release/scripts/UVpaint05.py b/release/scripts/UVpaint05.py
new file mode 100644
index 00000000000..b994be23871
--- /dev/null
+++ b/release/scripts/UVpaint05.py
@@ -0,0 +1,442 @@
+#!BPY
+""" Registration info for Blender menus: <- these words are ignored
+Name: 'UVpainter'
+Blender: 232
+Group: 'UV'
+Tip: 'Use vertex paint color value to fill uvmapping.'
+"""
+
+#----------------------------------------------
+# uvpainter script (c) 04/2004 jean-michel soler
+# http://jmsoler.free.fr/util/blenderfile/py/UVpaint05.zip
+# this script is released under GPL licence
+# for the Blender 2.33 scripts distribution
+#----------------------------------------------
+#----------------------------------------------
+# Official page :
+# http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_uvpainting.htm
+# Communicate problems and errors on:
+# http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender
+#----------------------------------------------
+# Page officielle :
+# http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_uvpainting.htm
+# Communiquer les problemes et erreurs sur:
+# http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender
+#---------------------------------------------
+# ce script est proposé sous licence GPL pour etre associe
+# a la distribution de Blender 2.33 et suivant
+#----------------------------------------------
+
+import Blender
+from Blender.Draw import *
+from Blender.BGL import *
+from Blender.NMesh import *
+
+try:
+ import nt
+ os=nt
+except:
+ import posix
+ os=posix
+
+def exist(path):
+ try:
+ pth=os.stat(Blender.sys.dirname(path))
+ except:
+ return 0
+ return 1
+
+loc0= Blender.sys.dirname(Blender.Get ("filename"))
+loc2=loc0+Blender.sys.dirsep+'test00.tga'
+
+glCr=glRasterPos2d
+glCl3=glColor3f
+glCl4=glColor4f
+glRct=glRectf
+
+xlimit=0
+selmatlist=[]
+
+def triangle(a,b,c):
+ glBegin(GL_TRIANGLES);
+ glColor3f(a[2],a[3],a[4])
+ glVertex2f(a[0],a[1]);
+ glColor3f(b[2],b[3],b[4])
+ glVertex2f(b[0],b[1]);
+ glColor3f(c[2],c[3],c[4])
+ glVertex2f(c[0],c[1]);
+ glEnd();
+
+def Ltriangle(a,b,c):
+ glBegin(GL_LINES);
+ glColor3f(1.0,1.0,1.0)
+ glVertex2f(a[0],a[1]);
+ glVertex2f(b[0],b[1]);
+ glVertex2f(c[0],c[1]);
+ glEnd();
+
+def carre(a,b,c,d):
+ triangle(a,b,c)
+ triangle(a,c,d)
+
+def Lcarre(a,b,c,d):
+ glBegin(GL_LINES);
+ glColor3f(1.0,1.0,1.0)
+ glVertex2f(a[0],a[1]);
+ glVertex2f(b[0],b[1]);
+ glVertex2f(c[0],c[1]);
+ glVertex2f(d[0],d[1]);
+ glEnd();
+
+
+
+def transface(f,x,y):
+ global xlimit
+
+
+
+ a=[0,0,0.0, 0.0,0.0,0.0]
+ b=[0,0,0.0, 0.0,0.0,0.0]
+ c=[0,0,0.0, 0.0,0.0,0.0]
+ d=[0,0,0.0, 0.0,0.0,0.0]
+
+ if len(f.v)>=3:
+ a[0]=int(f.uv[0][0]*x)
+ a[1]=int(f.uv[0][1]*y)
+
+ if a[0]>xlimit:
+ xlimit=a[0]
+
+ a[2]=f.col[0].r/255.0
+ a[3]=f.col[0].g/255.0
+ a[4]=f.col[0].b/255.0
+
+ c[0]=int(f.uv[2][0]*x)
+ c[1]=int(f.uv[2][1]*y)
+
+ if c[0]>xlimit:
+ xlimit=c[0]
+
+ c[2]=f.col[2].r/255.0
+ c[3]=f.col[2].g/255.0
+ c[4]=f.col[2].b/255.0
+
+
+ b[0]=int(f.uv[1][0]*x)
+ b[1]=int(f.uv[1][1]*y)
+
+ if b[0]>xlimit:
+ xlimit=b[0]
+
+ b[2]=f.col[1].r/255.0
+ b[3]=f.col[1].g/255.0
+ b[4]=f.col[1].b/255.0
+
+
+ if len(f.v)==4:
+ d[0]=int(f.uv[3][0]*x)
+ d[1]=int(f.uv[3][1]*y)
+
+ if d[0]>xlimit:
+ xlimit=d[0]
+
+ d[2]=f.col[3].r/255.0
+ d[3]=f.col[3].g/255.0
+ d[4]=f.col[3].b/255.0
+ else:
+ d=0
+
+
+ #print a,b,c
+ return a,b,c,d
+
+
+def extract_faces(me,MENU):
+ global TMATList, selmatlist
+ if MENU==2:
+ listf=[]
+ for f in me.faces:
+ if f.mat in selmatlist:
+ listf.append(f)
+ return listf
+
+def affiche_mesh(ME,x,y):
+ global LINE,xlimit,MMENU,XLIMIT,xwin,xlimit
+
+ if ME.getType()=='Mesh':
+ me=GetRaw(ME.getData().name)
+
+ if MMENU.val==1:
+ se=me.faces
+
+ elif MMENU.val==3:
+ se=me.getSelectedFaces()
+
+ elif MMENU.val==2:
+ se=extract_faces(me,2)
+
+ xlimit=0
+ for f in se:
+ a,b,c,d=transface(f,x,y)
+ if len(f.v)==4:
+ triangle(a,b,c)
+ triangle(a,c,d)
+ elif len(f.v)==3:
+ triangle(a,b,c)
+
+ if LINE.val==1:
+ for f in se:
+ a,b,c,d=transface(f,x,y)
+ if len(f.v)==4:
+ Lcarre(a,b,c,d)
+ elif len(f.v)==3:
+ Ltriangle(a,b,c)
+
+ if XLIMIT.val==0:
+ Lcarre([1,1],[1,y-2],[xlimit+2,y-2],[xlimit+2,1])
+ else:
+ Lcarre([1,1],[1,y-2],[xwin-2,y-2],[xwin-2,1])
+
+
+
+def write_tgafile(loc2,bitmap,width,height,profondeur):
+
+ f=open(loc2,'wb')
+ Origine_en_haut_a_gauche=32
+ Origine_en_bas_a_gauche=0
+ Data_Type_2=2
+ RVB=profondeur*8
+ RVBA=32
+ entete0=[]
+ for t in range(18):
+ entete0.append(chr(0))
+
+ entete0[2]=chr(Data_Type_2)
+ entete0[13]=chr(width/256)
+ entete0[12]=chr(width % 256)
+ entete0[15]=chr(height/256)
+ entete0[14]=chr(height % 256)
+ entete0[16]=chr(RVB)
+ entete0[17]=chr(Origine_en_bas_a_gauche)
+
+ #Origine_en_haut_a_gauche
+
+ for t in entete0:
+ f.write(t)
+
+ for t in bitmap:
+
+ for c in [2,1,0,3]:
+ #print t[c]%256
+ f.write(chr(t[c]*2))
+ f.close()
+
+
+def save(x0,y0,dx,dy):
+ im = Buffer(GL_BYTE,[dx*(dy+1),4])
+ glReadPixels(x0,y0,dx,dy,GL_RGBA, GL_BYTE,im);
+ print len(im), dx*dy, dx, dy, len(im)/dy
+ write_tgafile(loc2,im,dx,dy+1,4)
+
+def DOCMat_list(TMATList,ME):
+ me=Blender.NMesh.GetRaw(ME.getData().name)
+ if len(me.materials)!=0:
+ n=0
+ for mat in me.materials:
+ TMATList[1][n][0]=mat.R
+ TMATList[1][n][1]=mat.G
+ TMATList[1][n][2]=mat.B
+ n+=1
+ TMATList[0]=n
+ else:
+ TMATList[0]=0
+ return TMATList
+
+def SELMat_list():
+ global TMATList,selmatlist
+ Me=Blender.Object.GetSelected()
+ if Me!=[]:
+ if Me[0].getType()=='Mesh':
+ TMATList=DOCMat_list(TMATList,Me[0])
+ selmatlist=[]
+ for TMat in TMATList[2]:
+ if TMat.val==1.0:
+ selmatlist.append(TMATList[2].index(TMat))
+ ERROR=0
+ else:
+ ERROR=1
+ TextERROR='Selected Object is not a mesh.'
+ else:
+ ERROR=1
+ TextERROR='No Selected Object.'
+
+def DOCBONEMENU(TBONEMENU):
+ pass
+
+# ----------
+# uvpaint1
+# ----------
+NSIZE=Create(1.0)
+# ----------
+# uvpaint2
+# ----------
+LINE=Create(0)
+# ----------
+# uvpaint3
+# ----------
+TEXT=Create(loc2)
+# ----------
+# uvpaint4
+# ----------
+TMENU="MODE MENU %t|All %x1|Material %x2|Selected %x3"
+
+# coming soon : "|Bone %x4", perhaps in uvpainter v0.5
+
+MMENU=Create(3)
+TDOCMat = Create(0)
+# ----------
+TMATList= [0,[],[]]
+for t in range(16):
+ TMATList[1].append([0.0,0.0,0.0])
+ TMATList[2].append(Create(0))
+# ----------
+TDOCMat = Create(1)
+# ----------
+TBONEMENU= Create(1)
+# ----------
+
+XLIMIT=Create(0)
+
+y=0
+x=0
+x0=0
+y0=0
+xwin=0
+
+n0=32
+
+def draw():
+ global NSIZE,LINE,x0,y0,y,x,TEXT,MMENU,TDOCMat
+ global XLIMIT,selmatlist,xwin
+
+ size=Buffer(GL_FLOAT, 4)
+ glGetFloatv(GL_SCISSOR_BOX, size)
+ size= size.list
+
+ for s in [0,1,2,3]: size[s]=int(size[s])
+
+ n0=32
+ x0=size[0]
+ y0=size[1]
+
+ x=size[2]
+ y=size[3]
+
+ xwin=x
+ ywin=y
+
+
+ glClear(GL_COLOR_BUFFER_BIT)
+
+ glShadeModel(GL_SMOOTH)
+ SelecMESH=Blender.Object.GetSelected()
+ if SelecMESH!=[]:
+ if SelecMESH[0].getType()=='Mesh':
+ affiche_mesh(SelecMESH[0],int(y*NSIZE.val),int(y*NSIZE.val-n0-2))
+
+ glColor3f(0.0,0.0,0.0)
+ glRectf(4,size[3],555,size[3]-32 )
+
+ glColor3f(1.0,1.0,1.0)
+
+ glRasterPos2f(8, size[3]-13)
+ Text("uvpainter v0.5")
+
+ glRasterPos2f(8, size[3]-28)
+ Text("Jm Soler, 05/2004")
+
+ Button("ReDraw" ,16 ,290-118+61 ,size[3]-30 ,60 ,13)
+ Button("Exit" ,1 ,250-122+63 ,size[3]-30 ,38 ,13)
+ Button("Save" ,6 ,250-16+61 ,size[3]-30 ,40 ,13)
+
+ NSIZE= Slider("Sc:",4 ,290-118+61 ,size[3]-15 , 102, 13, NSIZE.val, 0.1,1.5,0,"SIZE.")
+ LINE=Toggle("line", 5 ,250-122+63 ,size[3]-15 , 38, 13, LINE.val, "Draw lines")
+
+ glRasterPos2f(250-130 ,size[3]-13,)
+ Text("Mode")
+
+ MMENU= Menu(TMENU ,2 ,250-130, size[3]-30, 63, 13, MMENU.val, "MODE menu.")
+
+ if MMENU.val==1 or MMENU.val==3:
+ glRasterPos2f( 250-16+61+42+80,size[3]-13)
+ if XLIMIT.val:
+ xl=xwin
+ else:
+ xl=xlimit
+
+ Text("x :"+"%d"%(xl+2))
+
+ glRasterPos2f(250-16+61+42+65*2,size[3]-13)
+ Text("y :"+"%d"%(y-n0+1))
+
+ TEXT=String("to:", 7 , 278+61 ,size[3]-28 , 213, 13, TEXT.val, 256, "Draw lines")
+ if XLIMIT.val==1:
+ limit='winlimit'
+ else:
+ limit='maxXlimit'
+ XLIMIT=Toggle(limit, 9 , 250-16+61+42 ,size[3]-15 , 60, 13, XLIMIT.val, "to save picture from x max uv limit, or x window max limit")
+
+ if MMENU.val==2:
+ TDOCMat=Toggle("doc" ,24,250-130+35 ,size[3]-13 , 28, 13, TDOCMat.val)
+ if TDOCMat.val==1:
+ SELMat_list()
+ for t in range(TMATList[0]):
+ glCl3(TMATList[1][t][0],
+ TMATList[1][t][1],
+ TMATList[1][t][2])
+ glRct((293-16+61)+t*20,
+ size[3]-13,
+ (293-16+61)+t*20+20,
+ size[3]-30,)
+ TMATList[2][t]=Toggle("%s"%t , 32+t ,(293-16+61)+t*20 ,size[3]-13 ,20 , 13,TMATList[2][t].val)
+
+
+
+def event(evt, val):
+ if (evt== QKEY and not val): Exit()
+
+def bevent(evt):
+ global LINE,NSIZE,n0,x0,y0,y,TEXT, loc2
+ global TMATList, selmatlist, TDOCMat,XLIMIT
+ global xlimit
+
+ if (evt== 1):
+ Exit()
+
+ elif (evt== 16):
+ pass
+
+ elif (evt== 4):
+ ng=NSIZE.val
+
+ elif (evt== 6):
+ if XLIMIT.val==1:
+ xi=xwin
+ else:
+ xi=xlimit
+
+ save(x0,y0,xi+2,int(y*NSIZE.val-n0))
+
+ elif (evt== 7):
+ if exist(TEXT.val):
+ loc2=TEXT.val
+ else:
+ TEXT.val=loc2
+
+ elif (evt== 24) or (evt in [32,33,34,35,36,37,38,39,40,41,42,43,44]):
+ SELMat_list()
+
+
+ Blender.Redraw()
+
+Register(draw, event, bevent)
diff --git a/release/scripts/ac3d_export.py b/release/scripts/ac3d_export.py
index 6a464767c4c..04da0d38cab 100644
--- a/release/scripts/ac3d_export.py
+++ b/release/scripts/ac3d_export.py
@@ -16,7 +16,7 @@ Tip: 'Export to AC3D (.ac) format.'
# --------------------------------------------------------------------------
# ***** BEGIN GPL LICENSE BLOCK *****
#
-# Copyright (C) 2004: Willian P. Germano, wgermano@ig.com.br
+# Copyright (C) 2004: Willian P. Germano, wgermano _at_ ig.com.br
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
diff --git a/release/scripts/ac3d_import.py b/release/scripts/ac3d_import.py
index 3e3d08a1155..3dc8af7ad2c 100644
--- a/release/scripts/ac3d_import.py
+++ b/release/scripts/ac3d_import.py
@@ -13,7 +13,7 @@ Tip: 'Import an AC3D (.ac) file.'
# --------------------------------------------------------------------------
# ***** BEGIN GPL LICENSE BLOCK *****
#
-# Copyright (C) 2004: Willian P. Germano, wgermano@ig.com.br
+# Copyright (C) 2004: Willian P. Germano, wgermano _at_ ig.com.br
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
diff --git a/release/scripts/disp_paint233f.py b/release/scripts/disp_paint233f.py
new file mode 100644
index 00000000000..cf60f4ecfae
--- /dev/null
+++ b/release/scripts/disp_paint233f.py
@@ -0,0 +1,329 @@
+#!BPY
+
+""" Registration info for Blender menus: <- these words are ignored
+Name: 'Dispaint'
+Blender: 233
+Group: 'Modifiers'
+Tip: 'use vertex paint color value to modify shape displacing vertices along normal.'
+"""
+
+#----------------------------------------------
+# jm soler, displacement paint 03/2002 - > 05/2004: disp_paintf
+#----------------------------------------------
+# Official page :
+# http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_displacementpainting.htm
+#----------------------------------------------
+# Communicate problems and errors on:
+# http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender
+#---------------------------------------------
+# this script is released under GPL licence
+# for the Blender 2.33 scripts package
+#----------------------------------------------
+# Page officielle :
+# http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_displacementpainting.htm
+# Communiquer les problemes et erreurs sur:
+# http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender
+#---------------------------------------------
+# ce script est proposé sous licence GPL pour etre associe
+# a la distribution de Blender 2.33
+#----------------------------------------------
+
+import Blender
+from Blender import *
+from Blender.Draw import *
+from Blender.BGL import *
+
+
+# niveau du deplacement
+ng=0.5
+
+# profondeur des couleurs primaires rgb
+maxcol=255.0*3
+
+# limitation de la zone de travail sur le
+# le materiau numer mat du tableau d'indices
+# des materiaux. Par defaut mat =-1 ce qui signifie
+# que toute la surface est traitee
+mat=[]
+vindex=[]
+ORIName=''
+NEWName=''
+ERROR=0
+TextERROR=''
+
+def copy_transform(ozero,Obis):
+ Obis.setSize(ozero.getSize());
+ Obis.setEuler(ozero.getEuler());
+ Obis.setLocation(ozero.getLocation())
+ return Obis
+
+def traite_face(f):
+ global vindexm
+ if ORIENTMenu.val==1:
+ for z in range(len(f.v)):
+ c=0.0
+ if vindex[f.v[z].index]!=0:
+ c=float(f.col[z].r+f.col[z].b+f.col[z].g)/maxcol*ng/vindex[f.v[z].index]
+ else:
+ c=0
+
+ f.v[z].co[0]=f.v[z].co[0]+f.v[z].no[0]*c
+ f.v[z].co[1]=f.v[z].co[1]+f.v[z].no[1]*c
+ f.v[z].co[2]=f.v[z].co[2]+f.v[z].no[2]*c
+
+ if ORIENTMenu.val==2:
+ for z in range(len(f.v)):
+ c=0.0
+ if vindex[f.v[z].index]!=0:
+ c=float(f.col[z].r+f.col[z].b+f.col[z].g)/maxcol*ng/vindex[f.v[z].index]
+ else:
+ c=0
+ for t in range(3):
+ if TAXEList[1][t].val==1:
+ f.v[z].co[t]=f.v[z].co[t]+c
+
+
+def paint():
+ global MODEMenu, vindex,ng, mat, ORIName, NEWName
+
+ Me=Object.GetSelected()
+ if Me!=[]:
+ if Me[0].getType()=='Mesh':
+
+ vindex=[]
+ ORIName=Me[0].getData().name
+ me=NMesh.GetRaw(Me[0].getData().name)
+
+ name='new.002'
+
+ for m in me.verts:
+ vindex.append(0)
+
+ for f in me.faces:
+ for v in f.v:
+ if MODEMenu.val!=2:
+ if MODEMenu.val==1:
+ vindex[v.index]+=1
+ else:
+ if v.sel==1:
+ vindex[v.index]+=1
+ else:
+ #print mat
+ if f.mat in mat:
+ vindex[v.index]+=1
+
+ for f in me.faces:
+ if MODEMenu.val==2:
+ if f.mat in mat:
+ traite_face(f)
+ else:
+ traite_face(f)
+
+ NMesh.PutRaw(me,name)
+
+ if name!=Object.GetSelected()[0].getData().name:
+ obj=Object.Get()
+ for o in obj:
+ if o.getType()=='Mesh':
+ if o.getData().name==name:
+ o.makeDisplayList()
+
+ o=copy_transform(Me[0],o)
+ """
+ o.setEuler(Me[0].getEuler())
+ o.setLocation(Me[0].getLocation())
+ """
+
+ else:
+ Me[0].makeDisplayList()
+
+def NEWMEcreation(name):
+ nomdelobjet=""; objnumber=-1; namelist=[]
+ obj=Object.Get()
+
+ for ozero in obj:
+ if ozero.getType()=='Mesh':
+ namelist.append(ozero.getData().name)
+ if ozero.getData().name==name:
+ objnumber=obj.index(ozero)
+
+ if objnumber!=-1:
+ ozero=obj[objnumber]
+ nomdelobjet=ozero.getName()
+ Mesh=Blender.NMesh.GetRawFromObject(nomdelobjet)
+
+ n=0; name2=name[:];ok=0
+
+ while ok==0:
+ for n0 in namelist:
+ if n0.find(name2)==0:
+ ok=0;name2=name[0:name.find('.')+1]+'%s'%(n+1)
+ else: ok=1
+ n+=1
+ Mesh.name=name2
+ Obis = Blender.NMesh.PutRaw(Mesh,name2)
+ copy_transform(ozero,Obis)
+ Obis.makeDisplayList()
+
+def DOCMat_list(TMATList):
+ global mat
+ Me=Object.GetSelected()
+ if Me!=[]:
+ if Me[0].getType()=='Mesh':
+ me=NMesh.GetRaw(Me[0].getData().name)
+ if len(me.materials)!=0:
+ n=0
+ for mat in me.materials:
+ TMATList[1][n][0]=mat.R
+ TMATList[1][n][1]=mat.G
+ TMATList[1][n][2]=mat.B
+ n+=1
+ TMATList[0]=n
+ else:
+ TMATList[0]=0
+ return TMATList
+
+MOname = "MODE MENU %t|Normal %x1|Material %x2|Selected %x3"
+ORname = "ORIENT MENU %t|From Normal %x1|Local Axes %x2"
+
+MODEMenu = Create(1)
+ORIENTMenu = Create(1)
+NSIZE = Create(1.0)
+TDOCMat = Create(0)
+NRepeat = Create(1)
+
+TMATList= [0,[],[]]
+
+for t in range(16):
+ TMATList[1].append([0.0,0.0,0.0])
+ TMATList[2].append(Create(0))
+
+TAXEList=[['X','Y','Z'],[]]
+for t in range(3):
+ TAXEList[1].append(Create(0))
+
+glCr=glRasterPos2d
+glCl3=glColor3f
+glCl4=glColor4f
+glRct=glRectf
+
+
+
+def draw():
+ global MODEMenu, NSIZE, TDOCMat,TMATList, TAXEList
+ global mat, ORIName, NEWName, ORIENTMenu
+ global NRepeat, ERROR, TextERROR
+
+ size=Buffer(GL_FLOAT, 4)
+ glGetFloatv(GL_SCISSOR_BOX, size)
+ size= size.list
+
+ for s in [0,1,2,3]: size[s]=int(size[s])
+
+ glClear(GL_COLOR_BUFFER_BIT)
+
+ glColor3f(0.0,0.0,0.0)
+ glRectf(4,size[3],534,size[3]-32 )
+
+ glColor3f(1.0,1.0,1.0)
+ glRasterPos2f(20, size[3]-15)
+ Text("Script Python de displacement paintingt")
+
+ glRasterPos2f(20, size[3]-28)
+ Text("Jean-michel Soler, avril 2004")
+
+
+ n0=70
+ n1=55
+
+ Button("Create" ,17 ,5 ,size[3]-n0+16 ,60 ,20)
+ Button("Action" ,16 ,5 ,size[3]-n0-4 ,60 ,20)
+ Button("Exit" ,1 ,5 ,size[3]-n0-24 ,60 ,20)
+
+ NRepeat=Number("repeat" ,5 ,5 ,size[3]-n0-50 ,75 ,20, NRepeat.val,1,10)
+
+ glColor3f(0.0,0.0,0.0)
+ glRasterPos2f(80 ,size[3]-n0+24)
+ Text("MODE")
+
+ MODEMenu= Menu(MOname, 2 ,80 ,size[3]-n0 ,100,20, MODEMenu.val, "MODE menu.")
+
+ if MODEMenu.val==2:
+ TDOCMat=Toggle("Doc Mat" ,24 ,180 ,size[3]-n0 ,60 ,20,TDOCMat.val)
+ if TDOCMat.val==1:
+ #print TMATList
+ for t in range(TMATList[0]):
+ glCl3(TMATList[1][t][0],
+ TMATList[1][t][1],
+ TMATList[1][t][2])
+ glRct(80+t*40,
+ size[3]-n0-60,
+ 80+t*40+40,
+ size[3]-n0-60+40)
+ TMATList[2][t]=Toggle("%s"%t , 32+t ,80+t*40+5 ,size[3]-n0-50 ,30 , 20,TMATList[2][t].val)
+ glColor3f(1.0,0.3,0.0)
+ glRasterPos2f(80+40+5 ,size[3]-n0-80)
+ if ERROR==1:
+ Text('Last error : '+TextERROR)
+ else:
+ Text('Last error : ')
+
+ glColor3f(0.0,0.0,0.0)
+ glRasterPos2f(240 ,size[3]-n0+24)
+ Text("ORIENTATION")
+
+ ORIENTMenu= Menu(ORname, 3 ,240 ,size[3]-n0 ,100,20, ORIENTMenu.val, "MODE menu.")
+ if ORIENTMenu.val>1:
+ for t in range(3):
+ TAXEList[1][t]=Toggle("%s"%TAXEList[0][t],
+ 40+t,
+ 240+100+t*30 , size[3]-n0 ,30 , 20,
+ TAXEList[1][t].val)
+
+ NSIZE= Slider("Disp Size", 4 ,80 ,size[3]-n0-20 ,260,20, NSIZE.val, -4.0,+4.0,0,"SIZE.")
+
+
+
+
+def event(evt, val):
+ if (evt== QKEY and not val): Exit()
+
+def bevent(evt):
+ global MODEMenu, NSIZE, ng, TMATList
+ global mat, ORIENTMenu, NRepeat, TAXEList
+ global ERROR,TextERROR
+
+ if (evt== 1):
+ Exit()
+
+
+ elif (evt== 16):
+ for n in range(NRepeat.val):
+ paint()
+
+ elif (evt== 4):
+ ng=NSIZE.val
+
+ elif (evt== 24) or (evt in [32,33,34,35,36,37,38,39,40,41,42,43,44]):
+ Me=Object.GetSelected()
+ if Me!=[]:
+ if Me[0].getType()=='Mesh':
+ TMATList=DOCMat_list(TMATList)
+ mat=[]
+ for TMat in TMATList[2]:
+ if TMat.val==1.0:
+ mat.append(TMATList[2].index(TMat))
+ ERROR=0
+ else:
+ ERROR=1
+ TextERROR='Selected Object is not a mesh.'
+ else:
+ ERROR=1
+ TextERROR='No Selected Object.'
+
+ elif (evt== 17):
+ NEWMEcreation('new.002')
+
+ Blender.Redraw()
+
+Register(draw, event, bevent)
diff --git a/release/scripts/fixfromarmature.py b/release/scripts/fixfromarmature.py
new file mode 100644
index 00000000000..564e56ff66e
--- /dev/null
+++ b/release/scripts/fixfromarmature.py
@@ -0,0 +1,37 @@
+#!BPY
+
+""" Registration info for Blender menus: <- these words are ignored
+Name: 'Fix from Armature'
+Blender: 232
+Group: 'Generators'
+Tip: 'Fix armature deformation.'
+"""
+
+#----------------------------------------------
+# jm soler 05/2004 : 'FixfromArmature'
+#----------------------------------------------
+# Official Page :
+# http://jmsoler.free.fr/util/blenderfile/py/fixfromarmature.py
+# Communicate problems and errors on:
+# http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender
+#---------------------------------------------
+# Page officielle :
+# http://jmsoler.free.fr/util/blenderfile/py/fixfromarmature.py
+# Communiquer les problemes et erreurs sur:
+# http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender
+#---------------------------------------------
+
+import Blender
+try:
+ Ozero=Blender.Object.GetSelected()[0]
+ nomdelobjet=Ozero.getName()
+ Mesh=Blender.NMesh.GetRawFromObject(nomdelobjet)
+ Obis = Blender.Object.New ('Mesh')
+ Obis.link(Mesh)
+ Obis.setSize(Ozero.getSize())
+ Obis.setEuler(Ozero.getEuler())
+ Obis.setLocation(Ozero.getMatrix()[3][0:3])
+ scene = Blender.Scene.getCurrent()
+ scene.link (Obis)
+except:
+ print "not a mesh or no object selected"
diff --git a/release/scripts/lightwave_export.py b/release/scripts/lightwave_export.py
new file mode 100644
index 00000000000..6ed96300673
--- /dev/null
+++ b/release/scripts/lightwave_export.py
@@ -0,0 +1,528 @@
+#!BPY
+
+"""
+Name: 'LightWave...'
+Blender: 232
+Group: 'Export'
+Tooltip: 'Export selected meshes to LightWave File Format (*.lwo)'
+"""
+
+# +---------------------------------------------------------+
+# | Copyright (c) 2002 Anthony D'Agostino |
+# | http://www.redrival.com/scorpius |
+# | scorpius@netzero.com |
+# | April 21, 2002 |
+# | Released under the Blender Artistic Licence (BAL) |
+# | Import Export Suite v0.5 |
+# +---------------------------------------------------------+
+# | Read and write LightWave Object File Format (*.lwo) |
+# +---------------------------------------------------------+
+
+import Blender, mod_meshtools
+import struct, chunk, os, cStringIO, time, operator
+
+# ==============================
+# === Write LightWave Format ===
+# ==============================
+def write(filename):
+ start = time.clock()
+ file = open(filename, "wb")
+
+ objects = Blender.Object.GetSelected()
+ objects.sort(lambda a,b: cmp(a.name, b.name))
+ if not objects:
+ mod_meshtools.print_boxed("No mesh objects are selected.")
+ return
+
+ if len(objects) > 20 and mod_meshtools.show_progress:
+ mod_meshtools.show_progress = 0
+
+ text = generate_text()
+ desc = generate_desc()
+ icon = "" #generate_icon()
+
+ material_names = get_used_material_names(objects)
+ tags = generate_tags(material_names)
+ surfs = generate_surfs(material_names)
+ chunks = [text, desc, icon, tags]
+
+ meshdata = cStringIO.StringIO()
+ layer_index = 0
+ for object in objects:
+ objname = object.name
+ meshname = object.data.name
+ mesh = Blender.NMesh.GetRaw(meshname)
+ #mesh = Blender.NMesh.GetRawFromObject(meshname) # for SubSurf
+ obj = Blender.Object.Get(objname)
+ if not mesh: continue
+
+ layr = generate_layr(objname, layer_index)
+ pnts = generate_pnts(mesh, obj.matrix)
+ bbox = generate_bbox(mesh)
+ pols = generate_pols(mesh)
+ ptag = generate_ptag(mesh, material_names)
+
+ if mesh.hasFaceUV():
+ vmad_uv = generate_vmad_uv(mesh) # per face
+
+ if mod_meshtools.has_vertex_colors(mesh):
+ if mod_meshtools.average_vcols:
+ vmap_vc = generate_vmap_vc(mesh) # per vert
+ else:
+ vmad_vc = generate_vmad_vc(mesh) # per face
+
+ write_chunk(meshdata, "LAYR", layr); chunks.append(layr)
+ write_chunk(meshdata, "PNTS", pnts); chunks.append(pnts)
+ write_chunk(meshdata, "BBOX", bbox); chunks.append(bbox)
+ write_chunk(meshdata, "POLS", pols); chunks.append(pols)
+ write_chunk(meshdata, "PTAG", ptag); chunks.append(ptag)
+
+ if mesh.hasFaceUV():
+ write_chunk(meshdata, "VMAD", vmad_uv)
+ chunks.append(vmad_uv)
+
+ if mod_meshtools.has_vertex_colors(mesh):
+ if mod_meshtools.average_vcols:
+ write_chunk(meshdata, "VMAP", vmap_vc)
+ chunks.append(vmap_vc)
+ else:
+ write_chunk(meshdata, "VMAD", vmad_vc)
+ chunks.append(vmad_vc)
+ layer_index += 1
+
+ for surf in surfs:
+ chunks.append(surf)
+
+ write_header(file, chunks)
+ write_chunk(file, "ICON", icon)
+ write_chunk(file, "TEXT", text)
+ write_chunk(file, "DESC", desc)
+ write_chunk(file, "TAGS", tags)
+ file.write(meshdata.getvalue()); meshdata.close()
+ for surf in surfs:
+ write_chunk(file, "SURF", surf)
+
+ Blender.Window.DrawProgressBar(1.0, "") # clear progressbar
+ file.close()
+ print '\a\r',
+ end = time.clock()
+ seconds = " in %.2f %s" % (end-start, "seconds")
+ message = "Successfully exported " + os.path.basename(filename) + seconds
+ mod_meshtools.print_boxed(message)
+
+# =======================================
+# === Generate Null-Terminated String ===
+# =======================================
+def generate_nstring(string):
+ if len(string)%2 == 0: # even
+ string += "\0\0"
+ else: # odd
+ string += "\0"
+ return string
+
+# ===============================
+# === Get Used Material Names ===
+# ===============================
+def get_used_material_names(objects):
+ matnames = {}
+ for object in objects:
+ objname = object.name
+ meshname = object.data.name
+ mesh = Blender.NMesh.GetRaw(meshname)
+ if not mesh: continue
+ if (not mesh.materials) and (mod_meshtools.has_vertex_colors(mesh)):
+ # vcols only
+ if mod_meshtools.average_vcols:
+ matnames["\251 Per-Vert Vertex Colors"] = None
+ else:
+ matnames["\251 Per-Face Vertex Colors"] = None
+ elif (mesh.materials) and (not mod_meshtools.has_vertex_colors(mesh)):
+ # materials only
+ for material in mesh.materials:
+ matnames[material.name] = None
+ elif (not mesh.materials) and (not mod_meshtools.has_vertex_colors(mesh)):
+ # neither
+ matnames["\251 Blender Default"] = None
+ else:
+ # both
+ for material in mesh.materials:
+ matnames[material.name] = None
+ return matnames
+
+# =========================================
+# === Generate Tag Strings (TAGS Chunk) ===
+# =========================================
+def generate_tags(material_names):
+ material_names = map(generate_nstring, material_names.keys())
+ tags_data = reduce(operator.add, material_names)
+ return tags_data
+
+# ========================
+# === Generate Surface ===
+# ========================
+def generate_surface(name, mesh):
+ if name.find("\251 Per-") == 0:
+ return generate_vcol_surf(mesh)
+ elif name == "\251 Blender Default":
+ return generate_default_surf()
+ else:
+ return generate_surf(name)
+
+# ======================
+# === Generate Surfs ===
+# ======================
+def generate_surfs(material_names):
+ keys = material_names.keys()
+ values = material_names.values()
+ surfaces = map(generate_surface, keys, values)
+ return surfaces
+
+# ===================================
+# === Generate Layer (LAYR Chunk) ===
+# ===================================
+def generate_layr(name, idx):
+ data = cStringIO.StringIO()
+ data.write(struct.pack(">h", idx)) # layer number
+ data.write(struct.pack(">h", 0)) # flags
+ data.write(struct.pack(">fff", 0, 0, 0)) # pivot
+ data.write(generate_nstring(name)) # name
+ return data.getvalue()
+
+# ===================================
+# === Generate Verts (PNTS Chunk) ===
+# ===================================
+def generate_pnts(mesh, matrix):
+ data = cStringIO.StringIO()
+ for i in range(len(mesh.verts)):
+ if not i%100 and mod_meshtools.show_progress:
+ Blender.Window.DrawProgressBar(float(i)/len(mesh.verts), "Writing Verts")
+ x, y, z = mod_meshtools.apply_transform(mesh.verts[i].co, matrix)
+ data.write(struct.pack(">fff", x, z, y))
+ return data.getvalue()
+
+# ==========================================
+# === Generate Bounding Box (BBOX Chunk) ===
+# ==========================================
+def generate_bbox(mesh):
+ data = cStringIO.StringIO()
+ # need to transform verts here
+ nv = map(getattr, mesh.verts, ["co"]*len(mesh.verts))
+ xx = map(operator.getitem, nv, [0]*len(nv))
+ yy = map(operator.getitem, nv, [1]*len(nv))
+ zz = map(operator.getitem, nv, [2]*len(nv))
+ data.write(struct.pack(">6f", min(xx), min(zz), min(yy), max(xx), max(zz), max(yy)))
+ return data.getvalue()
+
+# ========================================
+# === Average All Vertex Colors (Fast) ===
+# ========================================
+def average_vertexcolors(mesh):
+ vertexcolors = {}
+ vcolor_add = lambda u, v: [u[0]+v[0], u[1]+v[1], u[2]+v[2], u[3]+v[3]]
+ vcolor_div = lambda u, s: [u[0]/s, u[1]/s, u[2]/s, u[3]/s]
+ for i in range(len(mesh.faces)): # get all vcolors that share this vertex
+ if not i%100 and mod_meshtools.show_progress:
+ Blender.Window.DrawProgressBar(float(i)/len(mesh.verts), "Finding Shared VColors")
+ for j in range(len(mesh.faces[i].v)):
+ index = mesh.faces[i].v[j].index
+ color = mesh.faces[i].col[j]
+ r,g,b,a = color.r, color.g, color.b, color.a
+ vertexcolors.setdefault(index, []).append([r,g,b,a])
+ for i in range(len(vertexcolors)): # average them
+ if not i%100 and mod_meshtools.show_progress:
+ Blender.Window.DrawProgressBar(float(i)/len(mesh.verts), "Averaging Vertex Colors")
+ vcolor = [0,0,0,0] # rgba
+ for j in range(len(vertexcolors[i])):
+ vcolor = vcolor_add(vcolor, vertexcolors[i][j])
+ shared = len(vertexcolors[i])
+ vertexcolors[i] = vcolor_div(vcolor, shared)
+ return vertexcolors
+
+# ====================================================
+# === Generate Per-Vert Vertex Colors (VMAP Chunk) ===
+# ====================================================
+def generate_vmap_vc(mesh):
+ data = cStringIO.StringIO()
+ data.write("RGB ") # type
+ data.write(struct.pack(">H", 3)) # dimension
+ data.write(generate_nstring("Blender's Vertex Colors")) # name
+ vertexcolors = average_vertexcolors(mesh)
+ for i in range(len(vertexcolors)):
+ r, g, b, a = vertexcolors[i]
+ data.write(struct.pack(">H", i)) # vertex index
+ data.write(struct.pack(">fff", r/255.0, g/255.0, b/255.0))
+ return data.getvalue()
+
+# ====================================================
+# === Generate Per-Face Vertex Colors (VMAD Chunk) ===
+# ====================================================
+def generate_vmad_vc(mesh):
+ data = cStringIO.StringIO()
+ data.write("RGB ") # type
+ data.write(struct.pack(">H", 3)) # dimension
+ data.write(generate_nstring("Blender's Vertex Colors")) # name
+ for i in range(len(mesh.faces)):
+ if not i%100 and mod_meshtools.show_progress:
+ Blender.Window.DrawProgressBar(float(i)/len(mesh.faces), "Writing Vertex Colors")
+ numfaceverts = len(mesh.faces[i].v)
+ for j in range(numfaceverts-1, -1, -1): # Reverse order
+ r = mesh.faces[i].col[j].r
+ g = mesh.faces[i].col[j].g
+ b = mesh.faces[i].col[j].b
+ v = mesh.faces[i].v[j].index
+ data.write(struct.pack(">H", v)) # vertex index
+ data.write(struct.pack(">H", i)) # face index
+ data.write(struct.pack(">fff", r/255.0, g/255.0, b/255.0))
+ return data.getvalue()
+
+# ================================================
+# === Generate Per-Face UV Coords (VMAD Chunk) ===
+# ================================================
+def generate_vmad_uv(mesh):
+ data = cStringIO.StringIO()
+ data.write("TXUV") # type
+ data.write(struct.pack(">H", 2)) # dimension
+ data.write(generate_nstring("Blender's UV Coordinates")) # name
+ for i in range(len(mesh.faces)):
+ if not i%100 and mod_meshtools.show_progress:
+ Blender.Window.DrawProgressBar(float(i)/len(mesh.faces), "Writing UV Coordinates")
+ numfaceverts = len(mesh.faces[i].v)
+ for j in range(numfaceverts-1, -1, -1): # Reverse order
+ U,V = mesh.faces[i].uv[j]
+ v = mesh.faces[i].v[j].index
+ data.write(struct.pack(">H", v)) # vertex index
+ data.write(struct.pack(">H", i)) # face index
+ data.write(struct.pack(">ff", U, V))
+ return data.getvalue()
+
+# ======================================
+# === Generate Variable-Length Index ===
+# ======================================
+def generate_vx(index):
+ if index < 0xFF00:
+ value = struct.pack(">H", index) # 2-byte index
+ else:
+ value = struct.pack(">L", index | 0xFF000000) # 4-byte index
+ return value
+
+# ===================================
+# === Generate Faces (POLS Chunk) ===
+# ===================================
+def generate_pols(mesh):
+ data = cStringIO.StringIO()
+ data.write("FACE") # polygon type
+ for i in range(len(mesh.faces)):
+ if not i%100 and mod_meshtools.show_progress:
+ Blender.Window.DrawProgressBar(float(i)/len(mesh.faces), "Writing Faces")
+ data.write(struct.pack(">H", len(mesh.faces[i].v))) # numfaceverts
+ numfaceverts = len(mesh.faces[i].v)
+ for j in range(numfaceverts-1, -1, -1): # Reverse order
+ index = mesh.faces[i].v[j].index
+ data.write(generate_vx(index))
+ return data.getvalue()
+
+# =================================================
+# === Generate Polygon Tag Mapping (PTAG Chunk) ===
+# =================================================
+def generate_ptag(mesh, material_names):
+ data = cStringIO.StringIO()
+ data.write("SURF") # polygon tag type
+ for i in range(len(mesh.faces)): # numfaces
+ if not i%100 and mod_meshtools.show_progress:
+ Blender.Window.DrawProgressBar(float(i)/len(mesh.faces), "Writing Surface Indices")
+ data.write(generate_vx(i))
+ if (not mesh.materials) and (mod_meshtools.has_vertex_colors(mesh)): # vcols only
+ if mod_meshtools.average_vcols:
+ name = "\251 Per-Vert Vertex Colors"
+ else:
+ name = "\251 Per-Face Vertex Colors"
+ elif (mesh.materials) and (not mod_meshtools.has_vertex_colors(mesh)): # materials only
+ idx = mesh.faces[i].mat #erialIndex
+ name = mesh.materials[idx].name
+ elif (not mesh.materials) and (not mod_meshtools.has_vertex_colors(mesh)): # neither
+ name = "\251 Blender Default"
+ else: # both
+ idx = mesh.faces[i].mat
+ name = mesh.materials[idx].name
+ names = material_names.keys()
+ surfidx = names.index(name)
+ data.write(struct.pack(">H", surfidx)) # surface index
+ return data.getvalue()
+
+# ===================================================
+# === Generate VC Surface Definition (SURF Chunk) ===
+# ===================================================
+def generate_vcol_surf(mesh):
+ data = cStringIO.StringIO()
+ if mod_meshtools.average_vcols and mod_meshtools.has_vertex_colors(mesh):
+ surface_name = generate_nstring("\251 Per-Vert Vertex Colors")
+ else:
+ surface_name = generate_nstring("\251 Per-Face Vertex Colors")
+ data.write(surface_name)
+ data.write("\0\0")
+
+ data.write("COLR")
+ data.write(struct.pack(">H", 14))
+ data.write(struct.pack(">fffH", 1, 1, 1, 0))
+
+ data.write("DIFF")
+ data.write(struct.pack(">H", 6))
+ data.write(struct.pack(">fH", 0.0, 0))
+
+ data.write("LUMI")
+ data.write(struct.pack(">H", 6))
+ data.write(struct.pack(">fH", 1.0, 0))
+
+ data.write("VCOL")
+ data.write(struct.pack(">H", 34))
+ data.write(struct.pack(">fH4s", 1.0, 0, "RGB ")) # intensity, envelope, type
+ data.write(generate_nstring("Blender's Vertex Colors")) # name
+
+ data.write("CMNT") # material comment
+ comment = "Vertex Colors: Exported from Blender\256 " + mod_meshtools.blender_version_str
+ comment = generate_nstring(comment)
+ data.write(struct.pack(">H", len(comment)))
+ data.write(comment)
+ return data.getvalue()
+
+# ================================================
+# === Generate Surface Definition (SURF Chunk) ===
+# ================================================
+def generate_surf(material_name):
+ data = cStringIO.StringIO()
+ data.write(generate_nstring(material_name))
+ data.write("\0\0")
+
+ material = Blender.Material.Get(material_name)
+ R,G,B = material.R, material.G, material.B
+ data.write("COLR")
+ data.write(struct.pack(">H", 14))
+ data.write(struct.pack(">fffH", R, G, B, 0))
+
+ data.write("DIFF")
+ data.write(struct.pack(">H", 6))
+ data.write(struct.pack(">fH", material.ref, 0))
+
+ data.write("LUMI")
+ data.write(struct.pack(">H", 6))
+ data.write(struct.pack(">fH", material.emit, 0))
+
+ data.write("SPEC")
+ data.write(struct.pack(">H", 6))
+ data.write(struct.pack(">fH", material.spec, 0))
+
+ data.write("GLOS")
+ data.write(struct.pack(">H", 6))
+ gloss = material.hard / (255/2.0)
+ gloss = round(gloss, 1)
+ data.write(struct.pack(">fH", gloss, 0))
+
+ data.write("CMNT") # material comment
+ comment = material_name + ": Exported from Blender\256 " + mod_meshtools.blender_version_str
+ comment = generate_nstring(comment)
+ data.write(struct.pack(">H", len(comment)))
+ data.write(comment)
+ return data.getvalue()
+
+# =============================================
+# === Generate Default Surface (SURF Chunk) ===
+# =============================================
+def generate_default_surf():
+ data = cStringIO.StringIO()
+ material_name = "\251 Blender Default"
+ data.write(generate_nstring(material_name))
+ data.write("\0\0")
+
+ data.write("COLR")
+ data.write(struct.pack(">H", 14))
+ data.write(struct.pack(">fffH", 1, 1, 1, 0))
+
+ data.write("DIFF")
+ data.write(struct.pack(">H", 6))
+ data.write(struct.pack(">fH", 0.8, 0))
+
+ data.write("LUMI")
+ data.write(struct.pack(">H", 6))
+ data.write(struct.pack(">fH", 0, 0))
+
+ data.write("SPEC")
+ data.write(struct.pack(">H", 6))
+ data.write(struct.pack(">fH", 0.5, 0))
+
+ data.write("GLOS")
+ data.write(struct.pack(">H", 6))
+ gloss = 50 / (255/2.0)
+ gloss = round(gloss, 1)
+ data.write(struct.pack(">fH", gloss, 0))
+
+ data.write("CMNT") # material comment
+ comment = material_name + ": Exported from Blender\256 " + mod_meshtools.blender_version_str
+
+ # vals = map(chr, range(164,255,1))
+ # keys = range(164,255,1)
+ # keys = map(lambda x: `x`, keys)
+ # comment = map(None, keys, vals)
+ # comment = reduce(operator.add, comment)
+ # comment = reduce(operator.add, comment)
+
+ comment = generate_nstring(comment)
+ data.write(struct.pack(">H", len(comment)))
+ data.write(comment)
+ return data.getvalue()
+
+# ============================================
+# === Generate Object Comment (TEXT Chunk) ===
+# ============================================
+def generate_text():
+ comment = "Lightwave Export Script for Blender "
+ comment += mod_meshtools.blender_version_str + "\n"
+ comment += "by Anthony D'Agostino\n"
+ comment += "scorpius@netzero.com\n"
+ comment += "http://ourworld.compuserve.com/homepages/scorpius\n"
+ return generate_nstring(comment)
+
+# ==============================================
+# === Generate Description Line (DESC Chunk) ===
+# ==============================================
+def generate_desc():
+ comment = "Copyright 2002 Scorpius Entertainment"
+ return generate_nstring(comment)
+
+# ==================================================
+# === Generate Thumbnail Icon Image (ICON Chunk) ===
+# ==================================================
+def generate_icon():
+ data = cStringIO.StringIO()
+ file = open("f:/obj/radiosity/lwo2_icon.tga", "rb") # 60x60 uncompressed TGA
+ file.read(18)
+ icon_data = file.read(3600) # ?
+ file.close()
+ data.write(struct.pack(">HH", 0, 60))
+ data.write(icon_data)
+ #print len(icon_data)
+ return data.getvalue()
+
+# ===================
+# === Write Chunk ===
+# ===================
+def write_chunk(file, name, data):
+ file.write(name)
+ file.write(struct.pack(">L", len(data)))
+ file.write(data)
+
+# =============================
+# === Write LWO File Header ===
+# =============================
+def write_header(file, chunks):
+ chunk_sizes = map(len, chunks)
+ chunk_sizes = reduce(operator.add, chunk_sizes)
+ form_size = chunk_sizes + len(chunks)*8 + len("FORM")
+ file.write("FORM")
+ file.write(struct.pack(">L", form_size))
+ file.write("LWO2")
+
+def fs_callback(filename):
+ if filename.find('.lwo', -4) <= 0: filename += '.lwo'
+ write(filename)
+
+Blender.Window.FileSelector(fs_callback, "LWO Export")
diff --git a/release/scripts/lightwave_import.py b/release/scripts/lightwave_import.py
new file mode 100644
index 00000000000..5bfef5c907a
--- /dev/null
+++ b/release/scripts/lightwave_import.py
@@ -0,0 +1,172 @@
+#!BPY
+
+"""
+Name: 'LightWave...'
+Blender: 232
+Group: 'Import'
+Tooltip: 'Import LightWave Object File Format (*.lwo)'
+"""
+
+# +---------------------------------------------------------+
+# | Copyright (c) 2002 Anthony D'Agostino |
+# | http://www.redrival.com/scorpius |
+# | scorpius@netzero.com |
+# | April 21, 2002 |
+# | Released under the Blender Artistic Licence (BAL) |
+# | Import Export Suite v0.5 |
+# +---------------------------------------------------------+
+# | Read and write LightWave Object File Format (*.lwo) |
+# +---------------------------------------------------------+
+
+import Blender, mod_meshtools
+import struct, chunk, os, cStringIO, time, operator
+
+# =============================
+# === Read LightWave Format ===
+# =============================
+def read(filename):
+ start = time.clock()
+ file = open(filename, "rb")
+
+ # === LWO header ===
+ form_id, form_size, form_type = struct.unpack(">4s1L4s", file.read(12))
+ if (form_type != "LWOB") and (form_type != "LWO2"):
+ print "Can't read a file with the form_type:", form_type
+ return
+
+ objname = os.path.splitext(os.path.basename(filename))[0]
+
+ while 1:
+ try:
+ lwochunk = chunk.Chunk(file)
+ except EOFError:
+ break
+ if lwochunk.chunkname == "LAYR":
+ objname = read_layr(lwochunk)
+ elif lwochunk.chunkname == "PNTS": # Verts
+ verts = read_verts(lwochunk)
+ elif lwochunk.chunkname == "POLS" and form_type == "LWO2": # Faces v6.0
+ faces = read_faces_6(lwochunk)
+ mod_meshtools.create_mesh(verts, faces, objname)
+ elif lwochunk.chunkname == "POLS" and form_type == "LWOB": # Faces v5.5
+ faces = read_faces_5(lwochunk)
+ mod_meshtools.create_mesh(verts, faces, objname)
+ else: # Misc Chunks
+ lwochunk.skip()
+
+ Blender.Window.DrawProgressBar(1.0, "") # clear progressbar
+ file.close()
+ end = time.clock()
+ seconds = " in %.2f %s" % (end-start, "seconds")
+ if form_type == "LWO2": fmt = " (v6.0 Format)"
+ if form_type == "LWOB": fmt = " (v5.5 Format)"
+ message = "Successfully imported " + os.path.basename(filename) + fmt + seconds
+ mod_meshtools.print_boxed(message)
+
+# ==================
+# === Read Verts ===
+# ==================
+def read_verts(lwochunk):
+ data = cStringIO.StringIO(lwochunk.read())
+ numverts = lwochunk.chunksize/12
+ #$verts = []
+ verts = [None] * numverts
+ for i in range(numverts):
+ if not i%100 and mod_meshtools.show_progress:
+ Blender.Window.DrawProgressBar(float(i)/numverts, "Reading Verts")
+ x, y, z = struct.unpack(">fff", data.read(12))
+ #$verts.append((x, z, y))
+ verts[i] = (x, z, y)
+ return verts
+
+# =================
+# === Read Name ===
+# =================
+def read_name(file):
+ name = ""
+ while 1:
+ char = file.read(1)
+ if char == "\0": break
+ else: name += char
+ return name
+
+# ==================
+# === Read Layer ===
+# ==================
+def read_layr(lwochunk):
+ data = cStringIO.StringIO(lwochunk.read())
+ idx, flags = struct.unpack(">hh", data.read(4))
+ pivot = struct.unpack(">fff", data.read(12))
+ layer_name = read_name(data)
+ if not layer_name: layer_name = "No Name"
+ return layer_name
+
+# ======================
+# === Read Faces 5.5 ===
+# ======================
+def read_faces_5(lwochunk):
+ data = cStringIO.StringIO(lwochunk.read())
+ faces = []
+ i = 0
+ while i < lwochunk.chunksize:
+ if not i%100 and mod_meshtools.show_progress:
+ Blender.Window.DrawProgressBar(float(i)/lwochunk.chunksize, "Reading Faces")
+ facev = []
+ numfaceverts, = struct.unpack(">H", data.read(2))
+ for j in range(numfaceverts):
+ index, = struct.unpack(">H", data.read(2))
+ facev.append(index)
+ facev.reverse()
+ faces.append(facev)
+ surfaceindex, = struct.unpack(">H", data.read(2))
+ if surfaceindex < 0:
+ print "detail polygons follow, error."
+ return
+ i += (4+numfaceverts*2)
+ return faces
+
+# ==================================
+# === Read Variable-Length Index ===
+# ==================================
+def read_vx(data):
+ byte1, = struct.unpack(">B", data.read(1))
+ if byte1 != 0xFF: # 2-byte index
+ byte2, = struct.unpack(">B", data.read(1))
+ index = byte1*256 + byte2
+ index_size = 2
+ else: # 4-byte index
+ byte2, byte3, byte4 = struct.unpack(">3B", data.read(3))
+ index = byte2*65536 + byte3*256 + byte4
+ index_size = 4
+ return index, index_size
+
+# ======================
+# === Read Faces 6.0 ===
+# ======================
+def read_faces_6(lwochunk):
+ data = cStringIO.StringIO(lwochunk.read())
+ faces = []
+ polygon_type = data.read(4)
+ if polygon_type != "FACE":
+ print "No Faces Were Found. Polygon Type:", polygon_type
+ return ""
+ i = 0
+ while(i < lwochunk.chunksize-4):
+ if not i%100 and mod_meshtools.show_progress:
+ Blender.Window.DrawProgressBar(float(i)/lwochunk.chunksize, "Reading Faces")
+ facev = []
+ numfaceverts, = struct.unpack(">H", data.read(2))
+ i += 2
+
+ for j in range(numfaceverts):
+ index, index_size = read_vx(data)
+ i += index_size
+ facev.append(index)
+ facev.reverse()
+ faces.append(facev)
+ return faces
+
+def fs_callback(filename):
+ read(filename)
+
+Blender.Window.FileSelector(fs_callback, "LWO Import")
diff --git a/release/scripts/mod_flags.py b/release/scripts/mod_flags.py
deleted file mode 100644
index 810a510181a..00000000000
--- a/release/scripts/mod_flags.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# +---------------------------------------------------------+
-# | Copyright (c) 2002 Anthony D'Agostino |
-# | http://ourworld.compuserve.com/homepages/scorpius |
-# | scorpius@compuserve.com |
-# | October 25, 2002 |
-# | Released under the Blender Artistic Licence (BAL) |
-# | Import Export Suite v0.5 |
-# +---------------------------------------------------------+
-# | Share Global Variables Across Modules |
-# +---------------------------------------------------------+
-
-import Blender
-
-blender_version = Blender.Get('version')
-blender_version_str = `blender_version`[0] + '.' + `blender_version`[1:]
-
-show_progress = 1 # Set to 0 for faster performance
-average_vcols = 1 # Off for per-face, On for per-vertex
-overwrite_mesh_name = 0 # Set to 0 for safety
diff --git a/release/scripts/mod_meshtools.py b/release/scripts/mod_meshtools.py
index dbcdab513d5..95dae16b562 100644
--- a/release/scripts/mod_meshtools.py
+++ b/release/scripts/mod_meshtools.py
@@ -1,88 +1,93 @@
# +---------------------------------------------------------+
# | Copyright (c) 2001 Anthony D'Agostino |
-# | http://ourworld.compuserve.com/homepages/scorpius |
-# | scorpius@compuserve. |
+# | http://www.redrival.com/scorpius |
+# | scorpius@netzero.com |
# | September 28, 2002 |
# | Released under the Blender Artistic Licence (BAL) |
# | Import Export Suite v0.5 |
# +---------------------------------------------------------+
-# | Common Functions For All Modules |
+# | Common Functions & Global Variables For All IO Modules |
# +---------------------------------------------------------+
import Blender
-import sys#, random, operator
-import mod_flags
+import sys
+
+show_progress = 1 # Set to 0 for faster performance
+average_vcols = 1 # Off for per-face, On for per-vertex
+overwrite_mesh_name = 0 # Set to 0 to increment object-name version
+
+blender_version = Blender.Get('version')
+blender_version_str = `blender_version`[0] + '.' + `blender_version`[1:]
try:
- import random, operator
-# ===================================
-# ==== Append Faces To Face List ====
-# ===================================
- def append_faces(mesh, faces, facesuv, uvcoords):
- r = random.randrange(200, 255, 50)
- g = random.randrange(100, 200, 50)
- b = random.randrange(0, 100, 50)
- for i in range(len(faces)):
- if not i%100 and mod_flags.show_progress: Blender.Window.DrawProgressBar(float(i)/len(faces), "Generating Faces")
- numfaceverts=len(faces[i])
- if numfaceverts <= 4: # This face is a triangle or quad
+ import operator
+except:
+ msg = "Error: you need a full Python install to run this script."
+ mod_meshtools.print_boxed(msg)
+ Blender.Draw.PupMenu("ERROR%t|"+msg)
+
+# =================================
+# === Append Faces To Face List ===
+# =================================
+def append_faces(mesh, faces, facesuv, uvcoords):
+ for i in range(len(faces)):
+ if not i%100 and show_progress: Blender.Window.DrawProgressBar(float(i)/len(faces), "Generating Faces")
+ numfaceverts=len(faces[i])
+ if numfaceverts <= 4: # This face is a triangle or quad
+ face = Blender.NMesh.Face()
+ for j in range(numfaceverts):
+ index = faces[i][j]
+ face.v.append(mesh.verts[index])
+ if len(uvcoords) > 1:
+ uvidx = facesuv[i][j]
+ face.uv.append(uvcoords[uvidx])
+ face.mode = 0
+ face.col = [Blender.NMesh.Col()]*4
+ mesh.faces.append(face)
+ else: # Triangulate n-sided convex polygon.
+ a, b, c = 0, 1, 2 # Indices of first triangle.
+ for j in range(numfaceverts-2): # Number of triangles in polygon.
face = Blender.NMesh.Face()
- for j in range(numfaceverts):
- index = faces[i][j]
- face.v.append(mesh.verts[index])
- if len(uvcoords) > 1:
- uvidx = facesuv[i][j]
- face.uv.append(uvcoords[uvidx])
- face.mode = 0
- #face.col = [Blender.NMesh.Col(r, g, b)]*4 # Random color
- face.col = [Blender.NMesh.Col()]*4
+ face.v.append(mesh.verts[faces[i][a]])
+ face.v.append(mesh.verts[faces[i][b]])
+ face.v.append(mesh.verts[faces[i][c]])
+ b = c; c += 1
mesh.faces.append(face)
- else: # Triangulate n-sided convex polygon.
- a, b, c = 0, 1, 2 # Indices of first triangle.
- for j in range(numfaceverts-2): # Number of triangles in polygon.
- face = Blender.NMesh.Face()
- face.v.append(mesh.verts[faces[i][a]])
- face.v.append(mesh.verts[faces[i][b]])
- face.v.append(mesh.verts[faces[i][c]])
- b = c; c += 1
- mesh.faces.append(face)
- #face.smooth = 1
-
-# =====================================
-# ==== Append Verts to Vertex List ====
-# =====================================
- def append_verts(mesh, verts, normals):
- #print "Number of normals:", len(normals)
- #print "Number of verts :", len(verts)
- for i in range(len(verts)):
- if not i%100 and mod_flags.show_progress: Blender.Window.DrawProgressBar(float(i)/len(verts), "Generating Verts")
- x, y, z = verts[i]
- mesh.verts.append(Blender.NMesh.Vert(x, y, z))
- if normals:
- mesh.verts[i].no[0] = normals[i][0]
- mesh.verts[i].no[1] = normals[i][1]
- mesh.verts[i].no[2] = normals[i][2]
-
-# =============================
-# ==== Create Blender Mesh ====
-# =============================
- def create_mesh(verts, faces, objname, facesuv=[], uvcoords=[], normals=[]):
- if normals: normal_flag = 0
- else: normal_flag = 1
- mesh = Blender.NMesh.GetRaw()
- append_verts(mesh, verts, normals)
- append_faces(mesh, faces, facesuv, uvcoords)
- if not mod_flags.overwrite_mesh_name:
- objname = versioned_name(objname)
- Blender.NMesh.PutRaw(mesh, objname, normal_flag) # Name the Mesh
- Blender.Object.GetSelected()[0].name=objname # Name the Object
- Blender.Redraw()
-
-except ImportError: pass
+ #face.smooth = 1
-# ================================
-# ==== Increment Name Version ====
-# ================================
+# ===================================
+# === Append Verts to Vertex List ===
+# ===================================
+def append_verts(mesh, verts, normals):
+ #print "Number of normals:", len(normals)
+ #print "Number of verts :", len(verts)
+ for i in range(len(verts)):
+ if not i%100 and show_progress: Blender.Window.DrawProgressBar(float(i)/len(verts), "Generating Verts")
+ x, y, z = verts[i]
+ mesh.verts.append(Blender.NMesh.Vert(x, y, z))
+ if normals:
+ mesh.verts[i].no[0] = normals[i][0]
+ mesh.verts[i].no[1] = normals[i][1]
+ mesh.verts[i].no[2] = normals[i][2]
+
+# ===========================
+# === Create Blender Mesh ===
+# ===========================
+def create_mesh(verts, faces, objname, facesuv=[], uvcoords=[], normals=[]):
+ if normals: normal_flag = 0
+ else: normal_flag = 1
+ mesh = Blender.NMesh.GetRaw()
+ append_verts(mesh, verts, normals)
+ append_faces(mesh, faces, facesuv, uvcoords)
+ if not overwrite_mesh_name:
+ objname = versioned_name(objname)
+ Blender.NMesh.PutRaw(mesh, objname, normal_flag) # Name the Mesh
+ Blender.Object.GetSelected()[0].name=objname # Name the Object
+ Blender.Redraw()
+
+# ==============================
+# === Increment Name Version ===
+# ==============================
def versioned_name(objname):
existing_names = []
for object in Blender.Object.Get():
@@ -104,35 +109,40 @@ def versioned_name(objname):
break
return objname
-# =============================
-# ==== Print Text In A Box ====
-# =============================
+# ===========================
+# === Print Text In A Box ===
+# ===========================
def print_boxed(text):
lines = text.splitlines()
maxlinelen = max(map(len, lines))
- print '+-' + '-'*maxlinelen + '-+'
- for line in lines: print '| ' + line.ljust(maxlinelen) + ' |'
- print '+-' + '-'*maxlinelen + '-+'
-
+ if sys.platform[:3] == "win":
+ print chr(218)+chr(196) + chr(196)*maxlinelen + chr(196)+chr(191)
+ for line in lines:
+ print chr(179) + ' ' + line.ljust(maxlinelen) + ' ' + chr(179)
+ print chr(192)+chr(196) + chr(196)*maxlinelen + chr(196)+chr(217)
+ else:
+ print '+-' + '-'*maxlinelen + '-+'
+ for line in lines: print '| ' + line.ljust(maxlinelen) + ' |'
+ print '+-' + '-'*maxlinelen + '-+'
print '\a\r', # beep when done
-# =================================================
-# ==== Get Euler Angles From A Rotation Matrix ====
-# =================================================
-#def mat2euler(mat):
-# angle_y = -math.asin(mat[0][2])
-# c = math.cos(angle_y)
-# if math.fabs(c) > 0.005:
-# angle_x = math.atan2(mat[1][2]/c, mat[2][2]/c)
-# angle_z = math.atan2(mat[0][1]/c, mat[0][0]/c)
-# else:
-# angle_x = 0.0
-# angle_z = -math.atan2(mat[1][0], mat[1][1])
-# return (angle_x, angle_y, angle_z)
-
-# ============================
-# ==== Transpose A Matrix ====
-# ============================
+# ===============================================
+# === Get euler angles from a rotation matrix ===
+# ===============================================
+def mat2euler(mat):
+ angle_y = -math.asin(mat[0][2])
+ c = math.cos(angle_y)
+ if math.fabs(c) > 0.005:
+ angle_x = math.atan2(mat[1][2]/c, mat[2][2]/c)
+ angle_z = math.atan2(mat[0][1]/c, mat[0][0]/c)
+ else:
+ angle_x = 0.0
+ angle_z = -math.atan2(mat[1][0], mat[1][1])
+ return (angle_x, angle_y, angle_z)
+
+# ==========================
+# === Transpose A Matrix ===
+# ==========================
def transpose(A):
S = len(A)
T = len(A[0])
@@ -142,37 +152,177 @@ def transpose(A):
B[i][j] = A[j][i]
return B
-#def append_ntimes(Seq, N):
-# Seq = reduce(operator.add, Seq) # Flatten once
-# if N == 1: return Seq
-# return append_ntimes(Seq, N-1)
-
-
-
-# print "mesh.has_col ", mesh.has_col
-# print "mesh.hasVertexColours()", mesh.hasVertexColours()
-# print "mesh.hasFaceUV() ", mesh.hasFaceUV()
-# print "mesh.has_uvco ", mesh.has_uvco
-
-# # =============================
-# # ==== Create Blender Mesh ====
-# # =============================
-# def create_mesh_old(verts, faces, objname):
-# mesh = Blender.NMesh.GetRaw()
-# # === Vertex List ===
-# for i in range(len(verts)):
-# x, y, z = verts[i]
-# mesh.verts.append(Blender.NMesh.Vert(x, y ,z))
-# # === Face List ===
-# for i in range(len(faces)):
-# face = Blender.NMesh.Face()
-# for j in range(len(faces[i])):
-# index = faces[i][j]
-# face.v.append(mesh.verts[index])
-# mesh.faces.append(face)
-# # === Name the Object ===
-# Blender.NMesh.PutRaw(mesh, objname)
-# object = Blender.Object.GetSelected()
-# object[0].name=objname
-# Blender.Redraw()
+# =======================
+# === Apply Transform ===
+# =======================
+def apply_transform(vertex, matrix):
+ x, y, z = vertex
+ xloc, yloc, zloc = matrix[3][0], matrix[3][1], matrix[3][2]
+ xcomponent = x*matrix[0][0] + y*matrix[1][0] + z*matrix[2][0] + xloc
+ ycomponent = x*matrix[0][1] + y*matrix[1][1] + z*matrix[2][1] + yloc
+ zcomponent = x*matrix[0][2] + y*matrix[1][2] + z*matrix[2][2] + zloc
+ vertex = [xcomponent, ycomponent, zcomponent]
+ return vertex
+
+# =========================
+# === Has Vertex Colors ===
+# =========================
+def has_vertex_colors(mesh):
+ # My replacement/workaround for hasVertexColours()
+ # The docs say:
+ # "Warning: If a mesh has both vertex colours and textured faces,
+ # this function will return False. This is due to the way Blender
+ # deals internally with the vertex colours array (if there are
+ # textured faces, it is copied to the textured face structure and
+ # the original array is freed/deleted)."
+ try:
+ return mesh.faces[0].col[0]
+ except:
+ return 0
+
+# ===========================
+# === Generate Edge Table ===
+# ===========================
+def generate_edgetable(mesh):
+ edge_table = {}
+ numfaces = len(mesh.faces)
+
+ for i in range(numfaces):
+ if not i%100 and show_progress:
+ Blender.Window.DrawProgressBar(float(i)/numfaces, "Generating Edge Table")
+ if len(mesh.faces[i].v) == 4: # Process Quadrilaterals
+ generate_entry_from_quad(mesh, i, edge_table)
+ elif len(mesh.faces[i].v) == 3: # Process Triangles
+ generate_entry_from_tri(mesh, i, edge_table)
+ else: # Skip This Face
+ print "Face #", i, "was skipped."
+
+ # === Sort Edge_Table Keys & Add Edge Indices ===
+ i = 0
+ keys = edge_table.keys()
+ keys.sort()
+ for key in keys:
+ edge_table[key][6] = i
+ i += 1
+
+ # === Replace Tuples With Indices ===
+ for key in keys:
+ for i in [2,3,4,5]:
+ if edge_table.has_key(edge_table[key][i]):
+ edge_table[key][i] = edge_table[edge_table[key][i]][6]
+ else:
+ keyrev = (edge_table[key][i][1], edge_table[key][i][0])
+ edge_table[key][i] = edge_table[keyrev][6]
+
+ return edge_table
+
+# ================================
+# === Generate Entry From Quad ===
+# ================================
+def generate_entry_from_quad(mesh, i, edge_table):
+ vertex4, vertex3, vertex2, vertex1 = mesh.faces[i].v
+
+ if has_vertex_colors(mesh):
+ vcolor4, vcolor3, vcolor2, vcolor1 = mesh.faces[i].col
+ Acol = (vcolor1.r/255.0, vcolor1.g/255.0, vcolor1.b/255.0)
+ Bcol = (vcolor2.r/255.0, vcolor2.g/255.0, vcolor2.b/255.0)
+ Ccol = (vcolor3.r/255.0, vcolor3.g/255.0, vcolor3.b/255.0)
+ Dcol = (vcolor4.r/255.0, vcolor4.g/255.0, vcolor4.b/255.0)
+
+ # === verts are upper case, edges are lower case ===
+ A, B, C, D = vertex1.index, vertex2.index, vertex3.index, vertex4.index
+ a, b, c, d = (A, B), (B, C), (C, D), (D, A)
+
+ if edge_table.has_key((B, A)):
+ edge_table[(B, A)][1] = i
+ edge_table[(B, A)][4] = d
+ edge_table[(B, A)][5] = b
+ if has_vertex_colors(mesh): edge_table[(B, A)][8] = Bcol
+ else:
+ if has_vertex_colors(mesh):
+ edge_table[(A, B)] = [i, None, d, b, None, None, None, Bcol, None]
+ else:
+ edge_table[(A, B)] = [i, None, d, b, None, None, None]
+
+ if edge_table.has_key((C, B)):
+ edge_table[(C, B)][1] = i
+ edge_table[(C, B)][4] = a
+ edge_table[(C, B)][5] = c
+ if has_vertex_colors(mesh): edge_table[(C, B)][8] = Ccol
+ else:
+ if has_vertex_colors(mesh):
+ edge_table[(B, C)] = [i, None, a, c, None, None, None, Ccol, None]
+ else:
+ edge_table[(B, C)] = [i, None, a, c, None, None, None]
+
+ if edge_table.has_key((D, C)):
+ edge_table[(D, C)][1] = i
+ edge_table[(D, C)][4] = b
+ edge_table[(D, C)][5] = d
+ if has_vertex_colors(mesh): edge_table[(D, C)][8] = Dcol
+ else:
+ if has_vertex_colors(mesh):
+ edge_table[(C, D)] = [i, None, b, d, None, None, None, Dcol, None]
+ else:
+ edge_table[(C, D)] = [i, None, b, d, None, None, None]
+
+ if edge_table.has_key((A, D)):
+ edge_table[(A, D)][1] = i
+ edge_table[(A, D)][4] = c
+ edge_table[(A, D)][5] = a
+ if has_vertex_colors(mesh): edge_table[(A, D)][8] = Acol
+ else:
+ if has_vertex_colors(mesh):
+ edge_table[(D, A)] = [i, None, c, a, None, None, None, Acol, None]
+ else:
+ edge_table[(D, A)] = [i, None, c, a, None, None, None]
+
+# ====================================
+# === Generate Entry From Triangle ===
+# ====================================
+def generate_entry_from_tri(mesh, i, edge_table):
+ vertex3, vertex2, vertex1 = mesh.faces[i].v
+
+ if has_vertex_colors(mesh):
+ vcolor3, vcolor2, vcolor1, _vcolor4_ = mesh.faces[i].col
+ Acol = (vcolor1.r/255.0, vcolor1.g/255.0, vcolor1.b/255.0)
+ Bcol = (vcolor2.r/255.0, vcolor2.g/255.0, vcolor2.b/255.0)
+ Ccol = (vcolor3.r/255.0, vcolor3.g/255.0, vcolor3.b/255.0)
+
+ # === verts are upper case, edges are lower case ===
+ A, B, C = vertex1.index, vertex2.index, vertex3.index
+ a, b, c = (A, B), (B, C), (C, A)
+
+ if edge_table.has_key((B, A)):
+ edge_table[(B, A)][1] = i
+ edge_table[(B, A)][4] = c
+ edge_table[(B, A)][5] = b
+ if has_vertex_colors(mesh): edge_table[(B, A)][8] = Bcol
+ else:
+ if has_vertex_colors(mesh):
+ edge_table[(A, B)] = [i, None, c, b, None, None, None, Bcol, None]
+ else:
+ edge_table[(A, B)] = [i, None, c, b, None, None, None]
+
+ if edge_table.has_key((C, B)):
+ edge_table[(C, B)][1] = i
+ edge_table[(C, B)][4] = a
+ edge_table[(C, B)][5] = c
+ if has_vertex_colors(mesh): edge_table[(C, B)][8] = Ccol
+ else:
+ if has_vertex_colors(mesh):
+ edge_table[(B, C)] = [i, None, a, c, None, None, None, Ccol, None]
+ else:
+ edge_table[(B, C)] = [i, None, a, c, None, None, None]
+
+ if edge_table.has_key((A, C)):
+ edge_table[(A, C)][1] = i
+ edge_table[(A, C)][4] = b
+ edge_table[(A, C)][5] = a
+ if has_vertex_colors(mesh): edge_table[(A, C)][8] = Acol
+ else:
+ if has_vertex_colors(mesh):
+ edge_table[(C, A)] = [i, None, b, a, None, None, None, Acol, None]
+ else:
+ edge_table[(C, A)] = [i, None, b, a, None, None, None]
diff --git a/release/scripts/nendo_export.py b/release/scripts/nendo_export.py
new file mode 100644
index 00000000000..97796f03207
--- /dev/null
+++ b/release/scripts/nendo_export.py
@@ -0,0 +1,183 @@
+#!BPY
+
+"""
+Name: 'Nendo...'
+Blender: 232
+Group: 'Export'
+Tooltip: 'Export selected mesh to Nendo File Format (*.ndo)'
+"""
+
+# +---------------------------------------------------------+
+# | Copyright (c) 2001 Anthony D'Agostino |
+# | http://www.redrival.com/scorpius |
+# | scorpius@netzero.com |
+# | September 25, 2001 |
+# | Released under the Blender Artistic Licence (BAL) |
+# | Import Export Suite v0.5 |
+# +---------------------------------------------------------+
+# | Read and write Nendo File Format (*.nendo) |
+# +---------------------------------------------------------+
+
+import Blender, mod_meshtools
+import struct, time, sys, os
+
+# ==============================
+# === Write Nendo 1.1 Format ===
+# ==============================
+def write(filename):
+ start = time.clock()
+
+ objects = Blender.Object.GetSelected()
+ objname = objects[0].name
+ meshname = objects[0].data.name
+ mesh = Blender.NMesh.GetRaw(meshname)
+ obj = Blender.Object.Get(objname)
+
+ numedges = len(mesh.verts)+len(mesh.faces)-2
+ maxedges = (2**16)-1 # Blender & Wings can read more edges
+ #maxedges = 32767 # Nendo can't
+ if numedges > maxedges:
+ message = objname + " can't be exported to Nendo format (too many edges)."
+ Blender.Draw.PupMenu("Nendo Export Error%t|"+message)
+ return
+
+ edge_table = mod_meshtools.generate_edgetable(mesh)
+
+ try:
+ edge_table = mod_meshtools.generate_edgetable(mesh)
+ assert len(edge_table) <= maxedges
+ except:
+ edge_table = {}
+ message = "Unable to generate Edge Table for the object named " + meshname
+ mod_meshtools.print_boxed(message)
+ Blender.Draw.PupMenu("Edge Table Error%t|"+message)
+ Blender.Window.DrawProgressBar(1.0, "") # clear progressbar
+ return
+
+ file = open(filename, "wb")
+ write_header(file)
+ write_object_flags(file, objname)
+ write_edge_table(file, edge_table)
+ write_face_table(file, edge_table)
+ write_vert_table(file, edge_table, mesh)
+ write_texture(file)
+ file.close()
+
+ Blender.Window.DrawProgressBar(1.0, "") # clear progressbar
+ print '\a\r',
+ end = time.clock()
+ seconds = " in %.2f %s" % (end-start, "seconds")
+ message = "Successfully exported " + os.path.basename(filename) + seconds
+ mod_meshtools.print_boxed(message)
+
+# ====================
+# === Write Header ===
+# ====================
+def write_header(file):
+ file.write("nendo 1.1")
+ file.write("\0\0")
+ file.write("\1") # numobjects
+
+# ==========================
+# === Write Object Flags ===
+# ==========================
+def write_object_flags(file, objname):
+ file.write("\1") # good flag
+ file.write(struct.pack(">H", len(objname)))
+ file.write(objname)
+ file.write("\1"*4)
+ data = struct.pack(">18f",0,0,0,1,1,1,1,1,1,1,1,1,0.2,0.2,0.2,1,100,1)
+ data = "<<<< Nendo Export Script for Blender -- (c) 2004 Anthony D'Agostino >>>>"
+ file.write(data)
+
+# ========================
+# === Write Edge Table ===
+# ========================
+def write_edge_table(file, edge_table):
+ "+--------------------------------------+"
+ "| Wings: Sv Ev | Lf Rf | Lp Ls | Rp Rs |"
+ "| Nendo: Ev Sv | Lf Rf | Ls Rs | Rp Lp |"
+ "+--------------------------------------+"
+ #$print "edge_table"; pprint.pprint(edge_table)
+ file.write(struct.pack(">H", len(edge_table)))
+ keys = edge_table.keys()
+ keys.sort()
+ for key in keys:
+ file.write(struct.pack(">2H", key[0], key[1])) # Ev Sv
+ file.write(struct.pack(">2H", edge_table[key][0], edge_table[key][1])) # Lf Rf
+ file.write(struct.pack(">2H", edge_table[key][3], edge_table[key][5])) # Ls Rs
+ file.write(struct.pack(">2H", edge_table[key][4], edge_table[key][2])) # Rp Lp
+ file.write(struct.pack(">1B", 0)) # Hard flag
+ try:
+ r1,g1,b1 = map(lambda x:x*255, edge_table[key][8])
+ r2,g2,b2 = map(lambda x:x*255, edge_table[key][7])
+ except:
+ r1,g1,b1 = map(lambda x:x*255, [0.9,0.8,0.7])
+ r2,g2,b2 = r1,g1,b1
+ file.write(struct.pack(">8B", r1,g1,b1,0,r2,g2,b2,0))
+
+# ========================
+# === Write Face Table ===
+# ========================
+def write_face_table(file, edge_table):
+ face_table = build_face_table(edge_table)
+ #$print "face_table"; pprint.pprint(face_table)
+ file.write(struct.pack(">H", len(face_table)))
+ keys = face_table.keys()
+ keys.sort()
+ for key in keys:
+ file.write(struct.pack(">1H", face_table[key]))
+
+# ========================
+# === Write Vert Table ===
+# ========================
+def write_vert_table(file, edge_table, mesh):
+ vert_table = build_vert_table(edge_table)
+ #$print "vert_table"; pprint.pprint(vert_table)
+ file.write(struct.pack(">H", len(vert_table)))
+ keys = vert_table.keys()
+ keys.sort()
+ for key in keys:
+ vertex = mesh.verts[key].co
+ x,y,z = map(lambda x:x*10, vertex) # scale
+ idx = vert_table[key]
+ #$print "%i % f % f % f" % (idx, x, y, z)
+ file.write(struct.pack(">1H3f", idx, x, z, -y))
+
+# =====================
+# === Write Texture ===
+# =====================
+def write_texture(file):
+ file.write("\0"*5)
+
+# ========================
+# === Build Vert Table ===
+# ========================
+def build_vert_table(edge_table): # For Nendo
+ vert_table = {}
+ for key in edge_table.keys():
+ i = edge_table[key][6]
+ Sv = key[0]
+ Ev = key[1]
+ vert_table[Sv] = i
+ vert_table[Ev] = i
+ return vert_table
+
+# ========================
+# === Build Face Table ===
+# ========================
+def build_face_table(edge_table): # For Nendo
+ face_table = {}
+ for key in edge_table.keys():
+ i = edge_table[key][6]
+ Lf = edge_table[key][0]
+ Rf = edge_table[key][1]
+ face_table[Lf] = i
+ face_table[Rf] = i
+ return face_table
+
+def fs_callback(filename):
+ if filename.find('.ndo', -4) <= 0: filename += '.ndo'
+ write(filename)
+
+Blender.Window.FileSelector(fs_callback, "Nendo Export")
diff --git a/release/scripts/nendo_import.py b/release/scripts/nendo_import.py
new file mode 100644
index 00000000000..d14d99d87ab
--- /dev/null
+++ b/release/scripts/nendo_import.py
@@ -0,0 +1,205 @@
+#!BPY
+
+"""
+Name: 'Nendo...'
+Blender: 232
+Group: 'Import'
+Tooltip: 'Import Nendo Object File Format (*.ndo)'
+"""
+
+# +---------------------------------------------------------+
+# | Copyright (c) 2001 Anthony D'Agostino |
+# | http://www.redrival.com/scorpius |
+# | scorpius@netzero.com |
+# | September 25, 2001 |
+# | Released under the Blender Artistic Licence (BAL) |
+# | Import Export Suite v0.5 |
+# +---------------------------------------------------------+
+# | Read and write Nendo File Format (*.nendo) |
+# +---------------------------------------------------------+
+
+import Blender, mod_meshtools
+import struct, time, sys, os
+
+# =============================
+# === Read Nendo 1.x Format ===
+# =============================
+def read(filename):
+ start = time.clock()
+ file = open(filename, "rb")
+ version, numobjs = read_header(file)
+
+ for object in range(numobjs):
+ good, = struct.unpack(">B", file.read(1))
+ if not good: continue # an empty object
+ objname = read_object_flags(file)
+ edge_table = read_edge_table(file, version)
+ face_table = read_face_table(file)
+ vert_table = read_vert_table(file)
+ uv = read_uv(file)
+ verts = make_verts(vert_table)
+ faces = make_faces(edge_table)
+ mod_meshtools.create_mesh(verts, faces, objname)
+
+ Blender.Window.DrawProgressBar(1.0, "Done") # clear progressbar
+ file.close()
+ end = time.clock()
+ seconds = " in %.2f %s" % (end-start, "seconds")
+ message = "Successfully imported " + os.path.basename(filename) + seconds
+ message += " (%s)" % version.title()
+ mod_meshtools.print_boxed(message)
+
+# =======================
+# === Read The Header ===
+# =======================
+def read_header(file):
+ version, = struct.unpack(">9s", file.read(9))
+ misc, = struct.unpack(">H", file.read(2))
+ numobjs, = struct.unpack(">B", file.read(1))
+ if (version != "nendo 1.0") and (version != "nendo 1.1"):
+ mod_meshtools.print_boxed(file.name, "is not a Nendo file")
+ return
+ return version, numobjs
+
+# =========================
+# === Read Object Flags ===
+# =========================
+def read_object_flags(file):
+ namelen, = struct.unpack(">H", file.read(2))
+ objname = file.read(namelen)
+ visible, = struct.unpack(">B", file.read(1))
+ sensity, = struct.unpack(">B", file.read(1))
+ other, = struct.unpack(">H", file.read(2)) # or 2 more flags?
+ misc = struct.unpack(">18f", file.read(72))
+ return objname
+
+# =======================
+# === Read Edge Table ===
+# =======================
+def read_edge_table(file, version):
+ numedges, = struct.unpack(">H", file.read(2))
+ edge_table = {}
+ for i in range(numedges):
+ if not i%100 and mod_meshtools.show_progress:
+ Blender.Window.DrawProgressBar(float(i)/numedges, "Reading Edge Table")
+ edge = struct.unpack(">8H", file.read(16))
+ if version == "nendo 1.1":
+ hard, = struct.unpack(">B", file.read(1)) # edge hardness flag
+ color = struct.unpack(">8B", file.read(8))
+ edge_table[i] = edge
+ return edge_table
+
+# =======================
+# === Read Face Table ===
+# =======================
+def read_face_table(file):
+ numfaces, = struct.unpack(">H", file.read(2))
+ face_table = {}
+ for i in range(numfaces):
+ if not i%100 and mod_meshtools.show_progress:
+ Blender.Window.DrawProgressBar(float(i)/numfaces, "Reading Face Table")
+ face_table[i] = struct.unpack(">H", file.read(2))[0]
+ return face_table
+
+# =======================
+# === Read Vert Table ===
+# =======================
+def read_vert_table(file):
+ numverts, = struct.unpack(">H", file.read(2))
+ vert_table = []
+ for i in range(numverts):
+ if not i%100 and mod_meshtools.show_progress:
+ Blender.Window.DrawProgressBar(float(i)/numverts, "Reading Vertex Table")
+ w, x, y, z = struct.unpack(">H3f", file.read(14))
+ vert_table.append((w,(x, y, z)))
+ return vert_table
+
+# ====================
+# === Read Texture ===
+# ====================
+def read_uv(file):
+ numuvs, = struct.unpack(">H", file.read(2))
+ uvlist = struct.unpack(">"+`numuvs`+"H", file.read(numuvs*2))
+ numfacesT, = struct.unpack(">H", file.read(2))
+ facesT = struct.unpack(">"+`numfacesT`+"H", file.read(numfacesT*2))
+ textureflag, = struct.unpack(">B", file.read(1))
+ if textureflag:
+ xres, yres = struct.unpack(">2H", file.read(4))
+ print "%ix%i" % (xres, yres)
+ pixel = 0
+ while pixel < (xres*yres):
+ if not pixel%100 and mod_meshtools.show_progress:
+ Blender.Window.DrawProgressBar(float(pixel)/xres*yres, "Reading Texture")
+ count, = struct.unpack(">B", file.read(1))
+ rgb = file.read(3)
+ pixel = pixel+count
+ return numuvs
+
+# ==================
+# === Make Verts ===
+# ==================
+def make_verts(vert_table):
+ matrix = [ # Rotate 90*x and Scale 0.1
+ [0.1, 0.0, 0.0, 0.0],
+ [0.0, 0.0, 0.1, 0.0],
+ [0.0,-0.1, 0.0, 0.0],
+ [0.0, 0.0, 0.0, 1.0]]
+ verts = []
+ for i in range(len(vert_table)):
+ vertex = vert_table[i][1]
+ vertex = mod_meshtools.apply_transform(vertex, matrix)
+ verts.append(vertex)
+ return verts
+
+# =======================
+# === Make Face Table ===
+# =======================
+def make_face_table(edge_table): # For Nendo
+ face_table = {}
+ for i in range(len(edge_table)):
+ Lf = edge_table[i][2]
+ Rf = edge_table[i][3]
+ face_table[Lf] = i
+ face_table[Rf] = i
+ return face_table
+
+# =======================
+# === Make Vert Table ===
+# =======================
+def make_vert_table(edge_table): # For Nendo
+ vert_table = {}
+ for i in range(len(edge_table)):
+ Sv = edge_table[i][1]
+ Ev = edge_table[i][0]
+ vert_table[Sv] = i
+ vert_table[Ev] = i
+ return vert_table
+
+# ==================
+# === Make Faces ===
+# ==================
+def make_faces(edge_table): # For Nendo
+ face_table = make_face_table(edge_table)
+ faces=[]
+ #for i in range(len(face_table)):
+ for i in face_table.keys(): # avoids a whole class of errors
+ face_verts = []
+ current_edge = face_table[i]
+ while(1):
+ if i == edge_table[current_edge][3]:
+ next_edge = edge_table[current_edge][5] # Right successor edge
+ next_vert = edge_table[current_edge][1]
+ else:
+ next_edge = edge_table[current_edge][4] # Left successor edge
+ next_vert = edge_table[current_edge][0]
+ face_verts.append(next_vert)
+ current_edge = next_edge
+ if current_edge == face_table[i]: break
+ face_verts.reverse() # Flip all face normals
+ faces.append(face_verts)
+ return faces
+
+def fs_callback(filename):
+ read(filename)
+
+Blender.Window.FileSelector(fs_callback, "Nendo Import")
diff --git a/release/scripts/obj_export.py b/release/scripts/obj_export.py
new file mode 100644
index 00000000000..2fb84274c98
--- /dev/null
+++ b/release/scripts/obj_export.py
@@ -0,0 +1,161 @@
+#!BPY
+
+"""
+Name: 'OBJ Wavefront'
+Blender: 232
+Group: 'Export'
+Tooltip: 'Save a Wavefront OBJ File'
+"""
+
+# --------------------------------------------------------------------------
+# OBJ Export v0.9 by Campbell Barton (AKA Ideasman)
+# --------------------------------------------------------------------------
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# ***** END GPL LICENCE BLOCK *****
+# --------------------------------------------------------------------------
+
+#================================================#
+# Gets the world matrix of an object #
+# by multiplying by parents mat's recursively #
+# This only works in some simple situations, #
+# needs work.... #
+#================================================#
+def getWorldMat(ob):
+ mat = ob.getMatrix()
+ p = ob.getParent()
+ if p != None:
+ mat = mat + getWorldMat(p)
+ return mat
+
+#==================#
+# Apply Transform #
+#==================#
+def apply_transform(verts, matrix):
+
+ x, y, z = verts
+ xloc, yloc, zloc = matrix[3][0], matrix[3][1], matrix[3][2]
+ xcomponent = x*matrix[0][0] + y*matrix[1][0] + z*matrix[2][0] + xloc
+ ycomponent = x*matrix[0][1] + y*matrix[1][1] + z*matrix[2][1] + yloc
+ zcomponent = x*matrix[0][2] + y*matrix[1][2] + z*matrix[2][2] + zloc
+
+ return [xcomponent, ycomponent, zcomponent]
+
+
+#=====================================#
+# Apply Transform for vertex normals #
+# ignore the translation #
+#=====================================#
+def apply_normal_transform(verts, matrix):
+ x, y, z = verts
+ xcomponent = x*matrix[0][0] + y*matrix[1][0] + z*matrix[2][0]
+ ycomponent = x*matrix[0][1] + y*matrix[1][1] + z*matrix[2][1]
+ zcomponent = x*matrix[0][2] + y*matrix[1][2] + z*matrix[2][2]
+ return Mathutils.Vector([xcomponent, ycomponent, zcomponent])
+
+#====================================================#
+# Return a 6 deciaml point floating point value #
+# as a string that dosent have any python chars #
+#====================================================#
+def saneFloat(float):
+ #return '%(float)b' % vars() # 6 fp as house.hqx
+ return str('%f' % float) + ' '
+
+
+from Blender import *
+
+NULL_MAT = '(null)'
+
+def save_obj(filename):
+
+ file = open(filename, "w")
+
+ # Write Header
+ file.write('# Blender OBJ File: ' + Get('filename') + ' \n')
+ file.write('# www.blender.org\n')
+
+ # Get all meshs
+ for ob in Object.Get():
+ if ob.getType() == 'Mesh':
+ m = ob.getData()
+ if len(m.verts) > 0: # Make sure there is somthing to write.
+
+ # Set the default mat
+ currentMatName = ''
+
+ file.write('o ' + ob.getName() + '_' + m.name + '\n') # Write Object name
+
+ # Dosent work properly,
+ matrix = getWorldMat(ob)
+
+ # Vert
+ for v in m.verts:
+ # Transform the vert
+ vTx = apply_transform(v.co, matrix)
+
+ file.write('v ')
+ file.write(saneFloat(vTx[0]))
+ file.write(saneFloat(vTx[1]))
+ file.write(saneFloat(vTx[2]) + '\n')
+
+ # UV
+ for f in m.faces:
+ for uvIdx in range(len(f.v)):
+ file.write('vt ')
+ if f.uv:
+ file.write(saneFloat(f.uv[uvIdx][0]))
+ file.write(saneFloat(f.uv[uvIdx][1]))
+ else:
+ file.write('0.0 ')
+ file.write('0.0 ')
+
+ file.write('0.0' + '\n')
+
+ # NORMAL
+ for f in m.faces:
+ for v in f.v:
+ # Transform the normal
+ noTx = apply_normal_transform(v.no, matrix)
+ noTx.normalize()
+ file.write('vn ')
+ file.write(saneFloat(noTx[0]))
+ file.write(saneFloat(noTx[1]))
+ file.write(saneFloat(noTx[2]) + '\n')
+
+ uvIdx = 0
+ for f in m.faces:
+ # Check material and change if needed.
+ if len(m.materials) > f.mat:
+ if currentMatName != m.materials[f.mat].getName():
+ currentMatName = m.materials[f.mat].getName()
+ file.write('usemtl ' + currentMatName + '\n')
+
+ elif currentMatName != NULL_MAT:
+ currentMatName = NULL_MAT
+ file.write('usemtl ' + currentMatName + '\n')
+
+ file.write('f ')
+ for v in f.v:
+ file.write( str(m.verts.index(v) +1) + '/') # Vert IDX
+ file.write( str(uvIdx +1) + '/') # UV IDX
+ file.write( str(uvIdx +1) + ' ') # NORMAL IDX
+ uvIdx+=1
+ file.write('\n')
+
+ file.close()
+
+Window.FileSelector(save_obj, 'SELECT OBJ FILE')
diff --git a/release/scripts/obj_import.py b/release/scripts/obj_import.py
new file mode 100644
index 00000000000..856b156deb5
--- /dev/null
+++ b/release/scripts/obj_import.py
@@ -0,0 +1,245 @@
+#!BPY
+
+"""
+Name: 'OBJ Wavefront'
+Blender: 232
+Group: 'Import'
+Tooltip: 'Load a Wavefront OBJ File'
+ """
+
+# --------------------------------------------------------------------------
+# OBJ Import v0.9 by Campbell Barton (AKA Ideasman)
+# --------------------------------------------------------------------------
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# ***** END GPL LICENCE BLOCK *****
+# --------------------------------------------------------------------------
+
+WHITESPACE = [' ', '\n', '\r', '\t', '\f', '\v'] # used for the split function.
+NULL_MAT = '(null)' # Name for mesh's that have no mat set.
+
+MATLIMIT = 16
+
+#==============================================#
+# Strips the slashes from the back of a string #
+#==============================================#
+def stripPath(path):
+ for CH in range(len(path), 0, -1):
+ if path[CH-1] == "/" or path[CH-1] == "\\":
+ path = path[CH:]
+ break
+ return path
+
+#====================================================#
+# Strips the prefix off the name before writing #
+#====================================================#
+def stripName(name): # name is a string
+ prefixDelimiter = '.'
+ return name[ : name.find(prefixDelimiter) ]
+
+#================================================================#
+# Replace module deps 'string' for join and split # #
+# - Split splits a string into a list, and join does the reverse #
+#================================================================#
+def split(splitString, WHITESPACE):
+ splitList = []
+ charIndex = 0
+ while charIndex < len(splitString):
+ # Skip white space
+ while charIndex < len(splitString):
+ if splitString[charIndex] in WHITESPACE:
+ charIndex += 1
+ else:
+ break
+
+ # Gather text that is not white space and append to splitList
+ startWordCharIndex = charIndex
+ while charIndex < len(splitString):
+ if splitString[charIndex] in WHITESPACE: break
+ charIndex += 1
+
+ # Now we have the first and last chars we can append the word to the list
+ if charIndex != startWordCharIndex:
+ splitList.append(splitString[startWordCharIndex:charIndex])
+
+ return splitList
+
+#===============================#
+# Join list items into a string #
+#===============================#
+def join(joinList):
+ joinedString = ""
+ for listItem in joinList:
+ joinedString = joinedString + ' ' + str(listItem)
+
+ # Remove the first space
+ joinedString = joinedString[1:]
+ return joinedString
+
+
+from Blender import *
+
+def load_obj(file):
+ # This gets a mat or creates one of the requested name if none exist.
+ def getMat(matName):
+ # Make a new mat
+ try:
+ return Material.Get(matName)
+ except:
+ return Material.New(matName)
+
+ def applyMat(mesh, f, mat):
+ # Check weather the 16 mat limit has been met.
+ if len( mesh.materials ) >= MATLIMIT:
+ print 'Warning, max material limit reached, using an existing material'
+ return mesh, f
+
+ mIdx = 0
+ for m in mesh.materials:
+ if m.getName() == mat.getName():
+ break
+ mIdx+=1
+
+ if mIdx == len(mesh.materials):
+ mesh.addMaterial(mat)
+
+ f.mat = mIdx
+ return mesh, f
+
+ # Get the file name with no path or .obj
+ fileName = stripName( stripPath(file) )
+
+ fileLines = open(file, 'r').readlines()
+
+ mesh = NMesh.GetRaw() # new empty mesh
+
+ objectName = 'mesh' # If we cant get one, use this
+
+ uvMapList = [] # store tuple uv pairs here
+
+ nullMat = getMat(NULL_MAT)
+
+ currentMat = nullMat # Use this mat.
+
+ # Main loop
+ lIdx = 0
+ while lIdx < len(fileLines):
+ l = split(fileLines[lIdx], WHITESPACE)
+
+ # Detect a line that will be idnored
+ if len(l) == 0:
+ pass
+ elif l[0] == '#' or len(l) == 0:
+ pass
+ # VERTEX
+ elif l[0] == 'v':
+ # This is a new vert, make a new mesh
+ mesh.verts.append( NMesh.Vert(eval(l[1]), eval(l[2]), eval(l[3]) ) )
+
+ elif l[0] == 'vn':
+ pass
+
+ elif l[0] == 'vt':
+ # This is a new vert, make a new mesh
+ uvMapList.append( (eval(l[1]), eval(l[2])) )
+
+ elif l[0] == 'f':
+
+ # Make a face with the correct material.
+ f = NMesh.Face()
+ mesh, f = applyMat(mesh, f, currentMat)
+
+ # Set up vIdxLs : Verts
+ # Set up vtIdxLs : UV
+ vIdxLs = []
+ vtIdxLs = []
+ for v in l[1:]:
+ objVert = split( v, ['/'] )
+
+ # VERT INDEX
+ vIdxLs.append(eval(objVert[0]) -1)
+ # UV
+ if len(objVert) == 1:
+ vtIdxLs.append(eval(objVert[0]) -1) # Sticky UV coords
+ else:
+ vtIdxLs.append(eval(objVert[1]) -1) # Seperate UV coords
+
+ # Quads only, we could import quads using the method below but it polite to import a quad as a quad.f
+ if len(vIdxLs) == 4:
+ f.v.append(mesh.verts[vIdxLs[0]])
+ f.v.append(mesh.verts[vIdxLs[1]])
+ f.v.append(mesh.verts[vIdxLs[2]])
+ f.v.append(mesh.verts[vIdxLs[3]])
+ # UV MAPPING
+ if uvMapList:
+ if vtIdxLs[0] < len(uvMapList):
+ f.uv.append( uvMapList[ vtIdxLs[0] ] )
+ if vtIdxLs[1] < len(uvMapList):
+ f.uv.append( uvMapList[ vtIdxLs[1] ] )
+ if vtIdxLs[2] < len(uvMapList):
+ f.uv.append( uvMapList[ vtIdxLs[2] ] )
+ if vtIdxLs[3] < len(uvMapList):
+ f.uv.append( uvMapList[ vtIdxLs[3] ] )
+ mesh.faces.append(f) # move the face onto the mesh
+
+ elif len(vIdxLs) >= 3: # This handles tri's and fans
+ for i in range(len(vIdxLs)-2):
+ f = NMesh.Face()
+ mesh, f = applyMat(mesh, f, currentMat)
+ f.v.append(mesh.verts[vIdxLs[0]])
+ f.v.append(mesh.verts[vIdxLs[i+1]])
+ f.v.append(mesh.verts[vIdxLs[i+2]])
+ # UV MAPPING
+ if uvMapList:
+ if vtIdxLs[0] < len(uvMapList):
+ f.uv.append( uvMapList[ vtIdxLs[0] ] )
+ if vtIdxLs[1] < len(uvMapList):
+ f.uv.append( uvMapList[ vtIdxLs[i+1] ] )
+ if vtIdxLs[2] < len(uvMapList):
+ f.uv.append( uvMapList[ vtIdxLs[i+2] ] )
+
+ mesh.faces.append(f) # move the face onto the mesh
+
+ # is o the only vert/face delimeter?
+ # if not we could be screwed.
+ elif l[0] == 'o':
+ # Make sure the objects is worth puttong
+ if len(mesh.verts) > 0:
+ NMesh.PutRaw(mesh, fileName + '_' + objectName)
+ # Make new mesh
+ mesh = NMesh.GetRaw()
+
+ # New mesh name
+ objectName = join(l[1:]) # Use join in case of spaces
+
+ # New texture list
+ uvMapList = []
+
+ elif l[0] == 'usemtl':
+ if l[1] == '(null)':
+ currentMat = NULL_MAT
+ else:
+ currentMat = getMat(join(l[1:])) # Use join in case of spaces
+
+ lIdx+=1
+
+ # We need to do this to put the last object.
+ # All other objects will be put alredy
+ if len(mesh.verts) > 0:
+ NMesh.PutRaw(mesh, fileName + '_' + objectName)
+
+Window.FileSelector(load_obj, 'SELECT OBJ FILE')
diff --git a/release/scripts/off_export.py b/release/scripts/off_export.py
index 9648c1c3271..de843561e4c 100644
--- a/release/scripts/off_export.py
+++ b/release/scripts/off_export.py
@@ -9,8 +9,8 @@ Tooltip: 'Export selected mesh to Object File Format (*.off)'
# +---------------------------------------------------------+
# | Copyright (c) 2002 Anthony D'Agostino |
-# | http://ourworld.compuserve.com/homepages/scorpius |
-# | scorpius@compuserve.com |
+# | http://www.redrival.com/scorpius |
+# | scorpius@netzero.com |
# | February 3, 2001 |
# | Released under the Blender Artistic Licence (BAL) |
# | Import Export Suite v0.5 |
@@ -18,9 +18,8 @@ Tooltip: 'Export selected mesh to Object File Format (*.off)'
# | Read and write Object File Format (*.off) |
# +---------------------------------------------------------+
-import Blender
+import Blender, mod_meshtools
#import time
-import mod_flags, mod_meshtools
# ==============================
# ====== Write OFF Format ======
@@ -42,14 +41,14 @@ def write(filename):
# === Vertex List ===
for i in range(len(mesh.verts)):
- if not i%100 and mod_flags.show_progress:
+ if not i%100 and mod_meshtools.show_progress:
Blender.Window.DrawProgressBar(float(i)/len(mesh.verts), "Writing Verts")
x, y, z = mesh.verts[i].co
file.write("%f %f %f\n" % (x, y, z))
# === Face List ===
for i in range(len(mesh.faces)):
- if not i%100 and mod_flags.show_progress:
+ if not i%100 and mod_meshtools.show_progress:
Blender.Window.DrawProgressBar(float(i)/len(mesh.faces), "Writing Faces")
file.write(`len(mesh.faces[i].v)`+' ')
mesh.faces[i].v.reverse()
diff --git a/release/scripts/off_import.py b/release/scripts/off_import.py
index 9f7fd5eb9f7..44c5bf6ff05 100644
--- a/release/scripts/off_import.py
+++ b/release/scripts/off_import.py
@@ -9,8 +9,8 @@ Tooltip: 'Import Object File Format (*.off)'
# +---------------------------------------------------------+
# | Copyright (c) 2002 Anthony D'Agostino |
-# | http://ourworld.compuserve.com/homepages/scorpius |
-# | scorpius@compuserve.com |
+# | http://www.redrival.com/scorpius |
+# | scorpius@netzero.com |
# | February 3, 2001 |
# | Released under the Blender Artistic Licence (BAL) |
# | Import Export Suite v0.5 |
@@ -18,9 +18,8 @@ Tooltip: 'Import Object File Format (*.off)'
# | Read and write Object File Format (*.off) |
# +---------------------------------------------------------+
-import Blender
+import Blender, mod_meshtools
#import time
-import mod_flags, mod_meshtools
# =============================
# ====== Read OFF Format ======
@@ -40,7 +39,7 @@ def read(filename):
# === Vertex List ===
for i in range(numverts):
- if not i%100 and mod_flags.show_progress:
+ if not i%100 and mod_meshtools.show_progress:
Blender.Window.DrawProgressBar(float(i)/numverts, "Reading Verts")
x, y, z = file.readline().split()
x, y, z = float(x), float(y), float(z)
@@ -48,7 +47,7 @@ def read(filename):
# === Face List ===
for i in range(numfaces):
- if not i%100 and mod_flags.show_progress:
+ if not i%100 and mod_meshtools.show_progress:
Blender.Window.DrawProgressBar(float(i)/numfaces, "Reading Faces")
line = file.readline().split()
numfaceverts = len(line)-1
diff --git a/release/scripts/radiosity_export.py b/release/scripts/radiosity_export.py
index f87f8a1ef19..34c913dc1ef 100644
--- a/release/scripts/radiosity_export.py
+++ b/release/scripts/radiosity_export.py
@@ -9,8 +9,8 @@ Tooltip: 'Export selected mesh (with vertex colors) to Radiosity File Format (*.
# +---------------------------------------------------------+
# | Copyright (c) 2002 Anthony D'Agostino |
-# | http://ourworld.compuserve.com/homepages/scorpius |
-# | scorpius@compuserve.com |
+# | http://www.redrival.com/scorpius |
+# | scorpius@netzero.com |
# | April 11, 2002 |
# | Released under the Blender Artistic Licence (BAL) |
# | Import Export Suite v0.5 |
@@ -18,14 +18,15 @@ Tooltip: 'Export selected mesh (with vertex colors) to Radiosity File Format (*.
# | Read and write Radiosity File Format (*.radio) |
# +---------------------------------------------------------+
-import Blender
+import Blender, mod_meshtools
#import time
-import mod_flags, mod_meshtools
+
try:
import struct
except:
msg = "Error: you need a full Python install to run this script."
mod_meshtools.print_boxed(msg)
+ Blender.Draw.PupMenu("ERROR%t|"+msg)
# ================================
# ====== Write Radio Format ======
@@ -40,10 +41,11 @@ def write(filename):
mesh = Blender.NMesh.GetRaw(meshname)
obj = Blender.Object.Get(objname)
- if not mesh.hasVertexColours():
- message = "Please assign vertex colors before exporting.\n"
+ if not mod_meshtools.has_vertex_colors(mesh):
+ message = "Please assign vertex colors before exporting. \n"
message += objname + " object was not saved."
mod_meshtools.print_boxed(message)
+ Blender.Draw.PupMenu("ERROR%t|"+message)
return
# === Object Name ===
@@ -53,7 +55,7 @@ def write(filename):
# === Vertex List ===
file.write(struct.pack("<l", len(mesh.verts)))
for i in range(len(mesh.verts)):
- if not i%100 and mod_flags.show_progress:
+ if not i%100 and mod_meshtools.show_progress:
Blender.Window.DrawProgressBar(float(i)/len(mesh.verts), "Writing Verts")
x, y, z = mesh.verts[i].co
@@ -62,7 +64,7 @@ def write(filename):
# === Face List ===
file.write(struct.pack("<l", len(mesh.faces)))
for i in range(len(mesh.faces)):
- if not i%100 and mod_flags.show_progress:
+ if not i%100 and mod_meshtools.show_progress:
Blender.Window.DrawProgressBar(float(i)/len(mesh.faces), "Writing Faces")
file.write(struct.pack("<b", len(mesh.faces[i].v)))
diff --git a/release/scripts/radiosity_import.py b/release/scripts/radiosity_import.py
index d2e784b3ed4..46705855285 100644
--- a/release/scripts/radiosity_import.py
+++ b/release/scripts/radiosity_import.py
@@ -9,8 +9,8 @@ Tooltip: 'Import Radiosity File Format (*.radio) with vertex colors'
# +---------------------------------------------------------+
# | Copyright (c) 2002 Anthony D'Agostino |
-# | http://ourworld.compuserve.com/homepages/scorpius |
-# | scorpius@compuserve.com |
+# | http://www.redrival.com/scorpius |
+# | scorpius@netzero.com |
# | April 11, 2002 |
# | Released under the Blender Artistic Licence (BAL) |
# | Import Export Suite v0.5 |
@@ -18,14 +18,15 @@ Tooltip: 'Import Radiosity File Format (*.radio) with vertex colors'
# | Read and write Radiosity File Format (*.radio) |
# +---------------------------------------------------------+
-import Blender
+import Blender, mod_meshtools
#import time
-import mod_flags, mod_meshtools
+
try:
import struct
except:
msg = "Error: you need a full Python install to run this script."
mod_meshtools.print_boxed(msg)
+ Blender.Draw.PupMenu("ERROR%t|"+msg)
# ===============================
# ====== Read Radio Format ======
@@ -34,7 +35,7 @@ def read(filename):
#start = time.clock()
file = open(filename, "rb")
mesh = Blender.NMesh.GetRaw()
- mesh.addMaterial(Blender.Material.New())
+ #mesh.addMaterial(Blender.Material.New())
# === Object Name ===
namelen, = struct.unpack("<h", file.read(2))
@@ -43,7 +44,7 @@ def read(filename):
# === Vertex List ===
numverts, = struct.unpack("<l", file.read(4))
for i in range(numverts):
- if not i%100 and mod_flags.show_progress:
+ if not i%100 and mod_meshtools.show_progress:
Blender.Window.DrawProgressBar(float(i)/numverts, "Reading Verts")
x, y, z = struct.unpack("<fff", file.read(12))
mesh.verts.append(Blender.NMesh.Vert(x, y, z))
@@ -51,7 +52,7 @@ def read(filename):
# === Face List ===
numfaces, = struct.unpack("<l", file.read(4))
for i in range(numfaces):
- if not i%100 and mod_flags.show_progress:
+ if not i%100 and mod_meshtools.show_progress:
Blender.Window.DrawProgressBar(float(i)/numfaces, "Reading Faces")
face = Blender.NMesh.Face()
diff --git a/release/scripts/raw_export.py b/release/scripts/raw_export.py
index 809f6e2354e..9c2407c41a7 100644
--- a/release/scripts/raw_export.py
+++ b/release/scripts/raw_export.py
@@ -9,8 +9,8 @@ Tooltip: 'Export selected mesh to Raw Triangle Format (*.raw)'
# +---------------------------------------------------------+
# | Copyright (c) 2002 Anthony D'Agostino |
-# | http://ourworld.compuserve.com/homepages/scorpius |
-# | scorpius@compuserve.com |
+# | http://www.redrival.com/scorpius |
+# | scorpius@netzero.com |
# | April 28, 2002 |
# | Released under the Blender Artistic Licence (BAL) |
# | Import Export Suite v0.5 |
@@ -18,13 +18,13 @@ Tooltip: 'Export selected mesh to Raw Triangle Format (*.raw)'
# | Read and write RAW Triangle File Format (*.raw) |
# +---------------------------------------------------------+
-import Blender, sys
+import Blender, mod_meshtools
+import sys
#import time
-import mod_flags, mod_meshtools
-# ===================================
-# ==== Write RAW Triangle Format ====
-# ===================================
+# =================================
+# === Write RAW Triangle Format ===
+# =================================
def write(filename):
#start = time.clock()
file = open(filename, "wb")
diff --git a/release/scripts/raw_import.py b/release/scripts/raw_import.py
index c080d028e3d..f1b6cc511e4 100644
--- a/release/scripts/raw_import.py
+++ b/release/scripts/raw_import.py
@@ -9,8 +9,8 @@ Tooltip: 'Import Raw Triangle File Format (*.raw)'
# +---------------------------------------------------------+
# | Copyright (c) 2002 Anthony D'Agostino |
-# | http://ourworld.compuserve.com/homepages/scorpius |
-# | scorpius@compuserve.com |
+# | http://www.redrival.com/scorpius |
+# | scorpius@netzero.com |
# | April 28, 2002 |
# | Released under the Blender Artistic Licence (BAL) |
# | Import Export Suite v0.5 |
@@ -18,13 +18,12 @@ Tooltip: 'Import Raw Triangle File Format (*.raw)'
# | Read and write RAW Triangle File Format (*.raw) |
# +---------------------------------------------------------+
-import Blender
+import Blender, mod_meshtools
#import time
-import mod_flags, mod_meshtools
-# ==================================
-# ==== Read RAW Triangle Format ====
-# ==================================
+# ================================
+# === Read RAW Triangle Format ===
+# ================================
def read(filename):
#start = time.clock()
file = open(filename, "rb")
diff --git a/release/scripts/rvk1_torvk2.py b/release/scripts/rvk1_torvk2.py
new file mode 100644
index 00000000000..efe6c9a9559
--- /dev/null
+++ b/release/scripts/rvk1_torvk2.py
@@ -0,0 +1,108 @@
+#!BPY
+
+""" Registration info for Blender menus: <- these words are ignored
+Name: 'Rvk1 to Rvk2'
+Blender: 232
+Group: 'Animation'
+Tip: 'Copy deform data (not surf. subdiv) of active obj to rvk of the 2nd selected obj.'
+"""
+
+#----------------------------------------------
+# jm soler (c) 05/2004 : 'Rvk1toRvk2' release under blender artistic licence
+#----------------------------------------------
+# Blender Artistic License
+# http://download.blender.org/documentation/html/x21254.html
+#----------------------------------------------------
+# Copy the rvk (1, or armature, lattice, or
+# any mesh deformation except surface
+# sbdivision) of the active object to rvk (2) of
+# the second selected object. Create rvk or modify
+# absolute key if needed.
+#----------------------------------------------
+# official Page :
+# http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_rvk1versrvk2.htm
+# download the script :
+# http://jmsoler.free.fr/util/blenderfile/py/rvk1_torvk2.py
+# Communicate upon problems or errors:
+# http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender
+#----------------------------------------------
+# Page officielle :
+# http://jmsoler.free.fr/util/blenderfile/py/rvk1_torvk2.py
+# Communiquer les problemes et erreurs sur:
+# http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender
+#---------------------------------------------
+# changelog :
+# - a test on mesh parity between getraw and getrawfromobject
+# when there is active subsurf division.
+# - can copy, or not, vertex groups from the original mesh.
+#---------------------------------------------
+
+import Blender
+from Blender import NMesh,Draw,Object
+
+def rvk2rvk():
+ try:
+ SUBMODIF=0
+ RVK2=Object.GetSelected()[0]
+ RVK1=Object.GetSelected()[1]
+
+ FRAME=Blender.Get('curframe')
+
+ DATA2=RVK2.getData()
+
+ if DATA2.getMode() & NMesh.Modes['SUBSURF'] :
+ SUBSURF2=DATA2.getSubDivLevels()
+ if SUBSURF2[0]!=0:
+ name = "The active object has a subsurf level different from 0 ... %t| Let script do the the modification for you ? %x1| you prefer do it yourself ? %x2 "
+ result = Draw.PupMenu(name)
+ if result==1:
+ DATA2.mode=DATA2.mode-NMesh.Modes['SUBSURF']
+ SUBMODIF=1
+ DATA2.update()
+ RVK2.makeDisplayList()
+ Blender.Redraw()
+ else:
+ return
+
+ RVK2NAME=Object.GetSelected()[0].getName()
+ mesh=RVK1.getData()
+ meshrvk2=NMesh.GetRawFromObject(RVK2NAME)
+
+ name = "Do you want to replace or add vertex groups ? %t| YES %x1| NO ? %x2 "
+ result = Draw.PupMenu(name)
+
+ if result==1:
+ GROUPNAME1=mesh.getVertGroupNames()
+ if len(GROUPNAME1)!=0:
+ for GROUP1 in GROUPNAME1:
+ mesh.removeVertGroup(GROUP1)
+
+ GROUPNAME2=DATA2.getVertGroupNames()
+ if len(GROUPNAME2)!=0:
+ for GROUP2 in GROUPNAME2:
+ mesh.addVertGroup(GROUP2)
+ mesh.assignVertsToGroup(GROUP2,DATA2.getVertsFromGroup(GROUP2),1.0,'replace')
+
+ for v in meshrvk2.verts:
+ i= meshrvk2.verts.index(v)
+ v1=mesh.verts[i]
+ for n in range(len(v.co)):
+ v1.co[n]=v.co[n]
+
+ mesh.update()
+ mesh.insertKey(FRAME,'relative')
+ mesh.update()
+ RVK1.makeDisplayList()
+
+ if SUBMODIF==1:
+ DATA2.mode=DATA2.mode+NMesh.Modes['SUBSURF']
+ SUBMODIF=0
+ DATA2.update()
+ RVK2.makeDisplayList()
+
+ Blender.Redraw()
+ except:
+ print 'problem : not object selected or not mesh'
+
+
+rvk2rvk()
diff --git a/release/scripts/slp_import.py b/release/scripts/slp_import.py
new file mode 100644
index 00000000000..a066e333445
--- /dev/null
+++ b/release/scripts/slp_import.py
@@ -0,0 +1,76 @@
+#!BPY
+
+"""
+Name: 'SLP (Pro Engineer)...'
+Blender: 232
+Group: 'Import'
+Tooltip: 'Import SLP (Pro Engineer) File Format (*.raw)'
+"""
+
+# +---------------------------------------------------------+
+# | Copyright (c) 2004 Anthony D'Agostino |
+# | http://www.redrival.com/scorpius |
+# | scorpius@netzero.com |
+# | May 3, 2004 |
+# | Released under the Blender Artistic Licence (BAL) |
+# | Import Export Suite v0.5 |
+# +---------------------------------------------------------+
+# | Read and write SLP Triangle File Format (*.slp) |
+# +---------------------------------------------------------+
+
+import Blender, mod_meshtools
+#import time
+
+# ================================
+# === Read SLP Triangle Format ===
+# ================================
+def read(filename):
+ #start = time.clock()
+ file = open(filename, "rb")
+
+ raw = []
+ for line in file.readlines():
+ data = line.split()
+ if data[0] == "vertex":
+ vert = map(float, data[1:])
+ raw.append(vert)
+
+ tri = []
+ for i in range(0, len(raw), 3):
+ tri.append(raw[i] + raw[i+1] + raw[i+2])
+
+ #$import pprint; pprint.pprint(tri)
+
+ # Collect data from RAW format
+ faces = []
+ for line in tri:
+ f1, f2, f3, f4, f5, f6, f7, f8, f9 = line
+ faces.append([(f1, f2, f3), (f4, f5, f6), (f7, f8, f9)])
+
+ # Generate verts and faces lists, without duplicates
+ verts = []
+ coords = {}
+ index = 0
+ for i in range(len(faces)):
+ for j in range(len(faces[i])):
+ vertex = faces[i][j]
+ if not coords.has_key(vertex):
+ coords[vertex] = index
+ index += 1
+ verts.append(vertex)
+ faces[i][j] = coords[vertex]
+
+ objname = Blender.sys.splitext(Blender.sys.basename(filename))[0]
+
+ mod_meshtools.create_mesh(verts, faces, objname)
+ Blender.Window.DrawProgressBar(1.0, '') # clear progressbar
+ file.close()
+ #end = time.clock()
+ #seconds = " in %.2f %s" % (end-start, "seconds")
+ message = "Successfully imported " + Blender.sys.basename(filename)# + seconds
+ mod_meshtools.print_boxed(message)
+
+def fs_callback(filename):
+ read(filename)
+
+Blender.Window.FileSelector(fs_callback, "SLP Import")
diff --git a/release/scripts/truespace_export.py b/release/scripts/truespace_export.py
new file mode 100644
index 00000000000..8013278e528
--- /dev/null
+++ b/release/scripts/truespace_export.py
@@ -0,0 +1,265 @@
+#!BPY
+
+"""
+Name: 'TrueSpace...'
+Blender: 232
+Group: 'Export'
+Tooltip: 'Export selected meshes to trueSpace File Format (*.cob)'
+"""
+
+# +---------------------------------------------------------+
+# | Copyright (c) 2001 Anthony D'Agostino |
+# | http://www.redrival.com/scorpius |
+# | scorpius@netzero.com |
+# | June 12, 2001 |
+# | Released under the Blender Artistic Licence (BAL) |
+# | Import Export Suite v0.5 |
+# +---------------------------------------------------------+
+# | Read and write Caligari trueSpace File Format (*.cob) |
+# +---------------------------------------------------------+
+
+import Blender, mod_meshtools
+import struct, os, cStringIO, time
+
+# ==============================
+# === Write trueSpace Format ===
+# ==============================
+def write(filename):
+ start = time.clock()
+ file = open(filename, "wb")
+ objects = Blender.Object.GetSelected()
+
+ write_header(file)
+
+ G,P,V,U,M = 1000,2000,3000,4000,5000
+ for object in objects:
+ objname = object.name
+ meshname = object.data.name
+ mesh = Blender.NMesh.GetRaw(meshname)
+ obj = Blender.Object.Get(objname)
+ if not mesh: continue
+
+ grou = generate_grou('Group ' + `objects.index(object)+1`)
+ polh = generate_polh(objname, obj, mesh)
+ if mod_meshtools.has_vertex_colors(mesh): vcol = generate_vcol(mesh)
+ unit = generate_unit()
+ mat1 = generate_mat1(mesh)
+
+ if objects.index(object) == 0: X = 0
+
+ write_chunk(file, "Grou", 0, 1, G, X, grou)
+ write_chunk(file, "PolH", 0, 4, P, G, polh)
+ if mod_meshtools.has_vertex_colors(mesh) and vcol:
+ write_chunk(file, "VCol", 1, 0, V, P, vcol)
+ write_chunk(file, "Unit", 0, 1, U, P, unit)
+ write_chunk(file, "Mat1", 0, 5, M, P, mat1)
+
+ X = G
+ G,P,V,U,M = map(lambda x: x+1, [G,P,V,U,M])
+
+ write_chunk(file, "END ", 1, 0, 0, 0, '') # End Of File Chunk
+
+ Blender.Window.DrawProgressBar(1.0, '') # clear progressbar
+ file.close()
+ end = time.clock()
+ seconds = " in %.2f %s" % (end-start, "seconds")
+ message = "Successfully exported " + os.path.basename(filename) + seconds
+ mod_meshtools.print_boxed(message)
+
+# =============================
+# === Write COB File Header ===
+# =============================
+def write_header(file):
+ file.write("Caligari V00.01BLH"+" "*13+"\n")
+
+# ===================
+# === Write Chunk ===
+# ===================
+def write_chunk(file, name, major, minor, chunk_id, parent_id, data):
+ file.write(name)
+ file.write(struct.pack("<2h", major, minor))
+ file.write(struct.pack("<2l", chunk_id, parent_id))
+ file.write(struct.pack("<1l", len(data)))
+ file.write(data)
+
+# ============================================
+# === Generate PolH (Polygonal Data) Chunk ===
+# ============================================
+def generate_polh(objname, obj, mesh):
+ data = cStringIO.StringIO()
+ write_ObjectName(data, objname)
+ write_LocalAxes(data, obj)
+ write_CurrentPosition(data, obj)
+ write_VertexList(data, mesh)
+ uvcoords = write_UVCoordsList(data, mesh)
+ write_FaceList(data, mesh, uvcoords)
+ return data.getvalue()
+
+# === Write Object Name ===
+def write_ObjectName(data, objname):
+ data.write(struct.pack("<h", 0)) # dupecount
+ data.write(struct.pack("<h", len(objname)))
+ data.write(objname)
+
+# === Write Local Axes ===
+def write_LocalAxes(data, obj):
+ data.write(struct.pack("<fff", obj.mat[3][0], obj.mat[3][1], obj.mat[3][2]))
+ data.write(struct.pack("<fff", obj.mat[0][0]/obj.SizeX, obj.mat[1][0]/obj.SizeX, obj.mat[2][0]/obj.SizeX))
+ data.write(struct.pack("<fff", obj.mat[0][1]/obj.SizeY, obj.mat[1][1]/obj.SizeY, obj.mat[2][1]/obj.SizeY))
+ data.write(struct.pack("<fff", obj.mat[0][2]/obj.SizeZ, obj.mat[1][2]/obj.SizeZ, obj.mat[2][2]/obj.SizeZ))
+
+# === Write Current Position ===
+def write_CurrentPosition(data, obj):
+ data.write(struct.pack("<ffff", obj.mat[0][0], obj.mat[0][1], obj.mat[0][2], obj.mat[3][0]))
+ data.write(struct.pack("<ffff", obj.mat[1][0], obj.mat[1][1], obj.mat[1][2], obj.mat[3][1]))
+ data.write(struct.pack("<ffff", obj.mat[2][0], obj.mat[2][1], obj.mat[2][2], obj.mat[3][2]))
+
+# === Write Vertex List ===
+def write_VertexList(data, mesh):
+ data.write(struct.pack("<l", len(mesh.verts)))
+ for i in range(len(mesh.verts)):
+ if not i%100 and mod_meshtools.show_progress:
+ Blender.Window.DrawProgressBar(float(i)/len(mesh.verts), "Writing Verts")
+ x, y, z = mesh.verts[i].co
+ data.write(struct.pack("<fff", -y, x, z))
+
+# === Write UV Vertex List ===
+def write_UVCoordsList(data, mesh):
+ if not mesh.hasFaceUV():
+ data.write(struct.pack("<l", 1))
+ data.write(struct.pack("<2f", 0,0))
+ return {(0,0): 0}
+ # === Default UV Coords (one image per face) ===
+ # data.write(struct.pack("<l", 4))
+ # data.write(struct.pack("<8f", 0,0, 0,1, 1,1, 1,0))
+ # return {(0,0): 0, (0,1): 1, (1,1): 2, (1,0): 3}
+ # === Default UV Coords (one image per face) ===
+
+ # === collect, remove duplicates, add indices, and write the uv list ===
+ uvdata = cStringIO.StringIO()
+ uvcoords = {}
+ uvidx = 0
+ for i in range(len(mesh.faces)):
+ if not i%100 and mod_meshtools.show_progress:
+ Blender.Window.DrawProgressBar(float(i)/len(mesh.faces), "Writing UV Coords")
+ numfaceverts = len(mesh.faces[i].v)
+ for j in range(numfaceverts-1, -1, -1): # Reverse order
+ u,v = mesh.faces[i].uv[j]
+ if not uvcoords.has_key((u,v)):
+ uvcoords[(u,v)] = uvidx
+ uvidx += 1
+ uvdata.write(struct.pack("<ff", u,v))
+ uvdata = uvdata.getvalue()
+
+ numuvcoords = len(uvdata)/8
+ data.write(struct.pack("<l", numuvcoords))
+ data.write(uvdata)
+ #print "Number of uvcoords:", numuvcoords, '=', len(uvcoords)
+ return uvcoords
+
+# === Write Face List ===
+def write_FaceList(data, mesh, uvcoords):
+ data.write(struct.pack("<l", len(mesh.faces)))
+ for i in range(len(mesh.faces)):
+ if not i%100 and mod_meshtools.show_progress:
+ Blender.Window.DrawProgressBar(float(i)/len(mesh.faces), "Writing Faces")
+ numfaceverts = len(mesh.faces[i].v)
+ data.write(struct.pack("<B", 0x10)) # Cull Back Faces Flag
+ data.write(struct.pack("<h", numfaceverts))
+ data.write(struct.pack("<h", 0)) # Material Index
+ for j in range(numfaceverts-1, -1, -1): # Reverse order
+ index = mesh.faces[i].v[j].index
+ if mesh.hasFaceUV():
+ uv = mesh.faces[i].uv[j]
+ uvidx = uvcoords[uv]
+ else:
+ uvidx = 0
+ data.write(struct.pack("<ll", index, uvidx))
+
+# ===========================================
+# === Generate VCol (Vertex Colors) Chunk ===
+# ===========================================
+def generate_vcol(mesh):
+ data = cStringIO.StringIO()
+ data.write(struct.pack("<l", len(mesh.faces)))
+ uniquecolors = {}
+ unique_alpha = {}
+ for i in range(len(mesh.faces)):
+ if not i%100 and mod_meshtools.show_progress:
+ Blender.Window.DrawProgressBar(float(i)/len(mesh.faces), "Writing Vertex Colors")
+ numfaceverts = len(mesh.faces[i].v)
+ data.write(struct.pack("<ll", i, numfaceverts))
+ for j in range(numfaceverts-1, -1, -1): # Reverse order
+ r = mesh.faces[i].col[j].r
+ g = mesh.faces[i].col[j].g
+ b = mesh.faces[i].col[j].b
+ a = 100 # 100 is opaque in ts
+ uniquecolors[(r,g,b)] = None
+ unique_alpha[mesh.faces[i].col[j].a] = None
+ data.write(struct.pack("<BBBB", r,g,b,a))
+
+ #print "uniquecolors:", uniquecolors.keys()
+ #print "unique_alpha:", unique_alpha.keys()
+ if len(uniquecolors) == 1:
+ return None
+ else:
+ return data.getvalue()
+
+# ==================================
+# === Generate Unit (Size) Chunk ===
+# ==================================
+def generate_unit():
+ data = cStringIO.StringIO()
+ data.write(struct.pack("<h", 2))
+ return data.getvalue()
+
+# ======================================
+# === Generate Mat1 (Material) Chunk ===
+# ======================================
+def generate_mat1(mesh):
+ data = cStringIO.StringIO()
+ data.write(struct.pack("<h", 0))
+ data.write(struct.pack("<ccB", "p", "a", 0))
+ data.write(struct.pack("<fff", 1.0, 1.0, 1.0)) # rgb (0.0 - 1.0)
+ data.write(struct.pack("<fffff", 1, 1, 0, 0, 1))
+ if mesh.hasFaceUV():
+ tex_mapname = r"c:\image\maps\one-dot.tga"
+ data.write("t:")
+ data.write(struct.pack("<B", 0x00))
+ data.write(struct.pack("<h", len(tex_mapname)))
+ data.write(tex_mapname)
+ data.write(struct.pack("<4f", 0,0, 1,1))
+ return data.getvalue()
+
+# ============================
+# === Generate Group Chunk ===
+# ============================
+def generate_grou(name):
+ data = cStringIO.StringIO()
+ write_ObjectName(data, name)
+ data.write(struct.pack("<12f", 0,0,0, 1,0,0, 0,1,0, 0,0,1))
+ data.write(struct.pack("<12f", 1,0,0,0, 0,1,0,0, 0,0,1,0))
+ return data.getvalue()
+
+def fs_callback(filename):
+ if filename.find('.cob', -4) <= 0: filename += '.cob'
+ write(filename)
+
+Blender.Window.FileSelector(fs_callback, "COB Export")
+
+# === Matrix Differences between Blender & trueSpace ===
+#
+# For the 'Local Axes' values:
+# The x, y, and z-axis represent a simple rotation matrix.
+# This is equivalent to Blender's object matrix before it was
+# combined with the object's scaling matrix. Dividing each value
+# by the appropriate scaling factor (and transposing at the same
+# time) produces the original rotation matrix.
+#
+# For the 'Current Position' values:
+# This is equivalent to Blender's object matrix except that the
+# last row is omitted and the xyz location is used in the last
+# column. Binary format uses a 4x3 matrix, ascii format uses a 4x4
+# matrix.
+#
+# For Cameras: The matrix is a little confusing.
diff --git a/release/scripts/truespace_import.py b/release/scripts/truespace_import.py
new file mode 100644
index 00000000000..2b4f393d81f
--- /dev/null
+++ b/release/scripts/truespace_import.py
@@ -0,0 +1,229 @@
+#!BPY
+
+"""
+Name: 'TrueSpace...'
+Blender: 232
+Group: 'Import'
+Tooltip: 'Import trueSpace Object File Format (*.cob)'
+"""
+
+# +---------------------------------------------------------+
+# | Copyright (c) 2001 Anthony D'Agostino |
+# | http://www.redrival.com/scorpius |
+# | scorpius@netzero.com |
+# | June 12, 2001 |
+# | Released under the Blender Artistic Licence (BAL) |
+# | Import Export Suite v0.5 |
+# +---------------------------------------------------------+
+# | Read and write Caligari trueSpace File Format (*.cob) |
+# +---------------------------------------------------------+
+
+import Blender, mod_meshtools
+import struct, chunk, os, cStringIO, time
+
+# =======================
+# === COB Chunk Class ===
+# =======================
+class CobChunk(chunk.Chunk):
+ def __init__(self, file, align = 0, bigendian = 0, inclheader = 0): #$ COB
+ self.closed = 0
+ self.align = align # whether to align to word (2-byte) boundaries
+ if bigendian:
+ strflag = '>'
+ else:
+ strflag = '<'
+ self.file = file
+ self.chunkname = file.read(4)
+ if len(self.chunkname) < 4:
+ raise EOFError
+ self.major_ver, = struct.unpack(strflag+'h', file.read(2)) #$ COB
+ self.minor_ver, = struct.unpack(strflag+'h', file.read(2)) #$ COB
+ self.chunk_id, = struct.unpack(strflag+'l', file.read(4)) #$ COB
+ self.parent_id, = struct.unpack(strflag+'l', file.read(4)) #$ COB
+ try:
+ self.chunksize = struct.unpack(strflag+'l', file.read(4))[0]
+ except struct.error:
+ raise EOFError
+ if inclheader:
+ self.chunksize = self.chunksize - 20 #$ COB
+ self.size_read = 0
+ try:
+ self.offset = self.file.tell()
+ except:
+ self.seekable = 0
+ else:
+ self.seekable = 1
+
+# ============================
+# === Read COB File Header ===
+# ============================
+def read_header(file):
+ magic, = struct.unpack("<9s", file.read(9))
+ version, = struct.unpack("<6s", file.read(6))
+ format, = struct.unpack("<1c", file.read(1))
+ endian, = struct.unpack("<2s", file.read(2))
+ misc, = struct.unpack("13s", file.read(13))
+ newline, = struct.unpack("<1B", file.read(1))
+ return format
+
+# ========================================
+# === Read PolH (Polygonal Data) Chunk ===
+# ========================================
+def read_polh(chunk):
+ data = cStringIO.StringIO(chunk.read())
+ oname = read_ObjectName(data)
+ local = read_LocalAxes(data)
+ crpos = read_CurrentPosition(data)
+ verts = read_VertexList(data)
+ uvcoords = read_UVCoords(data)
+ faces, facesuv = read_FaceList(data, chunk)
+ return verts, faces, oname, facesuv, uvcoords
+
+# === Read Object Name ===
+def read_ObjectName(data):
+ dupecount, namelen = struct.unpack("<hh", data.read(4))
+ objname = data.read(namelen)
+ if objname == '': objname = 'NoName'
+ if dupecount > 0: objname = objname + ', ' + `dupecount`
+ return objname
+
+# === Read Local Axes ===
+def read_LocalAxes(data):
+ location = struct.unpack("<fff", data.read(12))
+ rotation_matrix=[]
+ for i in range(3):
+ row = struct.unpack("<fff", data.read(12))
+ #print "% f % f % f" % row
+ rotation_matrix.append(list(row))
+ #print
+ rotation_matrix = mod_meshtools.transpose(rotation_matrix)
+
+# === Read Current Position ===
+def read_CurrentPosition(data):
+ transformation_matrix=[]
+ for i in range(3):
+ row = struct.unpack("<ffff", data.read(16))
+ #print "% f % f % f % f" % row
+ transformation_matrix.append(list(row))
+ #print
+
+# === Read Vertex List ===
+def read_VertexList(data):
+ verts = []
+ numverts, = struct.unpack("<l", data.read(4))
+ for i in range(numverts):
+ if not i%100 and mod_meshtools.show_progress:
+ Blender.Window.DrawProgressBar(float(i)/numverts, "Reading Verts")
+ x, y, z = struct.unpack("<fff", data.read(12))
+ verts.append((y, -x, z))
+ return verts
+
+# === Read UV Vertex List ===
+def read_UVCoords(data):
+ uvcoords = []
+ numuvcoords, = struct.unpack("<l", data.read(4))
+ for i in range(numuvcoords):
+ if not i%100 and mod_meshtools.show_progress:
+ Blender.Window.DrawProgressBar(float(i)/numuvcoords, "Reading UV Coords")
+ uv = struct.unpack("<ff", data.read(8))
+ uvcoords.append(uv)
+
+ #print "num uvcoords:", len(uvcoords)
+ #for i in range(len(uvcoords)): print "%.4f, %.4f" % uvcoords[i]
+ return uvcoords
+
+# === Read Face List ===
+def read_FaceList(data, chunk):
+ faces = [] ; facesuv = []
+ numfaces, = struct.unpack("<l", data.read(4))
+ for i in range(numfaces):
+ if not i%100 and mod_meshtools.show_progress:
+ Blender.Window.DrawProgressBar(float(i)/numfaces, "Reading Faces")
+
+ face_flags, numfaceverts = struct.unpack("<Bh", data.read(3))
+
+ if (face_flags & 0x08) == 0x08:
+ print "face #" + `i-1` + " contains a hole."
+ pass
+ else:
+ data.read(2) # Material Index
+
+ facev = [] ; faceuv = []
+ for j in range(numfaceverts):
+ index, uvidx = struct.unpack("<ll", data.read(8))
+ facev.append(index); faceuv.append(uvidx)
+ facev.reverse() ; faceuv.reverse()
+ faces.append(facev) ; facesuv.append(faceuv)
+
+ if chunk.minor_ver == 6:
+ DrawFlags, RadiosityQuality = struct.unpack("<lh", data.read(6))
+ if chunk.minor_ver == 8:
+ DrawFlags, = struct.unpack("<l", data.read(4))
+
+ return faces , facesuv
+
+# =============================
+# === Read trueSpace Format ===
+# =============================
+def read(filename):
+ start = time.clock()
+ file = open(filename, "rb")
+
+ # === COB header ===
+ if read_header(file) == 'A':
+ print "Can't read ASCII format"
+ return
+
+ while 1:
+ try:
+ cobchunk = CobChunk(file)
+ except EOFError:
+ break
+ if cobchunk.chunkname == "PolH":
+ verts, faces, objname, facesuv, uvcoords = read_polh(cobchunk)
+ mod_meshtools.create_mesh(verts, faces, objname, facesuv, uvcoords)
+
+ '''
+ object = Blender.Object.GetSelected()
+ obj = Blender.Object.Get(objname)
+ obj.loc = location
+ obj.rot = mod_meshtools.mat2euler(rotation_matrix)
+ obj.size = (transformation_matrix[0][0]/rotation_matrix[0][0],
+ transformation_matrix[1][1]/rotation_matrix[1][1],
+ transformation_matrix[2][2]/rotation_matrix[2][2])
+
+ '''
+ else:
+ cobchunk.skip()
+
+ Blender.Window.DrawProgressBar(1.0, '') # clear progressbar
+ file.close()
+ end = time.clock()
+ seconds = " in %.2f %s" % (end-start, "seconds")
+ message = "Successfully imported " + os.path.basename(filename) + seconds
+ mod_meshtools.print_boxed(message)
+ #print "objname :", objname
+ #print "numverts:", len(verts)
+ #print "numfaces:", len(faces)
+
+def fs_callback(filename):
+ read(filename)
+
+Blender.Window.FileSelector(fs_callback, "COB Import")
+
+# === Matrix Differences between Blender & trueSpace ===
+#
+# For the 'Local Axes' values:
+# The x, y, and z-axis represent a simple rotation matrix.
+# This is equivalent to Blender's object matrix before it was
+# combined with the object's scaling matrix. Dividing each value
+# by the appropriate scaling factor (and transposing at the same
+# time) produces the original rotation matrix.
+#
+# For the 'Current Position' values:
+# This is equivalent to Blender's object matrix except that the
+# last row is omitted and the xyz location is used in the last
+# column. Binary format uses a 4x3 matrix, ascii format uses a 4x4
+# matrix.
+#
+# For Cameras: The matrix is a little confusing.
diff --git a/release/scripts/unweld044.py b/release/scripts/unweld044.py
new file mode 100644
index 00000000000..481aeab8aa2
--- /dev/null
+++ b/release/scripts/unweld044.py
@@ -0,0 +1,366 @@
+#!BPY
+""" Registration info for Blender menus: <- these words are ignored
+Name: 'UnWeld'
+Blender: 232
+Group: 'Modifiers'
+Tip: 'unweld all faces from one selected and commun vertex. Made vertex bevelling'
+"""
+
+# ------------------------------------------
+# Un-Weld script 0.4.4 beta
+#
+# split all faces from one selected vertex
+# (c) 2004 J-M Soler released under Blender Artistic License
+#----------------------------------------------
+# Official Page :
+# http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_faces2vertex.htm#exemple
+# Communicate problems and errors on:
+# http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender
+#----------------------------------------------
+# Blender Artistic License
+# http://download.blender.org/documentation/html/x21254.html
+#---------------------------------------------
+# Changelog
+#----------------------------------------------
+# 25/05 :
+# -- separate choise, normal (same place) or spread at random, middle of the face
+# -- works on several vertices too
+# -- Quite vertex bevelling on <<lone>> vertex : create hole in faces around this
+# vertex
+# 03/06 :
+# -- a sort of "bevelled vertex" extrusion controled by horizontal mouse
+# displacement. just a beta test to the mouse control.
+#----------------------------------------------
+# Page officielle :
+# http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_faces2vertex.htm#exemple
+# Communiquer les problemes et erreurs sur:
+# http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender
+# Blender Artistic License
+# http://download.blender.org/documentation/html/x21254.html
+#---------------------------------------------
+# Changelog
+#----------------------------------------------
+# 25/05 :
+# -- separation du choix, normal ou dispersion hasardeuse, milieu de face
+# -- sommets multiples /
+# -- Quite vertex bevelling on lone vertex : create hole in faces around the
+# vertex
+# 03/06 :
+# -- a sort of "bevelled vertex" extrusion controled by horizontal mouse
+# displacement
+#----------------------------------------------
+
+import Blender
+from Blender import Noise
+from Blender.Draw import *
+from Blender.BGL import *
+
+Nr=Noise.random
+decal=0.03
+t=[0.0,0.0,0.0]
+pl=[]
+orig=[]
+
+DEBUG = 0
+SUBSURF=0
+DIM=Create(1.0)
+
+def Tampon(v,t):
+ for n in range(len(v)): t[n]=t[n]+v[n]
+ return t
+
+def freeTampon(t):
+ for n in range(3): t[n]=0.0
+ return t
+
+def TamponMoyen(t,f):
+ for n in range(3): t[n]/=len(f)
+ return t
+
+def appliqueMoyenne(v,t):
+ for n in range(len(v)): v[n]=t[n]
+ return v
+
+def docF(f0,f):
+ try:
+ f0.mat=f.mat
+ f0.uv=f.uv
+ f0.col=f.col
+ f0.image=f.image
+ return f0
+ except:
+ pass
+
+def listConnecterFace(me,lebon):
+ listf2v={}
+ #tri des faces connectees aux sommets selectionnes
+ for f in me.faces:
+ for v in f.v:
+ if v==lebon:
+ if v.index not in listf2v.keys():
+ listf2v[me.verts.index(v)]=[f]
+ elif f not in listf2v[me.verts.index(v)]:
+ listf2v[me.verts.index(v)].append(f)
+ return listf2v
+
+def creerFaceSupplementaire(me,lebon,listf2v):
+ global t
+ for f in listf2v[lebon.index]:
+ f0=Blender.NMesh.Face()
+ if result==3: t=freeTampon(t)
+ for v in f.v:
+ if result==3: t=Tampon(v,t)
+ if v!=lebon:
+ f0.append(v)
+ else:
+ if result==2:
+ nv=Blender.NMesh.Vert(lebon.co[0]+Nr()*decal,lebon.co[1]+Nr()*decal,lebon.co[2]+Nr()*decal)
+ else:
+ nv=Blender.NMesh.Vert(lebon.co[0],lebon.co[1],lebon.co[2])
+ me.verts.append(nv)
+ f0.append(me.verts[me.verts.index(nv)])
+ localise=me.verts.index(nv)
+ docF(f0,f)
+
+ if result==3:
+ t=TamponMoyen(t,f0.v)
+ me.verts[localise]=appliqueMoyenne(me.verts[localise],t)
+ me.faces.append(f0)
+ del me.verts[me.verts.index(lebon)]
+ for f in listf2v[lebon.index]:
+ del me.faces[me.faces.index(f)]
+ return me
+
+def collecte_edge(listf2v,me,lebon):
+ back=0
+ edgelist = []
+ vertlist = []
+ if DEBUG : print listf2v
+ for face in listf2v[lebon.index]:
+ if len(face.v) == 4:
+ vlist = [0,1,2,3,0]
+ elif len(face.v) == 3:
+ vlist = [0,1,2,0]
+ else:
+ vlist = [0,1]
+ for i in range(len(vlist)-1):
+ vert0 = min(face.v[vlist[i]].index,face.v[vlist[i+1]].index)
+ vert1 = max(face.v[vlist[i]].index,face.v[vlist[i+1]].index)
+ edgeinlist = 0
+ if vert0==lebon.index or vert1==lebon.index:
+ for edge in edgelist:
+ if ((edge[0]==vert0) and (edge[1]==vert1)):
+ edgeinlist = 1
+ edge[2] = edge[2]+1
+ edge.append(me.faces.index(face))
+ break
+ if edgeinlist==0:
+ edge = [vert0,vert1,1,me.faces.index(face)]
+ edgelist.append(edge)
+
+ for edge in edgelist:
+ #print edge
+ if len(edge)==4:
+ del edgelist[edgelist.index(edge)]
+
+ edges=len(edgelist)
+ if DEBUG : print 'number of edges : ',edges," Edge list : " ,edgelist
+ return edges, edgelist
+
+MouseClickG= Blender.Draw.LEFTMOUSE
+MouseClickD= Blender.Draw.RIGHTMOUSE
+MouseClickM= Blender.Draw.MIDDLEMOUSE
+
+mouse_x=1
+mouse_y=1
+
+x=1
+y=1
+
+debut=0
+
+def D():
+ size=Buffer(GL_FLOAT, 4)
+ glGetFloatv(GL_SCISSOR_BOX, size)
+ size= size.list
+ glColor3f(0.1, 0.1, 0.15)
+ glRasterPos2f(10, size[3]-16)
+ Text("Quit = Qkey")
+ glRasterPos2f(10, size[3]-36)
+ Text("Mouse to the Rigth = Increase")
+ glRasterPos2f(10, size[3]-56)
+ Text("Mouse to the Left = Decrease")
+
+def E(evt,val):
+ global mouse_x,x,pl,orig,me,debut
+ global mouse_y,y, MouseClickG,MouseClickD,MouseClickM
+ if (evt== QKEY): Exit()
+
+ if (evt == MOUSEX):
+ mouse_x = val
+ pos=x-mouse_x
+ x=mouse_x
+ if pos==0:
+ pos=1
+ deplace(pl,orig,abs(pos)/pos)
+
+ if (evt == MOUSEY): mouse_y = val
+
+def BE(evt):
+ pass
+
+
+def deplace(pl,orig,n):
+ global me, OBJECT
+ for p in pl:
+ #print p, orig,len(me.verts)
+ me.verts[p].co[0]+=n*orig[0]
+ me.verts[p].co[1]+=n*orig[1]
+ me.verts[p].co[2]+=n*orig[2]
+ me.update()
+ Blender.Redraw()
+
+
+def VertexBevel(result):
+ global t,pl, orig,me, SUBSURF
+ unique=0
+ for v in me.verts:
+ if v.sel==1:
+ lebon=v
+ unique+=1
+
+ if unique==1:
+ edges=0
+ edgelist=[]
+ vertlist=[]
+ orig=lebon.no[:]
+ listf2v=listConnecterFace(me,lebon)
+ edges, edgelist = collecte_edge(listf2v,me,lebon)
+ for f in listf2v[lebon.index]:
+ f0=Blender.NMesh.Face()
+ for v in f.v:
+ if v!=lebon:
+ f0.append(v)
+ else:
+ nv=Blender.NMesh.Vert(lebon.co[0],lebon.co[1],lebon.co[2])
+ nv.sel=1
+ me.verts.append(nv)
+ f0.append(me.verts[me.verts.index(nv)])
+ for e in edgelist:
+ if e[-1]==me.faces.index(f) or e[-2]==me.faces.index(f):
+ if me.verts.index(nv) not in e:
+ e.insert(0,me.verts.index(nv))
+ docF(f0,f)
+ me.faces.append(f0)
+ vertlist.append([me.verts.index(nv),me.faces.index(f)])
+ for e in edgelist :
+ del e[e.index(lebon.index)]
+ f0=Blender.NMesh.Face()
+ for n in range(3):
+ f0.v.append(me.verts[e[n]])
+ me.faces.append(f0);
+
+ for ve in vertlist:
+ t=freeTampon(t)
+ for v in me.faces[ve[1]].v:
+ t=Tampon(v,t)
+ t=TamponMoyen(t,me.faces[ve[1]].v)
+ ve.append(t[:])
+ me.verts[ve[0]]=appliqueMoyenne(me.verts[ve[0]],t)
+
+ def swap(x,y):
+ return y,x
+
+ p=[[edgelist[0][0],edgelist[0][1]]]
+ while len(p)!=len(edgelist):
+ for n in range(1,len(edgelist)) :
+ if p[-1][1]== edgelist[n][0]:
+ p.append([edgelist[n][0],edgelist[n][1]])
+ n+=1
+ elif p[-1][1]== edgelist[n][1]:
+ edgelist[n][0],edgelist[n][1]=swap(edgelist[n][0],edgelist[n][1])
+ p.append([edgelist[n][0],edgelist[n][1]])
+ n+=1
+ if len(p)%2==0:
+ P0=p[:(len(p))/2] ; P1=p[len(p)/2:]; P1.reverse()
+ for s in range(len(P0)-1):
+ f0=Blender.NMesh.Face()
+ table=[P0[s][0],P0[s][1],P1[s+1][0],P1[s+1][1]]
+ for t in table:f0.v.append(me.verts[t])
+ me.faces.append(f0)
+ elif len(p) >3 :
+ P0=p[:(len(p)-1)/2];P1=p[(len(p)-1)/2:-1]; P1.reverse()
+ for s in range(len(P0)-1):
+ f0=Blender.NMesh.Face()
+ table=[P0[s][0],P0[s][1],P1[s+1][0],P1[s+1][1]]
+ for t in table:f0.v.append(me.verts[t])
+ me.faces.append(f0)
+ f0=Blender.NMesh.Face()
+ table=[p[-1][0],P0[0][0],P1[-1][1]]
+ for t in table:f0.v.append(me.verts[t])
+ me.faces.append(f0)
+
+ elif len(p) ==3 :
+ if DEBUG :print P0,P1
+ f0=Blender.NMesh.Face()
+ table=[p[0][0],p[0][1],p[1][1]]
+ for t in table:f0.v.append(me.verts[t])
+ me.faces.append(f0)
+
+ for f in listf2v[lebon.index]:
+ del me.faces[me.faces.index(f)]
+ del me.verts[me.verts.index(lebon)]
+ me.update()
+
+ if me.mode&Blender.NMesh.Modes['SUBSURF']:
+ me.mode-=Blender.NMesh.Modes['SUBSURF']
+ SUBSURF=1
+ me.update()
+ OBJECT[0].makeDisplayList()
+
+ if result==5:
+ pl=[]
+ for s in me.verts:
+ if s.sel==1:
+ pl.append(s.index)
+ Blender.Draw.Register(D,E,BE)
+
+ """
+ if SUBSURF==1 :
+ me.mode+=Blender.NMesh.Modes['SUBSURF']
+ me.update()
+ OBJECT[0].makeDisplayList()
+ """
+ else:
+ name = " It could leave only one selected vertex %t | ok %x1 ?"
+ result = Blender.Draw.PupMenu(name)
+
+OBJECT=Blender.Object.GetSelected()
+
+if len(OBJECT)!=0:
+ if OBJECT[0].getType()=='Mesh':
+ name = "Un-Weld, OK ? %t| unbind points %x1| with noise ? %x2| middle face ? %x3| static bevel vertex ? %x4| moving bevel vertex ? %x5|"
+ result = Blender.Draw.PupMenu(name)
+ if result:
+ me=OBJECT[0].getData()
+ unique=0
+ if result<4:
+ #tri des sommets selectionnes
+ for v in me.verts:
+ if v.sel==1:
+ lebon=v
+ if DEBUG : print lebon
+ #dictionnaires des faces connectees aux sommets selectionnes
+ listf2v=listConnecterFace(me,lebon)
+ me=creerFaceSupplementaire(me,lebon,listf2v)
+ OBJECT[0].link(me)
+ OBJECT[0].makeDisplayList()
+ else:
+ VertexBevel(result)
+ OBJECT[0].makeDisplayList()
+
+ else:
+ name = "Nothing to do! Are you sure ?"
+ result = Blender.Draw.PupMenu(name)
+
+
diff --git a/release/scripts/uv_export.py b/release/scripts/uv_export.py
index ef224b6eba8..5a494952487 100644
--- a/release/scripts/uv_export.py
+++ b/release/scripts/uv_export.py
@@ -28,7 +28,13 @@ Tooltip: 'Export the UV face layout of the selected object to a .TGA file'
#
# ***** END GPL LICENCE BLOCK *****
# --------------------------------------------------------------------------
-# thanks to jms for the tga functions
+# thanks to jms for the tga functions:
+# Writetga and buffer functions
+# (c) 2002-2004 J-M Soler released under GPL licence
+# Official Page :
+# http://jmsoler.free.fr/didacticiel/blender/tutor/write_tga_pic.htm
+# Communicate problems and errors on:
+# http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender
# --------------------------
# Version 1.1
# Clear a bug that crashed the script when UV coords overlapped in the same faces
diff --git a/release/scripts/videoscape_export.py b/release/scripts/videoscape_export.py
index 6f7b0849dfd..6cfbd3e9e1e 100644
--- a/release/scripts/videoscape_export.py
+++ b/release/scripts/videoscape_export.py
@@ -9,8 +9,8 @@ Tooltip: 'Export selected mesh to VideoScape File Format (*.obj)'
# +---------------------------------------------------------+
# | Copyright (c) 2001 Anthony D'Agostino |
-# | http://ourworld.compuserve.com/homepages/scorpius |
-# | scorpius@compuserve.com |
+# | http://www.redrival.com/scorpius |
+# | scorpius@netzero.com |
# | June 5, 2001 |
# | Released under the Blender Artistic Licence (BAL) |
# | Import Export Suite v0.5 |
@@ -22,7 +22,6 @@ Tooltip: 'Export selected mesh to VideoScape File Format (*.obj)'
import Blender, mod_meshtools
#import time
-import mod_flags
# =====================================
# ====== Write VideoScape Format ======
@@ -37,7 +36,7 @@ def write(filename):
mesh = Blender.NMesh.GetRaw(meshname)
obj = Blender.Object.Get(objname)
- if not mesh.hasVertexColours():
+ if not mod_meshtools.has_vertex_colors(mesh):
message = "Please assign vertex colors before exporting.\n"
message += objname + " object was not saved."
mod_meshtools.print_boxed(message)
@@ -51,7 +50,7 @@ def write(filename):
# === Write Vertex List & Vertex Colors ===
for i in range(len(mesh.verts)):
- if not i%100 and mod_flags.show_progress:
+ if not i%100 and mod_meshtools.show_progress:
Blender.Window.DrawProgressBar(float(i)/len(mesh.verts), "Writing Verts")
file.write("% f % f % f 0x" % tuple(mesh.verts[i].co))
for j in range(len(vcols[i])):
@@ -60,7 +59,7 @@ def write(filename):
# === Write Face List ===
for i in range(len(mesh.faces)):
- if not i%100 and mod_flags.show_progress:
+ if not i%100 and mod_meshtools.show_progress:
Blender.Window.DrawProgressBar(float(i)/len(mesh.faces), "Writing Faces")
file.write("%d " % len(mesh.faces[i].v)) # numfaceverts
for j in range(len(mesh.faces[i].v)):
@@ -86,7 +85,7 @@ vcolor_div = lambda u, s: [u[0]/s, u[1]/s, u[2]/s, u[3]/s]
def average_vertexcolors(mesh, debug=0):
vertexcolors = {}
for i in range(len(mesh.faces)): # get all vcolors that share this vertex
- if not i%100 and mod_flags.show_progress: Blender.Window.DrawProgressBar(float(i)/len(mesh.verts), "Finding Shared VColors")
+ if not i%100 and mod_meshtools.show_progress: Blender.Window.DrawProgressBar(float(i)/len(mesh.verts), "Finding Shared VColors")
for j in range(len(mesh.faces[i].v)):
index = mesh.faces[i].v[j].index
color = mesh.faces[i].col[j]
@@ -95,7 +94,7 @@ def average_vertexcolors(mesh, debug=0):
if debug: print 'before'; vcprint(vertexcolors)
for i in range(len(vertexcolors)): # average them
- if not i%100 and mod_flags.show_progress: Blender.Window.DrawProgressBar(float(i)/len(mesh.verts), "Averaging Vertex Colors")
+ if not i%100 and mod_meshtools.show_progress: Blender.Window.DrawProgressBar(float(i)/len(mesh.verts), "Averaging Vertex Colors")
vcolor = [0,0,0,0] # rgba
for j in range(len(vertexcolors[i])):
vcolor = vcolor_add(vcolor, vertexcolors[i][j])
@@ -111,7 +110,7 @@ def average_vertexcolors_slow_1(mesh, debug=0):
vertexcolors = []
i = 0
for vertex in mesh.verts:
- if not i%100 and mod_flags.show_progress: Blender.Window.DrawProgressBar(float(i)/len(mesh.verts), "Averaging Vertex Colors")
+ if not i%100 and mod_meshtools.show_progress: Blender.Window.DrawProgressBar(float(i)/len(mesh.verts), "Averaging Vertex Colors")
i += 1
vcolor = [0,0,0,0] # rgba
shared = 0
@@ -133,7 +132,7 @@ def average_vertexcolors_slow_1(mesh, debug=0):
def average_vertexcolors_slow_2(mesh, debug=0):
vertexcolors = []
for i in range(len(mesh.verts)):
- if not i%100 and mod_flags.show_progress: Blender.Window.DrawProgressBar(float(i)/len(mesh.verts), "Averaging Vertex Colors")
+ if not i%100 and mod_meshtools.show_progress: Blender.Window.DrawProgressBar(float(i)/len(mesh.verts), "Averaging Vertex Colors")
vcolor = [0,0,0,0] # rgba
shared = 0
for j in range(len(mesh.faces)):
@@ -153,7 +152,7 @@ def average_vertexcolors_slow_2(mesh, debug=0):
def average_vertexcolors_slow_3(mesh, debug=0):
vertexcolors = []
for i in range(len(mesh.verts)):
- if not i%100 and mod_flags.show_progress: Blender.Window.DrawProgressBar(float(i)/len(mesh.verts), "Averaging Vertex Colors")
+ if not i%100 and mod_meshtools.show_progress: Blender.Window.DrawProgressBar(float(i)/len(mesh.verts), "Averaging Vertex Colors")
vcolor = [0,0,0,0] # rgba
shared = 0
for j in range(len(mesh.faces)):
diff --git a/release/scripts/wings_export.py b/release/scripts/wings_export.py
new file mode 100644
index 00000000000..46112ac83fd
--- /dev/null
+++ b/release/scripts/wings_export.py
@@ -0,0 +1,337 @@
+#!BPY
+
+"""
+Name: 'Wings3D...'
+Blender: 232
+Group: 'Export'
+Tooltip: 'Export selected mesh to Wings3D File Format (*.wings)'
+"""
+
+# +---------------------------------------------------------+
+# | Copyright (c) 2002 Anthony D'Agostino |
+# | http://www.redrival.com/scorpius |
+# | scorpius@netzero.com |
+# | Feb 19, 2002 |
+# | Released under the Blender Artistic Licence (BAL) |
+# | Import Export Suite v0.5 |
+# +---------------------------------------------------------+
+# | Read and write Wings3D File Format (*.wings) |
+# +---------------------------------------------------------+
+
+import Blender, mod_meshtools
+import struct, time, sys, os, zlib, cStringIO
+
+# ===============================================
+# === Write The 'Header' Common To All Chunks ===
+# ===============================================
+def write_chunkheader(data, version, tag, name):
+ data.write(struct.pack(">BB", version, tag))
+ data.write(struct.pack(">BH", 0x64, len(name)))
+ data.write(name)
+
+# ===================
+# === Write Faces ===
+# ===================
+def write_faces(data, mesh):
+ numfaces = len(mesh.faces)
+ data.write(struct.pack(">BL", 0x6C, numfaces))
+ #for i in range(numfaces):
+ # if not i%100 and mod_meshtools.show_progress: Blender.Window.DrawProgressBar(float(i)/numfaces, "Writing Faces")
+ # data.write("\x6A")
+ data.write("\x6A" * numfaces) # same, but faster than the above loop
+ data.write("\x6A")
+
+# ===================
+# === Write Verts ===
+# ===================
+def write_verts(data, mesh):
+ numverts = len(mesh.verts)
+ data.write(struct.pack(">BL", 0x6C, numverts))
+ for i in range(numverts):
+ if not i%100 and mod_meshtools.show_progress: Blender.Window.DrawProgressBar(float(i)/numverts, "Writing Verts")
+ data.write(struct.pack(">BLBL", 0x6C, 1, 0x6D, 24))
+ #data.write("\x6c\x00\x00\x00\x01\x6D\x00\x00\x00\x30")
+ x, y, z = mesh.verts[i].co
+ data.write(struct.pack(">ddd", x, z, -y))
+ data.write("\x6A")
+ data.write("\x6A")
+
+# ===================
+# === Write Edges ===
+# ===================
+def write_edges(data, mesh, edge_table):
+ numedges = len(edge_table)
+ data.write(struct.pack(">BL", 0x6C, numedges))
+ keys = edge_table.keys()
+ keys.sort()
+ for key in keys:
+ i = edge_table[key][6]
+ if not i%100 and mod_meshtools.show_progress: Blender.Window.DrawProgressBar(float(i)/numedges, "Writing Edges")
+
+ if mod_meshtools.has_vertex_colors(mesh):
+ r1, g1, b1 = edge_table[key][7]
+ r2, g2, b2 = edge_table[key][8]
+ data.write("\x6C\x00\x00\x00\x02")
+ data.write("\x68\x02\x64\x00\x05color")
+ data.write("\x6D\x00\x00\x00\x30")
+ data.write(struct.pack(">dddddd", r1, g1, b1, r2, g2, b2))
+ #print "%f %f %f - %f %f %f" % (r1, g1, b1, r2, g2, b2)
+ else:
+ data.write("\x6C\x00\x00\x00\x01") # BL
+
+ #$write_chunkheader(data, 0x68, 0x09, "edge")
+ data.write("\x68\x09\x64\x00\x04edge") # faster
+
+ # Sv Ev (Reversed)
+ data.write(struct.pack(">BLBL", 0x62, key[1], 0x62, key[0]))
+
+ # Lf Rf LP LS RP RS
+ for i in range(6):
+ if edge_table[key][i] < 256:
+ data.write(struct.pack(">BB", 0x61, edge_table[key][i]))
+ else:
+ data.write(struct.pack(">BL", 0x62, edge_table[key][i]))
+
+ data.write("\x6A")
+
+ data.write("\x6A")
+
+# ===============================
+# === Write The Material Mode ===
+# ===============================
+def write_mode(data, mesh):
+ data.write("\x6A")
+ data.write(struct.pack(">BL", 0x6C, 1))
+ write_chunkheader(data, 0x68, 0x02, "mode")
+ if mod_meshtools.has_vertex_colors(mesh):
+ data.write(struct.pack(">BH6s", 0x64, 6, "vertex"))
+ else:
+ data.write(struct.pack(">BH8s", 0x64, 8, "material"))
+ data.write("\x6A")
+
+# ======================
+# === Write Material ===
+# ======================
+def write_material(data, mesh):
+ data.write("\x6A")
+ data.write(struct.pack(">BL", 0x6C, 1))
+ write_chunkheader(data, 0x68, 0x02, "my default")
+
+ data.write(struct.pack(">BL", 0x6C, 2))
+ write_chunkheader(data, 0x68, 0x02, "maps")
+ data.write("\x6A")
+ write_chunkheader(data, 0x68, 0x02, "opengl")
+
+ # === The Material Components ===
+ data.write(struct.pack(">BL", 0x6C, 5))
+
+ write_chunkheader(data, 0x68, 0x02, "diffuse")
+ data.write("\x68\x04")
+ data.write("\x63"+"1.00000000000000000000"+"e+000"+"\x00"*4)
+ data.write("\x63"+"1.00000000000000000000"+"e+000"+"\x00"*4)
+ data.write("\x63"+"1.00000000000000000000"+"e+000"+"\x00"*4)
+ data.write("\x63"+"1.00000000000000000000"+"e+000"+"\x00"*4)
+
+ write_chunkheader(data, 0x68, 0x02, "ambient")
+ data.write("\x68\x04")
+ data.write("\x63"+"1.00000000000000000000"+"e+000"+"\x00"*4)
+ data.write("\x63"+"1.00000000000000000000"+"e+000"+"\x00"*4)
+ data.write("\x63"+"1.00000000000000000000"+"e+000"+"\x00"*4)
+ data.write("\x63"+"1.00000000000000000000"+"e+000"+"\x00"*4)
+
+ write_chunkheader(data, 0x68, 0x02, "specular")
+ data.write("\x68\x04")
+ data.write("\x63"+"1.00000000000000000000"+"e+000"+"\x00"*4)
+ data.write("\x63"+"1.00000000000000000000"+"e+000"+"\x00"*4)
+ data.write("\x63"+"1.00000000000000000000"+"e+000"+"\x00"*4)
+ data.write("\x63"+"1.00000000000000000000"+"e+000"+"\x00"*4)
+
+ write_chunkheader(data, 0x68, 0x02, "emission")
+ data.write("\x68\x04")
+ data.write("\x63"+"0.00000000000000000000"+"e+000"+"\x00"*4)
+ data.write("\x63"+"0.00000000000000000000"+"e+000"+"\x00"*4)
+ data.write("\x63"+"0.00000000000000000000"+"e+000"+"\x00"*4)
+ data.write("\x63"+"0.00000000000000000000"+"e+000"+"\x00"*4)
+
+ write_chunkheader(data, 0x68, 0x02, "shininess")
+ data.write("\x63"+"0.00000000000000000000"+"e+000"+"\x00"*4)
+
+ #write_chunkheader(data, 0x68, 0x02, "twosided")
+ #data.write(struct.pack(">BH4s", 0x64, 4, "true"))
+
+ data.write("\x6A"*3) # use *4 if no ambient light
+
+# =====================
+# === Generate Data ===
+# =====================
+def generate_data(objname, edge_table, mesh):
+ data = cStringIO.StringIO()
+
+ # === wings chunk ===
+ write_chunkheader(data, 0x68, 0x03, "wings")
+
+ numobjs = 1 # len(Blender.Object.GetSelected())
+ data.write("\x61\x02\x68\x03") # misc bytes
+ data.write(struct.pack(">BL", 0x6C, numobjs))
+
+ # === object chunk ===
+ write_chunkheader(data, 0x68, 0x04, "object")
+ data.write(struct.pack(">BH", 0x6B, len(objname)))
+ data.write(objname)
+
+ # === winged chunk ===
+ write_chunkheader(data, 0x68, 0x05, "winged")
+ write_edges(data, mesh, edge_table)
+ write_faces(data, mesh)
+ write_verts(data, mesh)
+ write_mode(data, mesh)
+ write_material(data, mesh)
+ write_ambient_light(data)
+ return data.getvalue()
+
+# ===========================
+# === Write Ambient Light ===
+# ===========================
+def write_ambient_light(data):
+ light = [ # A quick cheat ;)
+ 0x6C, 0x00, 0x00, 0x00, 0x01, 0x68, 0x02, 0x64, 0x00, 0x06, 0x6C, 0x69,
+ 0x67, 0x68, 0x74, 0x73, 0x6C, 0x00, 0x00, 0x00, 0x01, 0x68, 0x02, 0x6B,
+ 0x00, 0x07, 0x41, 0x6D, 0x62, 0x69, 0x65, 0x6E, 0x74, 0x6C, 0x00, 0x00,
+ 0x00, 0x08, 0x68, 0x02, 0x64, 0x00, 0x07, 0x76, 0x69, 0x73, 0x69, 0x62,
+ 0x6C, 0x65, 0x64, 0x00, 0x04, 0x74, 0x72, 0x75, 0x65, 0x68, 0x02, 0x64,
+ 0x00, 0x06, 0x6C, 0x6F, 0x63, 0x6B, 0x65, 0x64, 0x64, 0x00, 0x05, 0x66,
+ 0x61, 0x6C, 0x73, 0x65, 0x68, 0x02, 0x64, 0x00, 0x06, 0x6F, 0x70, 0x65,
+ 0x6E, 0x67, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x03, 0x68, 0x02, 0x64, 0x00,
+ 0x04, 0x74, 0x79, 0x70, 0x65, 0x64, 0x00, 0x07, 0x61, 0x6D, 0x62, 0x69,
+ 0x65, 0x6E, 0x74, 0x68, 0x02, 0x64, 0x00, 0x07, 0x61, 0x6D, 0x62, 0x69,
+ 0x65, 0x6E, 0x74, 0x68, 0x04, 0x63, 0x31, 0x2E, 0x30, 0x30, 0x30, 0x30,
+ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+ 0x30, 0x30, 0x30, 0x30, 0x65, 0x2B, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00,
+ 0x00, 0x63, 0x31, 0x2E, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+ 0x65, 0x2B, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x63, 0x31, 0x2E,
+ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x65, 0x2B, 0x30, 0x30,
+ 0x30, 0x00, 0x00, 0x00, 0x00, 0x63, 0x31, 0x2E, 0x30, 0x30, 0x30, 0x30,
+ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+ 0x30, 0x30, 0x30, 0x30, 0x65, 0x2B, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00,
+ 0x00, 0x68, 0x02, 0x64, 0x00, 0x08, 0x70, 0x6F, 0x73, 0x69, 0x74, 0x69,
+ 0x6F, 0x6E, 0x68, 0x03, 0x63, 0x30, 0x2E, 0x30, 0x30, 0x30, 0x30, 0x30,
+ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+ 0x30, 0x30, 0x30, 0x65, 0x2B, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00,
+ 0x63, 0x33, 0x2E, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x65,
+ 0x2B, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x63, 0x30, 0x2E, 0x30,
+ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x65, 0x2B, 0x30, 0x30, 0x30,
+ 0x00, 0x00, 0x00, 0x00, 0x6A, 0x68, 0x02, 0x64, 0x00, 0x07, 0x76, 0x69,
+ 0x73, 0x69, 0x62, 0x6C, 0x65, 0x64, 0x00, 0x04, 0x74, 0x72, 0x75, 0x65,
+ 0x68, 0x02, 0x64, 0x00, 0x06, 0x6C, 0x6F, 0x63, 0x6B, 0x65, 0x64, 0x64,
+ 0x00, 0x05, 0x66, 0x61, 0x6C, 0x73, 0x65, 0x68, 0x02, 0x64, 0x00, 0x06,
+ 0x79, 0x61, 0x66, 0x72, 0x61, 0x79, 0x6C, 0x00, 0x00, 0x00, 0x0B, 0x68,
+ 0x02, 0x64, 0x00, 0x09, 0x6D, 0x69, 0x6E, 0x69, 0x6D, 0x69, 0x7A, 0x65,
+ 0x64, 0x64, 0x00, 0x04, 0x74, 0x72, 0x75, 0x65, 0x68, 0x02, 0x64, 0x00,
+ 0x05, 0x70, 0x6F, 0x77, 0x65, 0x72, 0x63, 0x31, 0x2E, 0x30, 0x30, 0x30,
+ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+ 0x30, 0x30, 0x30, 0x30, 0x30, 0x65, 0x2B, 0x30, 0x30, 0x30, 0x00, 0x00,
+ 0x00, 0x00, 0x68, 0x02, 0x64, 0x00, 0x04, 0x74, 0x79, 0x70, 0x65, 0x64,
+ 0x00, 0x09, 0x68, 0x65, 0x6D, 0x69, 0x6C, 0x69, 0x67, 0x68, 0x74, 0x68,
+ 0x02, 0x64, 0x00, 0x07, 0x73, 0x61, 0x6D, 0x70, 0x6C, 0x65, 0x73, 0x62,
+ 0x00, 0x00, 0x01, 0x00, 0x68, 0x02, 0x64, 0x00, 0x05, 0x64, 0x65, 0x70,
+ 0x74, 0x68, 0x61, 0x03, 0x68, 0x02, 0x64, 0x00, 0x0A, 0x62, 0x61, 0x63,
+ 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x64, 0x00, 0x09, 0x75, 0x6E,
+ 0x64, 0x65, 0x66, 0x69, 0x6E, 0x65, 0x64, 0x68, 0x02, 0x64, 0x00, 0x18,
+ 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x5F, 0x66,
+ 0x69, 0x6C, 0x65, 0x6E, 0x61, 0x6D, 0x65, 0x5F, 0x48, 0x44, 0x52, 0x49,
+ 0x6A, 0x68, 0x02, 0x64, 0x00, 0x19, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72,
+ 0x6F, 0x75, 0x6E, 0x64, 0x5F, 0x66, 0x69, 0x6C, 0x65, 0x6E, 0x61, 0x6D,
+ 0x65, 0x5F, 0x69, 0x6D, 0x61, 0x67, 0x65, 0x6A, 0x68, 0x02, 0x64, 0x00,
+ 0x1A, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x5F,
+ 0x65, 0x78, 0x70, 0x6F, 0x73, 0x75, 0x72, 0x65, 0x5F, 0x61, 0x64, 0x6A,
+ 0x75, 0x73, 0x74, 0x61, 0x00, 0x68, 0x02, 0x64, 0x00, 0x12, 0x62, 0x61,
+ 0x63, 0x6B, 0x67, 0x72, 0x6F, 0x75, 0x6E, 0x64, 0x5F, 0x6D, 0x61, 0x70,
+ 0x70, 0x69, 0x6E, 0x67, 0x64, 0x00, 0x05, 0x70, 0x72, 0x6F, 0x62, 0x65,
+ 0x68, 0x02, 0x64, 0x00, 0x10, 0x62, 0x61, 0x63, 0x6B, 0x67, 0x72, 0x6F,
+ 0x75, 0x6E, 0x64, 0x5F, 0x70, 0x6F, 0x77, 0x65, 0x72, 0x63, 0x31, 0x2E,
+ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
+ 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x65, 0x2B, 0x30, 0x30,
+ 0x30, 0x00, 0x00, 0x00, 0x00, 0x6A, 0x68, 0x02, 0x64, 0x00, 0x07, 0x76,
+ 0x69, 0x73, 0x69, 0x62, 0x6C, 0x65, 0x64, 0x00, 0x04, 0x74, 0x72, 0x75,
+ 0x65, 0x68, 0x02, 0x64, 0x00, 0x06, 0x6C, 0x6F, 0x63, 0x6B, 0x65, 0x64,
+ 0x64, 0x00, 0x05, 0x66, 0x61, 0x6C, 0x73, 0x65, 0x6A, 0x6A, 0x6A]
+ data.write("".join(map(chr, light)))
+
+# ==========================
+# === Write Wings Format ===
+# ==========================
+def write(filename):
+ start = time.clock()
+
+ objects = Blender.Object.GetSelected()
+ objname = objects[0].name
+ meshname = objects[0].data.name
+ mesh = Blender.NMesh.GetRaw(meshname)
+ obj = Blender.Object.Get(objname)
+
+ try:
+ edge_table = mod_meshtools.generate_edgetable(mesh)
+ except:
+ edge_table = {}
+ message = "Unable to generate\nEdge Table for mesh.\n"
+ message += "Object name is: " + meshname
+ mod_meshtools.print_boxed(message)
+ #return
+
+ if 0:
+ import Tkinter, tkMessageBox
+ sys.argv=['wings.pyo','wings.pyc'] # ?
+
+ #Tkinter.NoDefaultRoot()
+ win1 = Tkinter.Tk()
+ ans = tkMessageBox.showerror("Error", message)
+ win1.pack()
+ print ans
+ if ans:
+ win1.quit()
+ win1.mainloop()
+
+ else:
+ from Tkinter import Label
+ sys.argv = 'wings.py'
+ widget = Label(None, text=message)
+ #widget.title("Error")
+ widget.pack()
+ widget.mainloop()
+
+ data = generate_data(objname, edge_table, mesh)
+ dsize = len(data)
+ Blender.Window.DrawProgressBar(0.98, "Compressing Data")
+ data = zlib.compress(data, 6)
+ fsize = len(data)+6
+ header = "#!WINGS-1.0\r\n\032\04"
+ misc = 0x8350
+
+ file = open(filename, "wb")
+ file.write(header)
+ file.write(struct.pack(">L", fsize))
+ file.write(struct.pack(">H", misc))
+ file.write(struct.pack(">L", dsize))
+ file.write(data)
+
+ # Blender.Window.RedrawAll()
+ Blender.Window.DrawProgressBar(1.0, '') # clear progressbar
+ file.close()
+ end = time.clock()
+ seconds = " in %.2f %s" % (end-start, "seconds")
+ message = "Successfully exported " + os.path.basename(filename) + seconds + '\n\n'
+ message += "objname : " + objname + '\n'
+ message += "faces : " + `len(mesh.faces)` + '\n'
+ message += "edges : " + `len(edge_table)` + '\n'
+ message += "verts : " + `len(mesh.verts)` + '\n'
+ mod_meshtools.print_boxed(message)
+
+def fs_callback(filename):
+ if filename.find('.wings', -6) <= 0: filename += '.wings'
+ write(filename)
+
+Blender.Window.FileSelector(fs_callback, "Wings3D Export")
diff --git a/release/scripts/wings_import.py b/release/scripts/wings_import.py
new file mode 100644
index 00000000000..85d5fa377ad
--- /dev/null
+++ b/release/scripts/wings_import.py
@@ -0,0 +1,288 @@
+#!BPY
+
+"""
+Name: 'Wings3D...'
+Blender: 232
+Group: 'Import'
+Tooltip: 'Import Wings3D File Format (*.wings)'
+"""
+
+# +---------------------------------------------------------+
+# | Copyright (c) 2002 Anthony D'Agostino |
+# | http://www.redrival.com/scorpius |
+# | scorpius@netzero.com |
+# | Feb 19, 2002 |
+# | Released under the Blender Artistic Licence (BAL) |
+# | Import Export Suite v0.5 |
+# +---------------------------------------------------------+
+# | Read and write Wings3D File Format (*.wings) |
+# +---------------------------------------------------------+
+
+import Blender, mod_meshtools
+import struct, time, sys, os, zlib, cStringIO
+
+# ==============================================
+# === Read The 'Header' Common To All Chunks ===
+# ==============================================
+def read_chunkheader(data):
+ data.read(2) #version, tag = struct.unpack(">BB", data.read(2))
+ misc, namelen = struct.unpack(">BH", data.read(3))
+ name = data.read(namelen)
+ return name
+
+# ==============================
+# === Read The Material Mode ===
+# ==============================
+def read_mode(data):
+ data.read(5) # BL
+ read_chunkheader(data) # "mode"
+ misc, namelen = struct.unpack(">BH", data.read(3))
+ data.read(namelen)
+ data.read(1) # 6A
+
+# =======================
+# === Read Hard Edges ===
+# =======================
+def read_hardedges(data):
+ tag = data.read(1)
+ if tag == '\x6A':
+ return # There are no hard edges
+ elif tag == '\x6B':
+ numhardedges, = struct.unpack(">H", data.read(2))
+ print "numhardedges:", numhardedges
+ for i in range(numhardedges):
+ data.read(1)
+ elif tag == '\x6C':
+ numhardedges, = struct.unpack(">L", data.read(4))
+ print "numhardedges:", numhardedges
+ for i in range(numhardedges):
+ misc = data.read(1)
+ if misc == '\x61': # next value is stored as a byte
+ data.read(1)
+ elif misc == '\x62': # next value is stored as a long
+ data.read(4)
+ data.read(1) # 6A
+ else:
+ print tag
+
+# ==================
+# === Read Edges ===
+# ==================
+def read_edges(data):
+ misc, numedges = struct.unpack(">BL", data.read(5))
+ edge_table = {} # the winged-edge table
+ for i in range(numedges):
+ if not i%100 and mod_meshtools.show_progress: Blender.Window.DrawProgressBar(float(i)/numedges, "Reading Edges")
+ misc, etype = struct.unpack(">BL", data.read(5))
+ if etype == 2: # Vertex Colors
+ data.read(10) # or read_chunkheader(data) # "color"
+ data.read(5) # BL
+ r1,g1,b1,r2,g2,b2 = struct.unpack(">dddddd", data.read(48))
+ #print "%3d %3d %3d | %3d %3d %3d" % (r1*255,g1*255,b1*255,r2*255,g2*255,b2*255),
+ #print "%f %f %f | %f %f %f" % (r1, g1, b1, r2, g2, b2)
+ data.read(9) # or read_chunkheader(data) # "edge"
+ edge = [] # the eight entries for this edge
+ for e in range(8): # Sv Ev | Lf Rf | Lp Ls | Rp Rs
+ misc = data.read(1)
+ if misc == '\x61': # next value is stored as a byte
+ entry, = struct.unpack(">B", data.read(1))
+ edge.append(entry)
+ elif misc == '\x62': # next value is stored as a long
+ entry, = struct.unpack(">L", data.read(4))
+ edge.append(entry)
+ edge_table[i] = edge
+ data.read(1) # 6A
+ data.read(1) # 6A
+ return edge_table
+
+# ==================
+# === Read Faces ===
+# ==================
+def read_faces(data):
+ misc, numfaces = struct.unpack(">BL", data.read(5))
+ for i in range(numfaces):
+ if not i%100 and mod_meshtools.show_progress: Blender.Window.DrawProgressBar(float(i)/numfaces, "Reading Faces")
+ if data.read(1) == '\x6C': # a material follows
+ data.read(4)
+ read_chunkheader(data)
+ misc, namelen = struct.unpack(">BH", data.read(3))
+ materialname = data.read(namelen)
+ data.read(1)
+ data.read(1) # 6A
+ return numfaces
+
+# ==================
+# === Read Verts ===
+# ==================
+def read_verts(data):
+ misc, numverts = struct.unpack(">BL", data.read(5))
+ verts = [] # a list of verts
+ for i in range(numverts):
+ if not i%100 and mod_meshtools.show_progress: Blender.Window.DrawProgressBar(float(i)/numverts, "Reading Verts")
+ data.read(10)
+ x, y, z = struct.unpack(">ddd", data.read(24)) # double precision
+ verts.append((x, -z, y))
+ data.read(1) # 6A
+ data.read(1) # 6A
+ return verts
+
+# =======================
+# === Make Face Table ===
+# =======================
+def make_face_table(edge_table): # For Wings
+ face_table = {}
+ for i in range(len(edge_table)):
+ Lf = edge_table[i][2]
+ Rf = edge_table[i][3]
+ face_table[Lf] = i
+ face_table[Rf] = i
+ return face_table
+
+# =======================
+# === Make Vert Table ===
+# =======================
+def make_vert_table(edge_table): # For Wings
+ vert_table = {}
+ for i in range(len(edge_table)):
+ Sv = edge_table[i][0]
+ Ev = edge_table[i][1]
+ vert_table[Sv] = i
+ vert_table[Ev] = i
+ return vert_table
+
+# ==================
+# === Make Faces ===
+# ==================
+def make_faces(edge_table): # For Wings
+ face_table = make_face_table(edge_table)
+ faces=[]
+ for i in range(len(face_table)):
+ face_verts = []
+ current_edge = face_table[i]
+ while(1):
+ if i == edge_table[current_edge][3]:
+ next_edge = edge_table[current_edge][7] # Right successor edge
+ next_vert = edge_table[current_edge][0]
+ else:
+ next_edge = edge_table[current_edge][5] # Left successor edge
+ next_vert = edge_table[current_edge][1]
+ face_verts.append(next_vert)
+ current_edge = next_edge
+ if current_edge == face_table[i]: break
+ face_verts.reverse()
+ faces.append(face_verts)
+ return faces
+
+# =======================
+# === Dump Wings File ===
+# =======================
+def dump_wings(filename):
+ import pprint
+ start = time.clock()
+ file = open(filename, "rb")
+ header = file.read(15)
+ fsize, = struct.unpack(">L", file.read(4)) # file_size - 19
+ misc, = struct.unpack(">H", file.read(2))
+ dsize, = struct.unpack(">L", file.read(4)) # uncompressed data size
+ data = file.read(fsize-6)
+ file.close()
+ data = zlib.decompress(data)
+ if dsize != len(data): print "ERROR: uncompressed size does not match."
+ data = cStringIO.StringIO(data)
+ print "header:", header
+ print read_chunkheader(data) # === wings chunk ===
+ data.read(4) # misc bytes
+ misc, numobjs, = struct.unpack(">BL", data.read(5))
+ print "filename:", filename
+ print "numobjs :", numobjs
+ for obj in range(numobjs):
+ print read_chunkheader(data) # === object chunk ===
+ misc, namelen = struct.unpack(">BH", data.read(3))
+ objname = data.read(namelen)
+ print read_chunkheader(data) # === winged chunk ===
+ edge_table = read_edges(data)
+ numfaces = read_faces(data)
+ verts = read_verts(data)
+ read_hardedges(data)
+
+ face_table = {} # contains an incident edge
+ vert_table = {} # contains an incident edge
+ for i in range(len(edge_table)):
+ face_table[edge_table[i][2]] = i # generate face_table
+ face_table[edge_table[i][3]] = i
+ vert_table[edge_table[i][0]] = i # generate vert_table
+ vert_table[edge_table[i][1]] = i
+
+ print "objname :", objname
+ print "numedges:", len(edge_table)
+ print "numfaces:", numfaces
+ print "numverts:", len(verts)
+ print
+ print "Ä"*79
+ print "edge_table:"
+ pprint.pprint(edge_table)
+ #for i in range(len(edge_table)): print "%2d" % (i), edge_table[i]
+ print
+ print "face_table:"
+ pprint.pprint(face_table)
+ #for i in range(len(face_table)): print "%2d %2d" % (i, face_table[i])
+ print
+ print "vert_table:"
+ pprint.pprint(vert_table)
+ #for i in range(len(vert_table)): print "%2d %2d" % (i, vert_table[i])
+ file.close()
+ end = time.clock()
+ print '\a\r',
+ sys.stderr.write("\nDone in %.2f %s" % (end-start, "seconds"))
+
+# =========================
+# === Read Wings Format ===
+# =========================
+def read(filename):
+ start = time.clock()
+ file = open(filename, "rb")
+ header = file.read(15)
+ fsize, = struct.unpack(">L", file.read(4)) # file_size - 19
+ misc, = struct.unpack(">H", file.read(2))
+ dsize, = struct.unpack(">L", file.read(4)) # uncompressed data size
+ data = file.read(fsize-6)
+ #print file.tell(), "bytes"
+ file.close()
+ Blender.Window.DrawProgressBar(1.0, "Decompressing Data")
+ data = zlib.decompress(data)
+ data = cStringIO.StringIO(data)
+ read_chunkheader(data) # wings chunk
+ data.read(4) # misc bytes
+ misc, numobjs = struct.unpack(">BL", data.read(5))
+ message = "Successfully imported " + os.path.basename(filename) + '\n\n'
+ message += "%s %8s %8s %8s\n" % ("Object".ljust(15), "faces", "edges", "verts")
+ message += "%s %8s %8s %8s\n" % ("ÄÄÄÄÄÄ".ljust(15), "ÄÄÄÄÄ", "ÄÄÄÄÄ", "ÄÄÄÄÄ")
+
+ for obj in range(numobjs):
+ read_chunkheader(data) # object chunk
+ misc, namelen = struct.unpack(">BH", data.read(3))
+ objname = data.read(namelen)
+ read_chunkheader(data) # winged chunk
+ edge_table = read_edges(data)
+ numfaces = read_faces(data)
+ verts = read_verts(data)
+ read_hardedges(data)
+ read_mode(data)
+ faces = make_faces(edge_table)
+ message += "%s %8s %8s %8s\n" % (objname.ljust(15), len(faces), len(edge_table), len(verts))
+ mod_meshtools.create_mesh(verts, faces, objname)
+
+ material = data.read()
+ #for i in material[0:6]: print "%02X" % ord(i),
+ #print
+ Blender.Window.DrawProgressBar(1.0, "Done") # clear progressbar
+ data.close()
+ end = time.clock()
+ seconds = "\nDone in %.2f %s" % (end-start, "seconds")
+ message += seconds
+ mod_meshtools.print_boxed(message)
+
+def fs_callback(filename):
+ read(filename)
+
+Blender.Window.FileSelector(fs_callback, "Wings3D Import")
diff --git a/source/blender/python/BPY_menus.c b/source/blender/python/BPY_menus.c
index f2879f654c1..f43b5852a32 100644
--- a/source/blender/python/BPY_menus.c
+++ b/source/blender/python/BPY_menus.c
@@ -83,6 +83,8 @@ static int bpymenu_group_atoi (char *str)
else if (!strcmp(str, "Animation")) return PYMENU_ANIMATION;
else if (!strcmp(str, "Materials")) return PYMENU_MATERIALS;
else if (!strcmp(str, "UV")) return PYMENU_UV;
+ else if (!strcmp(str, "Utils")) return PYMENU_UTILS;
+ else if (!strcmp(str, "Tools")) return PYMENU_TOOLS;
/* "Misc" or an inexistent group name: use misc */
else return PYMENU_MISC;
}
@@ -113,6 +115,10 @@ char *BPyMenu_group_itoa (short menugroup)
break;
case PYMENU_UV:
return "UV";
+ case PYMENU_UTILS:
+ return "Utils";
+ case PYMENU_TOOLS:
+ return "Tools";
case PYMENU_MISC:
return "Misc";
break;
diff --git a/source/blender/python/BPY_menus.h b/source/blender/python/BPY_menus.h
index 5e7139f213e..20e10b06d54 100644
--- a/source/blender/python/BPY_menus.h
+++ b/source/blender/python/BPY_menus.h
@@ -75,19 +75,19 @@ typedef struct BPyMenu {
* BPY_menus.c;
* - add the necessary code to the header_***.c file in
* source/blender/src/, like done in header_info.c for import/export;
- * - update the bpython registering function and its documentation to include
- * the new group.
*/
typedef enum {
PYMENU_WIZARDS, /* complex 'app' scripts */
- PYMENU_MODIFIERS, /* modifies existing objs */
+ PYMENU_UV, /* UV editing tools, to go in UV/Image editor space, 'UV' menu */
+ PYMENU_UTILS,
+ PYMENU_TOOLS,
+ PYMENU_MODIFIERS, /* modifies existing obj *data* */
PYMENU_MISC,
PYMENU_MATERIALS,
PYMENU_GENERATORS, /* creates new objects */
PYMENU_IMPORT,
PYMENU_EXPORT,
PYMENU_ANIMATION,
- PYMENU_UV, /* UV editing tools, to go in UV/Image editor space, 'UV' menu */
PYMENU_TOTAL
} PYMENUHOOKS;