use f.area where possible over python function and use len(mface) over len(mface.v)
[blender.git] / release / scripts / kloputils.py
1 #!BPY
2
3 """ Registration info for Blender menus:
4 Name: 'Kloputils 3'
5 Blender: 234
6 Group: 'Wizards'
7 Tip: 'Set of object aligning, modifying tools'
8 """
9
10 __author__ = "Carlos López (klopez)"
11 __url__ = ("elysiun", "Author's web page, http://klopes.tk",
12 "Script's homepage, http://www.iespana.es/klopes/enchufes-guiri.htm",
13 "Thread on elYsiun with links to English and Spanish webpage and pdf docs,\
14 http://www.elysiun.com/forum/viewtopic.php?t=25736")
15 __version__ = "3.1"
16
17 __bpydoc__ = """\
18 This Wizard script contains customizable tools to align and modify mesh
19 objects.
20
21 Edited freely from a post by the author to elYsiun (last link button above):
22
23 These tools are initially oriented as a help for the general design of objects
24 in 2D and 3D (architecture, industrial...), and this is the paradigm the
25 program will be developed around.
26
27 The utilities in the program are separated in 4 areas, accessible through the
28 top menu in the GUI:
29
30 - Alignment:<br>
31   + fitting an object between two others;<br>
32   + setting to an object the absolute size of another one;<br>
33   + aligning selected objects, according to several criteria: location,
34 rotation, scale (scale can be changed either additive or multiplicatively);<br>
35   + location separation can be referenced either by centers, baricenters,
36 origins or limits.
37
38 - Object creation:<br>
39   + circunference passing through 3 points;<br>
40   + arc passing through 3 points;<br>
41   + arc based on angles and radius (interactive).
42
43 - Mesh modification (affects vertices, faces and edges):<br>
44   + edges subdivision in any number of parts;<br>
45   + projection onto an arbitrary plane, in an arbitrary direction;<br>
46   + transformation of position, rotation, scale values (new matrix) of an
47 object, though it looks unaffected.
48
49 - 3D objects modifications (affects transform matrices):<br>
50   + translating / rotating / scaling randomly the selected objects;<br>
51   + moving selected objects closer or away from the active one, setting them at
52 a fixed distance or translating by a fixed or proportional value.
53
54 Notes:<br>
55     All numeric / vectorial values used during the program can be copied and
56 pasted with the help of a buffer, which can contain: a position vector, an
57 Euler list or a scaling vector and can store: numbers entered by user, values
58 acquired from objects (matrices averages, distances, differences of position or
59 rotation angles between two objects).  Buffer contents can also be pasted to
60 the console window as text.
61
62 Usage:
63
64 Open the script from the "Scripts->Wizards" menu of the Scripts window, then
65 one choose from the available languages.  The script has a GUI where specific
66 tools can be selected and configured before being applied.
67
68 Notes:<br>
69     Kloputils has many useful tools.  To get a better idea of what it can do,
70 besides reading the tooltips for each button, users can check its online
71 documentation.
72 """
73
74 # $Id$
75 #
76 ##################################################
77 #                                                #
78 #        KLOPUTILES v3.1 para Blender v2.33      #
79 #                   multilingue                  #
80 #                                                #
81 ##################################################
82 #               Pulsa Alt+P para ejecutar el script
83 #       Improved:       use of Mathutils
84 #       Feature:        actualize objects on ApplyLRS
85 #       Improved:       Project onto planes
86 #       Feature:        mover/rotar/escalar objetos al azar
87 #       Feature:        acercar objs al activo (fijo, abs, rel)
88 #       Improved:       Fit/Embrace
89 #       TODO: subdividir solo aristas seleccionadas (NO FUNCIONA)
90 #       TODO: Elipses
91 #
92 ##################################################
93 #
94 # --------------------------------------------------------------------------
95 # Kloputils by Carlos López (klopez)
96 # --------------------------------------------------------------------------
97 # ***** BEGIN GPL LICENSE BLOCK *****
98 #
99 # Copyright (C) 2004: Carlos López, http://klopes.tk
100 #
101 # This program is free software; you can redistribute it and/or
102 # modify it under the terms of the GNU General Public License
103 # as published by the Free Software Foundation; either version 2
104 # of the License, or (at your option) any later version.
105 #
106 # This program is distributed in the hope that it will be useful,
107 # but WITHOUT ANY WARRANTY; without even the implied warranty of
108 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
109 # GNU General Public License for more details.
110 #
111 # You should have received a copy of the GNU General Public License
112 # along with this program; if not, write to the Free Software Foundation,
113 # Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
114 #
115 # ***** END GPL LICENCE BLOCK *****
116 # --------------------------------------------------------------------------
117
118 import Blender
119 from Blender.Mathutils import *
120 from Blender.NMesh import *
121 from Blender.BGL import *
122 from Blender.Draw import *
123 from Blender.sys import *
124 from Blender.Noise import random
125
126 from math import *
127
128 #path=dirname(progname)
129 #path=[dirname(progname),'.blender','bpydata']
130 path=Blender.Get("datadir")
131 if not path:
132         errmsg = "\nNo bpydata/ dir found! It should be in Blender's home dir."
133         raise IOError, errmsg
134
135 sc=Blender.Scene.GetCurrent()
136 MId=Matrix([1,0],[0,1])
137 MId.resize4x4()
138
139 coo=['X','Y','Z']
140 l=PupMenu('Choose language%t|Espanol%x1|English%x2|Catala%x3')
141 Lang=['Espanol','English','Catala'][l-1]
142
143
144
145 #Buffer:
146 BfL=[0.,0.,0.]
147 BfR=[0.,0.,0.]
148 BfS=[1.,1.,1.]
149
150 pagina=Create(1)
151 creake=Create(1)
152 editake=Create(2)
153 moveke=Create(1)
154
155 numReal=Create(0.)
156 movekomo=Create(1)
157 menuLRS=Create(1)
158
159 ndiv=Create(3)
160 akeplano=Create(2)
161 akeplanoXYZ=Create(3)
162 enkedir=Create(3)
163
164 nLocX=Create(1.0)
165 nLocY=Create(2.0)
166 nLocZ=Create(3.0)
167 nRotX=Create(0.0)
168 nRotY=Create(0.0)
169 nRotZ=Create(0.0)
170 nSizX=Create(1.0)
171 nSizY=Create(1.0)
172 nSizZ=Create(1.0)
173 other=Create(1)
174
175 ang1=Create(0.0)
176 ang2=Create(30.0)
177 angulo=Create(30.0)
178 radio=Create(1.0)
179 pts=Create(10)
180 ctro=Create(0)
181 meTx=Create('Arc')
182
183 arcorden=Create(0)
184
185 CreaNew=Create(1)
186 Cuantos=Create(2)
187 toBuffer=Create(0)
188
189 menueqiX=Create(1)
190 sepX=Create(0.5)
191 aliX=Create(1)
192 menueqiY=Create(1)
193 sepY=Create(0.0)
194 aliY=Create(0)
195 menueqiZ=Create(2)
196 sepZ=Create(1.0)
197 aliZ=Create(0)
198
199 girX=Create(0)
200 incX=Create(0.0)
201 girY=Create(0)
202 incY=Create(0.0)
203 girZ=Create(1)
204 incZ=Create(5.0)
205
206 scaX=Create(1)
207 iScaX=Create(.5)
208 scaY=Create(1)
209 iScaY=Create(.5)
210 scaZ=Create(1)
211 iScaZ=Create(.5)
212
213 encX=Create(1)
214 encY=Create(0)
215 encZ=Create(0)
216 en2X=Create(1)
217 en2Y=Create(0)
218 en2Z=Create(0)
219
220
221 def CreaObjDeMalla(mm,o,nombre):
222         oo=Blender.Object.New('Mesh')
223         oo.link(mm)
224         oo.setName(nombre)
225         oo.LocX,oo.LocY,oo.LocZ=o.LocX,o.LocY,o.LocZ
226         oo.RotX,oo.RotY,oo.RotZ=o.RotX,o.RotY,o.RotZ
227         oo.SizeX,oo.SizeY,oo.SizeZ=o.SizeX,o.SizeY,o.SizeZ
228         sc.link(oo)
229         return oo
230
231 def rectang(x,y,l,h,r,g,b):
232         glColor3f(r,g,b)
233         glBegin(GL_POLYGON)
234         glVertex2i(x, y)
235         glVertex2i(l, y)
236         glVertex2i(l, h)
237         glVertex2i(x, h)
238         glEnd()
239
240 def SituaL(objeto,coord,X):
241         if coord==0:
242                 objeto.LocX=X
243         elif coord==1:
244                 objeto.LocY=X
245         elif coord==2:
246                 objeto.LocZ=X
247 def SituaR(objeto,coord,X):
248         if coord==0:
249                 objeto.RotX=X
250         elif coord==1:
251                 objeto.RotY=X
252         elif coord==2:
253                 objeto.RotZ=X
254 def SituaS(objeto,coord,X):
255         if coord==0:
256                 objeto.SizeX=X
257         elif coord==1:
258                 objeto.SizeY=X
259         elif coord==2:
260                 objeto.SizeZ=X
261
262 def mallaScan(o):
263         return o.getType()=='Mesh'
264
265 def Sistema(MM,D):
266         MM.invert()
267         return MatMultVec(MM,D)
268
269 def GloVrt((x,y,z),M):  # Devuelve (vector) coords globs de v
270         v=Vector([x,y,z,1])
271         v=VecMultMat(v,M)
272         v.resize3D()
273         return v
274
275 def Extremo(lista,M=MId):       # Devuelve extremos y pto medio de lista de vectores
276         o1=GloVrt(lista[0],M)
277         o2=GloVrt(lista[0],M)
278         for v in lista:
279                 va=Vector(list(v))
280                 va.resize4D()
281                 va=VecMultMat(va,M)
282                 for c in range(3):
283                         o1[c]=min(va[c],o1[c])
284                         o2[c]=max(va[c],o2[c])
285         return [o1,(o1+o2)/2,o2]
286
287 def Media(lista):       #Media
288         ctr=Vector([0,0,0])
289         for c in range(3):
290                 for l in lista: ctr[c]=ctr[c]+l[c]
291                 ctr[c]=ctr[c]/len(lista)
292         return ctr
293
294
295
296
297
298
299 def draw():
300         global pagina, toBuffer
301         glClearColor(0.4,0.2,0.2,0.0)
302         glClear(GL_COLOR_BUFFER_BIT)
303
304         pagina=Menu(menu0,98,20,370,170,28,pagina.val,"Select page")
305         toBuffer=Menu(menu4,80,200,370,20,15,toBuffer.val,"Copy values to the internal buffer")
306         glColor3f(0.6,0.6,0.2)
307         glRasterPos2i(198,388)
308         Text("Copy",'small')
309
310         if (pagina.val==1): draw1()
311         elif (pagina.val==2): draw2()
312         elif (pagina.val==3): draw3()
313         elif (pagina.val==4): draw4()
314
315         Button(menuExit,99,20,5,200,18)
316
317 def draw4():
318         global moveke,o
319         global aliX,aliY,aliZ,numReal,movekomo,menuLRS,menuPaste
320         
321
322         rectang(15,38,225,264,0.2,0.,0.)
323
324         moveke=Menu(menu5,98,10,248,200,20,moveke.val,"Modify the matrices of selected objects")
325         if moveke.val==2:
326                 aliX=Toggle("X",0, 50,160,45,30,aliX.val,"Activate modification in X")
327                 aliY=Toggle("Y",0, 95,160,45,30,aliY.val,"Activate modification in Y")
328                 aliZ=Toggle("Z",0,140,160,45,30,aliZ.val,"Activate modification in Z")
329                 menuLRS=Menu("Loc%x1|Rot%x2|Size%x3",98,20,110,50,20,menuLRS.val)
330         if moveke.val==1:
331                 movekomo=Menu(menu5a,98,20,225,200,20,movekomo.val,"Transformation type")
332                 m,M,tip= -100,100,"Quantity"
333         else:
334                 if menuLRS.val==1:
335                         m,M,tip= -1000, 1000, "Distance"
336                 elif menuLRS.val==2:
337                         m,M,tip= 0, 360, "Angle"
338                 elif menuLRS.val==3:
339                         m,M,tip= 0, 100, "Scale"
340         if moveke.val==1 and movekomo.val==3:   tip=tip+"Multiplier "
341         if moveke.val==2:       tip=tip+" (max)"
342
343         numReal=Number("",0,20,140,178,18,numReal.val,m,M,tip)
344         glColor3f(0.6,0.6,0.2)
345         glRasterPos2i(200,156)
346         Text("Paste",'small')
347         menuPaste=Menu("Paste...%t|LocX%x1|LocY%x2|LocZ%x3|\Loc\%x4|RotX%x5|RotY%x6|RotZ%x7|SizeX%x8|SizeY%x9|SizeZ%x10"
348 ,88,202,140,20,12,0,"Paste what?")
349         ok=Button("OK",50,80,110,80,20)
350
351
352 def draw3():
353         global editake,ndiv,akeplano,akeplanoXYZ,enkedir,ok
354         global other
355         global getlocrotsiz,ok,nLocX,nLocY,nLocZ
356         global nRotX,nRotY,nRotZ,nSizX,nSizY,nSizZ
357         global Cloc,Ploc,Crot,Prot,Csiz,Psiz
358
359         rectang(15,38,225,264,0.3,0.7,0.5)
360
361         editake=Menu(menu3,98,10,248,143,20,editake.val,"Mesh editing menu")
362         if(editake.val==1):
363                 ndiv=Number(menu3a,98,20,200,150,18,ndiv.val,2,1000)
364                 ok=Button("OK",20,172,200,32,18)
365         elif(editake.val==2):
366                 akeplano=Menu(menu3b,98,20,200,140,20,akeplano.val)
367                 if akeplano.val in [1,2]:
368                         akeplanoXYZ=Menu(menu3c,98,162,200,55,20,akeplanoXYZ.val) 
369                 enkedir=Menu(menu3d,98,20,100,140,20,enkedir.val)
370                 ok=Button("OK",40,162,100,55,20)
371         elif(editake.val==3):
372                 Button("P",87,192,222,30,18,"Paste buffer matrix")
373                 nLocX=Number("LocX:",98,20,200,170,19,nLocX.val,-1000.,1000.)
374                 nLocY=Number("LocY:",98,20,180,170,19,nLocY.val,-1000.,1000.)
375                 nLocZ=Number("LocZ:",98,20,160,170,19,nLocZ.val,-1000.,1000.)
376                 nRotX=Number("RotX:",98,20,140,170,19,nRotX.val,-1000.,1000.)
377                 nRotY=Number("RotY:",98,20,120,170,19,nRotY.val,-1000.,1000.)
378                 nRotZ=Number("RotZ:",98,20,100,170,19,nRotZ.val,-1000.,1000.)
379                 nSizX=Number("SizeX:",98,20, 80,170,19,nSizX.val,-1000.,1000.)
380                 nSizY=Number("SizeY:",98,20, 60,170,19,nSizY.val,-1000.,1000.)
381                 nSizZ=Number("SizeZ:",98,20, 40,170,19,nSizZ.val,-1000.,1000.)
382                 other=Toggle("Refresh others",98,20,222,170,18,other.val)
383                 oklocrotsiz=Button("OK",30,192,40,30,179)
384
385 def draw2():
386         global creake,ang1,ang2,angulo,radio,pts,ctro,meTx,arcorden
387
388         rectang(15,65,224,257,0.7,0.5,0.65)
389
390         creake=Menu(menu2,98,10,248,143,20,creake.val,"Object type")
391         if(creake.val==1):
392                 pts=Number(menu2a[0],98,20,115,80,18,pts.val,2,1000)
393                 ctro=Toggle(menu2a[1],98,102,115,50,18,ctro.val,"Close the arc with a vertex on its center")
394                 arcorden=Menu(menu2a[2]+"%t|1-2-3%x1|2-3-1%x2|3-1-2%x3",17,155,115,65,18,arcorden.val,"Vertices order (arc is created when this is chosen)")
395                 meTx=String("Object: ",98,20,70,200,22,meTx.val,30,"New object's name")
396         if(creake.val==2):
397                 ang1=Slider(menu2a[4],10,20,220,200,18,ang1.val,-360,360,0,"Initial angle in degrees")
398                 ang2=Slider(menu2a[5],11,20,200,200,18,ang2.val,ang1.val,ang1.val+360,0,"Final angle in degress")
399                 angulo=Slider(menu2a[6],12,20,170,200,18,angulo.val,-360,360,0,"Arc's angle in degress")
400                 radio=Slider(menu2a[7],13,20,140,200,18,radio.val,0,1,0)
401                 pts=Number(menu2a[8],14,20,115,80,18,pts.val,2,1000)
402                 ctro=Toggle(menu2a[9],15,102,115,50,18,ctro.val,"Close the arc with a vertex on its center")
403                 meTx=String(menu2a[10],16,20,70,200,22,meTx.val,30,"Name of the mesh to substitute")
404         if(creake.val==3):
405                 pts=Number("Pts:",98,20,115,80,18,pts.val,2,1000)
406                 ok=Button("OK",18,102,115,120,36)
407                 meTx=String("Object: ",98,20,70,200,22,meTx.val,30,"New object's name")
408                 
409 def draw1():
410         global menueqiX,sepX,aliX,menueqiY,sepY,aliY,menueqiZ,sepZ,aliZ
411         global girX,incX,girY,incY,girZ,incZ
412         global encX,encY,encZ,en2X,en2Y,en2Z
413         global scaX,scaY,scaZ,iScaX,iScaY,iScaZ
414         global CreaNew,Cuantos,toBuffer
415
416 ######################### ALINEACIONES #####################
417         rectang(5,167,254,292,0.7,0.5,0.65)
418         Button("C",81,194,270,25,18,"Copy")
419         Button("P",82,220,270,25,18,"Paste buffer Loc")
420
421         aliX=Toggle("X",0,10,270,30,18,aliX.val,"Activate X alignment")
422         menueqiX=Menu(menu1b,98,41,270,148,18,menueqiX.val,"Separation extremes")  
423         sepX=Number(menu1a[4],0,10,250,179,18,sepX.val,-1000,1000,"X separation distance")
424
425         aliY=Toggle("Y",0,10,230,30,18,aliY.val,"Activate Y alignment")
426         menueqiY=Menu(menu1b,98,41,230,148,18,menueqiY.val,"Separation extremes")  
427         sepY=Number(menu1a[4],0,10,210,179,18,sepY.val,-1000,1000,"Y separation distance")
428
429         aliZ=Toggle("Z",0,10,190,30,18,aliZ.val,"Activate Z alignment")
430         menueqiZ=Menu(menu1b,98,41,190,148,18,menueqiZ.val,"Separation extremes")  
431         sepZ=Number(menu1a[4],0,10,170,179,18,sepZ.val,-1000,1000,"Y separation distance")
432
433 ########################## GIROS ##############################
434         rectang(5,97,254,162,0.67,0.54,0.1)
435         Button("C",83,194,140,25,18,"Copy")
436         Button("P",84,220,140,25,18,"Paste buffer Rot")
437
438         girX=Toggle("X",0,10,140,30,18,girX.val,"Increment RotX values")
439         incX=Number("X: ",0,42,140,147,18,incX.val,-180,180,"X increment in degress")
440         girY=Toggle("Y",0,10,120,30,18,girY.val,"Increment RotY values")
441         incY=Number("Y: ",0,42,120,147,18,incY.val,-180,180,"Y increment in degrees")
442         girZ=Toggle("Z",0,10,100,30,18,girZ.val,"Increment RotZ values")
443         incZ=Number("Z: ",0,42,100,147,18,incZ.val,-180,180,"Z increment in degrees")
444
445 ######################### ESCALADOS ##########################
446         rectang(5,27,254,92,0.27,0.54,0.4)
447         Button("C",85,194,70,25,18,"Copy")
448         Button("P",86,220,70,25,18,"Paste buffer Sca")
449
450         scaX=Toggle("X",0,10,70,30,18,scaX.val)
451         iScaX=Number(menu1a[7],0,42,70,147,18,iScaX.val,-180,180,"X scale increment")
452         scaY=Toggle("Y",0,10,50,30,18,scaY.val)
453         iScaY=Number(menu1a[7],0,42,50,147,18,iScaY.val,-180,180,"Y scale increment")
454         scaZ=Toggle("Z",0,10,30,30,18,scaZ.val)
455         iScaZ=Number(menu1a[7],0,42,30,147,18,iScaZ.val,-180,180,"Z scale increment")
456 ########################## ENCAJES ##########################
457         rectang(5,317,254,363,0.1,0.5,0.6)
458
459         encX=Toggle(menu1a[0]+"X",0,10,340,43,18,encX.val,"Move object in X")
460         encY=Toggle(menu1a[0]+"Y",0,55,340,43,18,encY.val,"Move object in Y")
461         encZ=Toggle(menu1a[0]+"Z",0,100,340,43,18,encZ.val,"Move object in Z")
462
463         en2X=Toggle(menu1a[1]+"X",0,10,320,43,18,en2X.val,"Adjust X size")
464         en2Y=Toggle(menu1a[1]+"Y",0,55,320,43,18,en2Y.val,"Adjust Y size")
465         en2Z=Toggle(menu1a[1]+"Z",0,100,320,43,18,en2Z.val,"Adjust Z size")
466 ######################################################
467         CreaNew=Toggle(menu1a[8],98,10,295,129,18,CreaNew.val,"Create new objects or just modify selected?")
468         if CreaNew.val:
469                 Cuantos=Number('',98,139,295,30,18,Cuantos.val,1,999,"Number of copies")
470         Button(menu1a[5],1,190,170,60,98,"Align")               #Alinea
471         Button(menu1a[6],2,190,100,60,38,"Rotate")              #Gira
472         Button(menu1a[9],3,190,30,29,38,"Scale +")              #Escala+
473         Button(menu1a[10],7,220,30,30,38,"Scale *")             #Escala*
474         Button(menu1a[2],6,147,320,45,38,"Fit active in one or two others using max limits (creates new object)")               #Encaja
475         Button(menu1a[3],5,195,320,55,38,"Fit active in one or two others using min limits (creates new object)")               #Abarca
476
477 def HaceArco(pts,ang1,angul,ctro,R):
478         me=New()
479         for c in range(pts):
480                 alfa=(ang1+angul*c/(pts-1))*pi/180
481                 if (c): v1=v
482                 v=Vert()
483                 v.co[0]=R*cos(alfa)
484                 v.co[1]=R*sin(alfa)
485                 v.co[2]=0
486                 me.verts.append(v)
487                 if (c):
488                         f=Face()
489                         f.v=[v1]
490                         f.v.append(v)
491                         me.faces.append(f)
492                 if (c==0): v0=v
493         if(ctro):
494                 v1=v
495                 v=Vert()
496                 me.verts.append(v)
497                 f=Face()
498                 f.v=[v1,v]
499                 me.faces.append(f)
500                 f=Face()
501                 f.v=[v,v0]
502                 me.faces.append(f)
503         return me
504
505 def Exec_align(os,c,ali,eqi,sep):
506         coor=os[0].loc[c]
507         ademas=0
508         flag=0
509         for o in os:
510                 m=o.data     #Maya del objeto
511                 ctr=[0,0,0]
512                 if(eqi[c]==2):
513                         for d in range(3): ctr[d]=Extremo(m.verts,o.matrix)[1][d]
514                 elif(eqi[c]==3 or eqi[c]==6):
515                         ctr=Extremo(m.verts,o.matrix)[0]
516                 elif(eqi[c]==4):
517                         ctr=Extremo(m.verts,o.matrix)[2]
518                 elif(eqi[c]==5):
519                         ctr=Media(m.verts)
520                         ctr=GloVrt(ctr,o.matrix)
521
522                 if (eqi[c]>1): ademas=ctr[c]-o.loc[c]
523                 if (flag):      coor=coor-ademas
524                 else:   flag=1
525                 SituaL(o,c,coor)
526                 if(eqi[c]==6): ademas=Extremo(m.verts,o.matrix)[2][c]-o.loc[c]
527                 coor=coor+sep[c]+ademas
528
529 def event(evt,val):
530         if (evt==ESCKEY and not val):
531                 print "Bye..."
532                 Exit()
533
534 #@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@22#
535
536 def bevent(evt):
537         global me
538         global BfL,BfR,BfS
539         #print "Event:",evt
540         os=Blender.Object.GetSelected()
541         if os:
542                 oa=os[0]
543
544         ##########MENU BUFFER
545         if evt==80:
546                 copi=toBuffer.val
547                 if copi==1:
548                         if len(os)==2:
549                                 for c in range(3): BfL[c]=os[1].loc[c]-os[0].loc[c]
550                                 print "Copied to Loc buffer:",BfL
551                         else:
552                                 PupMenu('ERROR%t|Selecciona 2 objetos|Just select 2 objects!')
553                 if copi==2:
554                         if len(os)==2:
555                                 BfL=3*[sqrt((os[1].loc[0]-os[0].loc[0])**2+
556 (os[1].loc[1]-oa.loc[1])**2+
557 (os[1].loc[2]-oa.loc[2])**2)]
558                                 print "Copied to Loc buffer:",BfL
559                         else:
560                                 PupMenu('ERROR%t|Selecciona 2 objetos|Just select 2 objects!')
561                 if copi==3:
562                         if len(os)==2:
563                                 for c in range(3): BfR[c]=os[1].rot[c]-oa.rot[c]
564                                 print "Copied to Rot buffer:",BfR
565                         else:
566                                 PupMenu('ERROR%t|Selecciona 2 objetos|Just select 2 objects!')
567                 if copi==4 and len(os):
568                         lista=[]
569                         for o in os: lista.append(o.loc)
570                         BfL=Media(lista)
571                         print "Copied to Loc buffer:",BfL
572                         lista=[]
573                         for o in os: lista.append(o.rot)
574                         BfR=Media(lista)
575                         for c in range(3): BfR[c]*=180/pi
576                         print "Copied to Rot buffer:",BfR
577                         lista=[]
578                         for o in os: lista.append(o.size)
579                         BfS=Media(lista)
580                         print "Copiado to Size buffer:",BfS
581                 if copi==5:
582                         print"\n_Buffer contents_\n"
583                         for c in range(3): print "Loc",coo[c]," :",BfL[c]
584                         for c in range(3): print "Rot",coo[c]," :",BfR[c]
585                         for c in range(3): print "Size",coo[c],":",BfS[c]
586                         print "______________________"
587
588         ##########COPY
589         if evt==81:
590                 X       =[sepX.val,sepY.val,sepZ.val]
591                 ali     =[aliX.val,aliY.val,aliZ.val]
592                 for c in range(3):
593                         if ali[c]:
594                                 BfL[c]=X[c]
595                                 print"Copying to Loc buffer",coo[c],"value", BfL[c]
596
597         if evt==83:
598                 X       =[incX.val,incY.val,incZ.val]
599                 ali     =[girX.val,girY.val,girZ.val]
600                 for c in range(3):
601                         if ali[c]:
602                                 BfR[c]=X[c]
603                                 print"Copying to Rot buffer",coo[c],"value", BfR[c]
604
605         if evt==85:
606                 X       =[iScaX.val,iScaY.val,iScaZ.val]
607                 ali     =[scaX.val,scaY.val,scaZ.val]
608                 for c in range(3):
609                         if ali[c]:
610                                 BfS[c]=X[c]
611                                 print"Copying to Size buffer",coo[c],"value", BfS[c]
612
613         ##########PASTE
614         if evt==82:
615                 X       =[sepX.val,sepY.val,sepZ.val]
616                 ali     =[aliX.val,aliY.val,aliZ.val]
617                 for c in range(3):
618                         if ali[c]:
619                                 X[c]=BfL[c]
620                                 print"Retrieving from buffer Loc",coo[c],"value", BfL[c]
621                 sepX.val,sepY.val,sepZ.val=X
622
623         if evt==84:
624                 X       =[incX.val,incY.val,incZ.val]
625                 ali     =[girX.val,girY.val,girZ.val]
626                 for c in range(3):
627                         if ali[c]:
628                                 X[c]=BfR[c]
629                                 print"Retrieving from buffer Rot",coo[c],"value", BfR[c]
630                 incX.val,incY.val,incZ.val=X
631
632         if evt==86:
633                 X       =[iScaX.val,iScaY.val,iScaZ.val]
634                 ali     =[scaX.val,scaY.val,scaZ.val]
635                 for c in range(3):
636                         if ali[c]:
637                                 X[c]=BfS[c]
638                                 print"Retrieving from buffer Size",coo[c],"value", BfS[c]
639                 iScaX.val,iScaY.val,iScaZ.val=X
640
641         if evt==87:
642                 print"Retrieving <ApplyLocRotSize> matrix"
643                 nLocX.val,nLocY.val,nLocZ.val=BfL
644                 nRotX.val,nRotY.val,nRotZ.val=BfR
645                 nSizX.val,nSizY.val,nSizZ.val=BfS
646
647         if evt==88:
648                 print"Retrieving float number to button"
649                 x=[BfL[0],BfL[1],BfL[2],
650 sqrt(BfL[0]**2+BfL[1]**2+BfL[2]**2),
651 BfR[0],BfR[1],BfR[2],
652 BfS[0],BfS[1],BfS[2]]
653                 numReal.val = x[menuPaste.val-1]
654
655         if evt==50:
656                 if moveke.val==1:                               #               MOVER HACIA EL O.ACTIVO
657                         oaV=Vector(list(oa.loc))
658                         for o in os[1:]:
659                                 oV=Vector(list(o.loc))
660                                 v=oV-oaV                                                                        #Calculo del vector final
661                                 d=sqrt(DotVecs(v,v))
662                                 v1=v*numReal.val
663                                 if movekomo.val==1:
664                                         v1 = oaV+v1/d
665                                 elif movekomo.val==2:
666                                         v1 = oV+v1/d
667                                 elif movekomo.val==3:
668                                         v1 = oaV+v1
669                                 o.setLocation(v1)
670
671                 if moveke.val==2:                                       #       MOVER AL AZAR
672                         n=numReal.val
673                         if menuLRS.val==2:
674                                 n=n*pi/180
675                         for o in os:
676                                 v1=Vector([
677 aliX.val * (2*n*random() - n),
678 aliY.val * (2*n*random() - n),
679 aliZ.val * (2*n*random() - n)])
680
681                                 if menuLRS.val==1:                                                      #Uso del vector final
682                                         oV=Vector(list(o.loc))
683                                         o.setLocation(oV+v1)
684                                 elif menuLRS.val==2:
685                                         v=Vector(list(o.getEuler()))+v1
686                                         o.setEuler(v)
687                                 else:
688                                         oV=Vector(list(o.size))
689                                         o.setSize(oV+v1)
690
691         if evt==40:                             #                                       PROYECTA EN PLANOS
692                 n=Vector([0.,0.,0.])
693
694                 numObjs=-len(os)+1
695                 if akeplano.val==1:     #plano global
696                         n[akeplanoXYZ.val-1]=1.
697                         numObjs=-len(os)
698                 elif akeplano.val==2: n=oa.matrix[akeplanoXYZ.val-1] #plano local
699                 n.resize3D()
700
701                 d=Vector([0.,0.,0.])
702                 if enkedir.val<4: d[enkedir.val-1]=1.   #direccion global
703                 elif enkedir.val==4: d=n                                #direc. ortog. al plano
704
705                 n1 = Vector([-n[2],n[0],n[1]])
706                 N1 = CrossVecs (n,n1)
707                 N2 = CrossVecs (n,N1)   
708                 n.normalize(), N1.normalize(), N2.normalize()
709                 #print"productos escalares (deben ser 0):",DotVecs(N1,n),DotVecs(N2,n),DotVecs(N2,N1)
710                 p=oa.loc
711                 N=Matrix(
712         [N1[0],N1[1],N1[2],0],
713         [N2[0],N2[1],N2[2],0],
714         [ n[0], n[1], n[2],0],
715         [ p[0], p[1], p[2],1])
716                 NI=CopyMat(N)
717                 NI.invert()
718
719                 dN=VecMultMat(d,NI.rotationPart())
720                 if dN[2]==0:
721                         PupMenu('Error%t|Operacion no permitida: la direccion esta en el plano%x1|Illegal operation: plane contains direction%x2')
722                         return
723                 print"Absolute direction:",d,"\nPlane normal:",n,"\nRelative direction:",dN
724                 for o in filter(mallaScan,os[numObjs:]):
725                         me=Blender.NMesh.GetRawFromObject(o.name)
726                         M=o.matrix
727                         for v in me.verts:
728                                 v0=Vector([v[0],v[1],v[2]])
729                                 v0=GloVrt(v0,M)
730                                 v0.resize4D()
731                                 v0=VecMultMat(v0,NI)
732                                 v[0] = v0[0] - v0[2]/dN[2] * dN[0]
733                                 v[1] = v0[1] - v0[2]/dN[2] * dN[1]
734                                 v[2] = 0
735                         oo=Blender.Object.New('Mesh')
736                         oo.setName(o.name+'Proy')
737                         oo.link(me)
738                         sc.link(oo)
739                         oo.setMatrix(N)
740
741         if(evt>9 and evt<17):   #       HACE ARCO INTERACTIV.
742                 GetRaw(meTx.val)
743                 if(evt==11): angulo.val=ang2.val-ang1.val
744                 if(evt==12 or evt==10): ang2.val=(ang1.val+angulo.val)
745                 m=HaceArco(pts.val,ang1.val,angulo.val,ctro.val,radio.val)
746                 PutRaw(m,meTx.val)
747
748         if evt in [17,18]:      # HACE ARCO CON 3 PTS.
749                 o=oa
750                 m=o.getData()
751                 M=o.matrix
752                 if arcorden.val==1 or evt==18:
753                         p1,p2,p3=m.verts[0],m.verts[1],m.verts[2]
754                 elif arcorden.val==2:
755                         p1,p2,p3=m.verts[1],m.verts[2],m.verts[0]
756                 elif arcorden.val==3:
757                         p1,p2,p3=m.verts[2],m.verts[0],m.verts[1]
758
759                 p1=GloVrt(p1,M)
760                 p2=GloVrt(p2,M)
761                 p3=GloVrt(p3,M)
762
763                 print "Points:\n ",p1,p2,p3
764                 
765                 p21=p2-p1
766                 p31=p3-p1
767
768                 M1=CrossVecs(p21,p31)
769
770                 D=DotVecs(M1,p1)
771                 D2=DotVecs(p21,p1+p2)/2
772                 D3=DotVecs(p31,p1+p3)/2
773
774                 SS=Matrix(
775                 [M1[0],M1[1],M1[2]],
776                 [p21[0],p21[1],p21[2]],
777                 [p31[0],p31[1],p31[2]],
778                 )
779                 O=Sistema(SS,Vector([D,D2,D3]))
780                 
781                 v2=p2-O
782                 b3=p3-O
783                 vN=CrossVecs(v2,b3)
784                 v3=CrossVecs(v2,vN)
785
786                         #Terna ortogonal: v2,vN,v3
787                 R=sqrt(DotVecs(v2,v2))
788                 RN=sqrt(DotVecs(vN,vN))
789                 R3=sqrt(DotVecs(v3,v3))
790
791                 if evt==18: angul=2*pi
792                 else: angul=AngleBetweenVecs(v2,b3)
793
794                 print "Center:",O
795                 print "Radius :",R,"RN:",RN,"R3:",R3
796                 print "Angle:",angul
797                 M2=Matrix([v2[0]/R,v2[1]/R,v2[2]/R],[-v3[0]/R3,-v3[1]/R3,-v3[2]/R3],[vN[0]/RN,vN[1]/RN,vN[2]/RN])
798
799                 arco=HaceArco(pts.val,0,angul,ctro.val,1)
800                 oo=CreaObjDeMalla(arco,o,meTx.val+'.In')
801                 EU=M2.toEuler()
802                 EU=EU[0]*pi/180,EU[1]*pi/180,EU[2]*pi/180
803                 oo.RotX,oo.RotY,oo.RotZ=EU[0],EU[1],EU[2]
804                 oo.setLocation(O)
805                 oo.setSize(R,R,R)
806
807                 if evt==17:
808                         angul=angul-360
809                         arco=HaceArco(pts.val,0,angul,ctro.val,1)
810                         oo=CreaObjDeMalla(arco,o,meTx.val+'.Ex')
811                         oo.RotX,oo.RotY,oo.RotZ=EU[0],EU[1],EU[2]
812                         oo.setLocation(O)
813                         oo.setSize(R,R,R)
814
815         if(evt==20): # SUBDIVIDE
816                 for o in filter(mallaScan,os):
817                         m=o.data
818                         mm=New()
819                         mm.name=m.name+'.Subdiv'
820                         for v in m.verts: mm.verts.append(v)
821                         N=ndiv.val
822                         NV=len(m.verts)-1
823                         for k1 in range(NV+1):
824                                 v1=m.verts[k1]
825                                 for k2 in range(NV-k1):
826                                         v2=m.verts[NV-k2]
827                                         for f in m.faces:
828                                                 if (v1 in f.v) and (v2 in f.v): #       SI...
829                                                         dif=abs(f.v.index(v2)-f.v.index(v1))
830                                                         if dif==1 or dif==len(f.v)-1: #...entonces f contiene la arista v1-v2
831                                                                 v=v1
832                                                                 for K in range(N):
833                                                                         cara=Face()
834                                                                         cara.v.append(v)
835                                                                         if K<N-1:
836                                                                                 v=Vert()
837                                                                                 for c in range(3): v.co[c]=(v1.co[c]*(N-K-1)+v2.co[c]*(K+1))/N
838                                                                                 mm.verts.append(v)
839                                                                         elif K==N-1: v=v2
840                                                                         cara.v.append(v)
841                                                                         mm.faces.append(cara)
842                                                         break #para que no se repitan aristas comunes a varias caras
843                         CreaObjDeMalla(mm,o,o.name+'.Subdiv')
844
845         if evt==30:                                             # APLICA LOC.ROT.SIZE
846                 for o in filter(mallaScan,os):
847                         M=o.matrix
848
849                         eu=Euler([nRotX.val,nRotY.val,nRotZ.val])
850                         Mr=eu.toMatrix()
851                         Mr.resize4x4()
852                         Mt=TranslationMatrix(Vector([nLocX.val,nLocY.val,nLocZ.val]))
853
854                         o.setMatrix(Mr*Mt)
855                         o.setSize(nSizX.val,nSizY.val,nSizZ.val)
856                         MI=o.getInverseMatrix()
857                         P=M*MI
858                         maya=o.getData()
859                         for v in maya.verts:
860                                 w=list(VecMultMat(Vector([v[0],v[1],v[2],1]),P))
861                                 for c in range(3):      v[c]=w[c]/o.size[c]
862
863                         maya.update()
864                         if other.val:
865                                 P.invert()
866                                 for oo in Blender.Object.Get():
867                                         if oo.data.name==maya.name and o!=oo:
868                                                 N=oo.getMatrix()
869                                                 oo.setMatrix(P*N)
870                                                 oo.setSize(oo.SizeX*nSizX.val,oo.SizeY*nSizY.val,oo.SizeZ*nSizZ.val)
871
872         if((evt==5 or evt==6) and len(os)):   #  ENCAJA-ABARCA
873                 enc=[encX.val,encY.val,encZ.val]
874                 en2=[en2X.val,en2Y.val,en2Z.val]
875                 me=GetRaw(oa.data.name)
876                 meVs=me.verts
877                 for v in meVs:
878                         w=GloVrt(v,oa.matrix)
879                         for c in range(3):
880                                 v[c]=w[c]
881                 for c in range(3):
882                         if en2[c] or enc[c]:
883                                 if (len(os)>1):
884                                         n1=Extremo(os[1].data.verts,os[1].matrix)[0][c]
885                                         m1=Extremo(os[1].data.verts,os[1].matrix)[2][c]
886                                 if (len(os)>2):
887                                         n2=Extremo(os[2].data.verts,os[2].matrix)[0][c]
888                                         m2=Extremo(os[2].data.verts,os[2].matrix)[2][c]
889                                 n0=Extremo(meVs)[0] [c]
890                                 m0=Extremo(meVs)[2] [c]
891                                 ancho=m0-n0
892                                 pm=(m0+n0)/2
893                                 if (len(os)==1): n1,m1=n0,m0
894                                 if (len(os)<3): n2,m2=n1,m1
895                                 if (n2<n1):
896                                         t,s=n2,m2
897                                         n2,n1,m2,m1=n1,t,m1,s
898                                 print coo[c],n0,m0,n1,m1,n2,m2
899                         for v in meVs:
900                                 A , factor = 0. , 1.
901                                 if enc[c]:
902                                         if evt==5:      pm2=(n2+m1)/2
903                                         else:           pm2=(m2+n1)/2
904                                         v[c]+= pm2-pm
905                                 if en2[c] and ancho:
906                                         if evt==5:      factor=(n2-m1)/ancho
907                                         else:           factor=(m2-n1)/ancho
908                                         v[c]=pm2+(v[c]-pm2)*factor
909                 PutRaw(me)
910
911         elif (evt==1 and len(os)):
912                 ali=[aliX.val,aliY.val,aliZ.val]
913                 eqi=[menueqiX.val,menueqiY.val,menueqiZ.val]
914                 sep=[sepX.val,sepY.val,sepZ.val]
915                 if CreaNew.val:
916                         for o in filter(mallaScan,os):
917                                 newos=[o]
918                                 for i in range(Cuantos.val):
919                                         newo=CreaObjDeMalla(o.getData(),o,o.name)
920                                         newos.append(newo)
921                                         for c in range(3):
922                                                 if (ali[c]):
923                                                         Exec_align(newos,c,ali,eqi,sep)
924                 else:
925                         for c in range(3):
926                                 if (ali[c]):
927                                         Exec_align(filter(mallaScan,os),c,ali,eqi,sep)
928         elif (evt==2 and len(os)):
929                 gir=[girX.val,girY.val,girZ.val]
930                 inc=[incX.val,incY.val,incZ.val]
931                 if CreaNew.val:
932                         for o in filter(mallaScan,os):
933                                 newos=[o]
934                                 for i in range(Cuantos.val):
935                                         newo=CreaObjDeMalla(o.getData(),o,o.name)
936                                         newos.append(newo)
937                                         for c in range(3):
938                                                 valor=o.rot[c]
939                                                 for oo in newos:
940                                                         if (gir[c]):
941                                                                 SituaR(oo,c,valor)
942                                                                 valor=valor+inc[c]*pi/180
943                 else:
944                         for c in range(3):
945                                 if (gir[c]):
946                                         valor=oa.rot[c]
947                                         for o in os:
948                                                 SituaR(o,c,valor)
949                                                 valor=valor+inc[c]*pi/180
950                                 
951         elif evt in [3,7] and len(os):
952                 sca=[scaX.val,scaY.val,scaZ.val]
953                 inc=[iScaX.val,iScaY.val,iScaZ.val]
954                 if CreaNew.val:
955                         for o in filter(mallaScan,os):
956                                 newos=[o]
957                                 for i in range(Cuantos.val):
958                                         newo=CreaObjDeMalla(o.getData(),o,o.name)
959                                         newos.append(newo)
960                                         for c in range(3):
961                                                 valor=o.size[c]
962                                                 for oo in newos:
963                                                         if (sca[c]):
964                                                                 SituaS(oo,c,valor)
965                                                                 if evt==3: valor=valor+inc[c]
966                                                                 if evt==7: valor=valor*inc[c]
967                 else:
968                         for c in range(3):
969                                 if (sca[c]):
970                                         valor=oa.size[c]
971                                         for o in os:
972                                                 SituaS(o,c,valor)
973                                                 if evt==3: valor=valor+inc[c]
974                                                 if evt==7: valor=valor*inc[c]
975
976         elif (evt==99): Exit()
977         Blender.Redraw()
978
979 #file=open(path+dirsep+'KUlang.txt','r')
980 #file=open(dirsep.join(path)+dirsep+'KUlang.txt','r')
981
982 file=open(join(path,'KUlang.txt'),'r')
983 fich=file.readlines()
984 print "\n\nKloputils",fich[0]
985 for i in range(len(fich)):
986         if fich[i]==Lang+'\012': break
987 print "Language:",fich[i]
988 menuExit=fich[i+1]#Sale prog.
989 menu0=fich[i+2]#Pral.
990 J=int(fich[i+3])#Alinea:botones
991 menu1a=[]
992 for j in range(J): menu1a.append(fich[i+j+4])
993 i=i+J
994 menu1b=fich[i+4]#Alinea:menu separa
995 menu2=str(fich[i+5])#Crea:menu
996 J=int(fich[i+6])#Crea:botones
997 menu2a=[]
998 for j in range(J): menu2a.append(fich[i+j+7])
999 i=i+J
1000 menu3=fich[i+7]#Modif:menu
1001 menu3a=fich[i+8]#Modif:"partes
1002 menu3b=fich[i+9]#Modif:menu plano
1003 menu3c=fich[i+10]#Modf:"Actua...
1004 menu3d=fich[i+11]#Modif:menu dire
1005 menu3e=fich[i+12]#Modf:"Captura
1006 menu4=fich[i+13]#Buffer
1007 menu5=fich[i+14]#ModifObjs
1008 menu5a=fich[i+15]
1009
1010 file.close
1011
1012 Register(draw,event,bevent)