2.5: Top Menu
[blender.git] / release / scripts / discombobulator.py
1 #!BPY
2
3 """
4 Name: 'Discombobulator'
5 Blender: 237
6 Group: 'Mesh'
7 Tip: 'Adds random geometry to a mesh'
8 """
9
10 __author__ = "Evan J. Rosky (syrux)"
11 __url__ = ("Script's homepage, http://evan.nerdsofparadise.com/programs/discombobulator/index.html")
12 __version__ = "237"
13 __bpydoc__ = """\
14 Discombobulator adds random geometry to a mesh.
15
16 As an example, this script can easily give a "high-tech"
17 look to walls and spaceships.
18
19 Definitions:<br>
20   - Protrusions: extrusions of each original face on the mesh.
21 You may have from 1 to 4 protrusions on each face.<br>
22   - Taper: The tips of each protrusion will be a percentage
23 smaller than the base.<br>
24   - Doodads: small extruded blocks/shapes that are randomly placed
25 about the top of a protrusion or face.
26
27
28 Usage:<br>
29   Input your settings, make sure the mesh you would like to modify
30 is selected (active) and then click on "Discombobulate".<br>
31   See the scripts tutorial page (on the homepage) for more info.
32
33
34 New Features:<br>
35   - Will use existing materials if there are any.<br>
36   - Clicking "Assign materials by part" will allow assigning
37 of different material indices to Protrusion or Doodad Sides
38 and Tops in the gui element below it.<br>
39   - Setting a material index to 0 will use whatever material
40 is assigned to the face that is discombobulated.
41   - You can now scroll using the arrow keys.
42
43
44 Notes:<br>
45   - Modifications can be restricted to selected faces
46 by setting "Only selected faces" for protrusions and/or
47 doodads.<br>
48   - It's possible to restrict mesh generation to add only
49 protrusions or only doodads instead of both.<br>
50   - You may also choose to have Discombobulator select the
51 tops of created protrusions by clicking the corresponding
52 number of protrusion buttons under "Select Tops". You may 
53 also do the same for doodads by choosing "Select Doodads" and
54 "Only Select Tops". You may choose to select the whole doodads 
55 by leaving "Only Select Tops" off.<br>
56   - By selecting "Deselect Selected" you can have
57 discombobulator deselect everything but the selections it
58 makes.<br>
59   - The "Face %" option will set the percentage of faces that
60 will be modified either for the doodads or the protrusions.<br>
61   - "Copy Before Modifying" will create a new object with the
62 modifications where leaving it off will overwrite the original
63 mesh.<br>
64
65 You can find more information at the Link above.
66 """
67
68
69 # $Id$
70
71 # Updated 2006-09-26
72 # Changes since last version: 
73 #     > Works with Blender CVS and hopefully with Blender 2.40.
74 #     > Swaps min/max values when min>max rather than complaining.
75 #     > Will keep previously assigned materials.
76 #     > Now allows user to assign custom material indices to
77 #            Protrusion and Doodad Sides and Tops.
78 #     > The initial Gui Layout will change depending on the aspect
79 #            ratio of the window it is in.
80 #     > Using the arrow keys will scroll the gui.
81
82 # --------------------------------------------------------------------------
83 # Discombobulator v2.1b
84 # by Evan J. Rosky, 2005
85 # This plugin is protected by the GPL: Gnu Public Licence
86 # GPL - http://www.gnu.org/copyleft/gpl.html
87 # --------------------------------------------------------------------------
88 # ***** BEGIN GPL LICENSE BLOCK *****
89 #
90 # Copyright (C) 2005: Evan J. Rosky
91 #
92 # This program is free software; you can redistribute it and/or
93 # modify it under the terms of the GNU General Public License
94 # as published by the Free Software Foundation; either version 2
95 # of the License, or (at your option) any later version.
96 #
97 # This program is distributed in the hope that it will be useful,
98 # but WITHOUT ANY WARRANTY; without even the implied warranty of
99 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
100 # GNU General Public License for more details.
101 #
102 # You should have received a copy of the GNU General Public License
103 # along with this program; if not, write to the Free Software Foundation,
104 # Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
105 #
106 # ***** END GPL LICENCE BLOCK *****
107 # --------------------------------------------------------------------------
108
109 #Hit Alt-P to run
110
111 import Blender
112 from Blender import NMesh,Object,Material,Window,Types,Scene
113 from Blender.NMesh import Vert,Face
114 from Blender.Mathutils import *
115
116 import defaultdoodads
117 import BPyMathutils
118 from BPyMathutils import genrand
119 a = BPyMathutils.sgenrand(int(round(Rand(1000,99999),0)))
120
121 #Create random numbers
122 def randnum(low,high):
123         num = genrand()
124         num = num*(high-low)
125         num = num+low
126         return num
127
128 #Object Vars
129 newmesh = NMesh.GetRaw()
130 materialArray = [0]
131
132 #Material Vars
133 reassignMats = 0
134 protSideMat = 1
135 protTopMat = 2
136 doodSideMat = 3
137 doodTopMat = 4
138 thereAreMats = 0
139 currmat = 0
140
141 #Global Vars
142 makenewobj = 1
143 errortext = "Remember to select an object."
144 editmode = 0
145
146 #Protrusion Vars
147 makeprots = 1
148 faceschangedpercent = 1.0
149 minimumheight = 0.2
150 maximumheight = 0.4
151 subface1 = 1
152 subface2 = 1
153 subface3 = 1
154 subface4 = 1
155 subfaceArray = [1,2,3,4]
156 minsubfaces = 1
157 minimumtaperpercent = 0.15
158 maximumtaperpercent = 0.35
159 useselectedfaces = 0
160 selectface1 = 1
161 selectface2 = 1
162 selectface3 = 1
163 selectface4 = 1
164 deselface = 1
165
166 #Doodad Vars
167 makedoodads = 1
168 doodadfacepercent = 1.0
169 selectdoodad = 0
170 onlyonprotrusions = 0
171 doodonselectedfaces = 0
172 selectdoodadtoponly = 0
173 doodad1 = 1
174 doodad2 = 1
175 doodad3 = 1
176 doodad4 = 1
177 doodad5 = 1
178 doodad6 = 1
179 doodadminperface = 2
180 doodadmaxperface = 6
181 doodadminsize = 0.15
182 doodadmaxsize = 0.45
183 doodadminheight = 0.0
184 doodadmaxheight = 0.1
185 doodadArray = [1,2,3,4,5,6]
186
187 def makeSubfaceArray():
188         global subfaceArray
189         global subface1
190         global subface2
191         global subface3
192         global subface4
193         
194         subfaceArray = []
195         if subface1 > 0:
196                 subfaceArray.append(1)
197         if subface2 > 0:
198                 subfaceArray.append(2)
199         if subface3 > 0:
200                 subfaceArray.append(3)
201         if subface4 > 0:
202                 subfaceArray.append(4)
203
204 def makeDoodadArray():
205         global doodadArray
206         global doodad1
207         global doodad2
208         global doodad3
209         global doodad4
210         global doodad5
211         global doodad6
212         
213         doodadArray = []
214         if doodad1 > 0:
215                 doodadArray.append(1)
216         if doodad2 > 0:
217                 doodadArray.append(2)
218         if doodad3 > 0:
219                 doodadArray.append(3)
220         if doodad4 > 0:
221                 doodadArray.append(4)
222         if doodad5 > 0:
223                 doodadArray.append(5)
224         if doodad6 > 0:
225                 doodadArray.append(6)
226
227 def extrude(mid,nor,protrusion,v1,v2,v3,v4,tosel=1,flipnor=0):
228         taper = 1 - randnum(minimumtaperpercent,maximumtaperpercent)
229         newmesh_verts = newmesh.verts
230         newmesh_faces = newmesh.faces
231         
232         vert = newmesh_verts[v1]
233         point = (vert.co - mid)*taper + mid + protrusion*Vector(nor)
234         ver = Vert(point[0],point[1],point[2])
235         ver.sel = tosel
236         newmesh_verts.append(ver)
237         vert = newmesh_verts[v2]
238         point = (vert.co - mid)*taper + mid + protrusion*Vector(nor)
239         ver = Vert(point[0],point[1],point[2])
240         ver.sel = tosel
241         newmesh_verts.append(ver)
242         vert = newmesh_verts[v3]
243         point = (vert.co - mid)*taper + mid + protrusion*Vector(nor)
244         ver = Vert(point[0],point[1],point[2])
245         ver.sel = tosel
246         newmesh_verts.append(ver)
247         vert = newmesh_verts[v4]
248         point = (vert.co - mid)*taper + mid + protrusion*Vector(nor)
249         ver = Vert(point[0],point[1],point[2])
250         ver.sel = tosel
251         newmesh_verts.append(ver)
252         
253         faceindex = len(newmesh_verts) - 4
254         
255         #side face 1
256         face = Face([newmesh_verts[v1], newmesh_verts[v2], newmesh_verts[faceindex+1], newmesh_verts[faceindex]])
257         if flipnor != 0:
258                 face.v.reverse()
259         if thereAreMats == 1:
260                 if reassignMats == 0 or protSideMat == 0:
261                         face.materialIndex = currmat
262                 else:
263                         face.materialIndex = protSideMat-1
264         newmesh_faces.append(face)
265         
266         #side face 2
267         face = Face([newmesh_verts[v2], newmesh_verts[v3], newmesh_verts[faceindex+2], newmesh_verts[faceindex+1]])
268         if flipnor != 0:
269                 face.v.reverse()
270         if thereAreMats == 1:
271                 if reassignMats == 0 or protSideMat == 0:
272                         face.materialIndex = currmat
273                 else:
274                         face.materialIndex = protSideMat-1
275         newmesh_faces.append(face)
276         
277         #side face 3
278         face = Face([newmesh_verts[v3], newmesh_verts[v4], newmesh_verts[faceindex+3], newmesh_verts[faceindex+2]])
279         if flipnor != 0:
280                 face.v.reverse()
281         if thereAreMats == 1:
282                 if reassignMats == 0 or protSideMat == 0:
283                         face.materialIndex = currmat
284                 else:
285                         face.materialIndex = protSideMat-1
286         newmesh_faces.append(face)
287         
288         #side face 4
289         face = Face([newmesh_verts[v4], newmesh_verts[v1], newmesh_verts[faceindex], newmesh_verts[faceindex+3]])
290         if flipnor != 0:
291                 face.v.reverse()
292         if thereAreMats == 1:
293                 if reassignMats == 0 or protSideMat == 0:
294                         face.materialIndex = currmat
295                 else:
296                         face.materialIndex = protSideMat-1
297         newmesh_faces.append(face)
298         
299         #top face       
300         face = Face(newmesh_verts[-4:])
301         if flipnor != 0:
302                 face.v.reverse()
303         if tosel == 1:
304                 face.sel = 1
305         if thereAreMats == 1:
306                 if reassignMats == 0 or protTopMat == 0:
307                         face.materialIndex = currmat
308                 else:
309                         face.materialIndex = protTopMat-1
310         newmesh_faces.append(face)
311         return face
312
313 #Sets the global protrusion values
314 def setProtrusionValues(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15):
315         
316         #Protrusions
317         global makeprots
318         global minimumtaperpercent
319         global maximumtaperpercent
320         global faceschangedpercent
321         global minimumheight
322         global maximumheight
323         global subface1
324         global subface2
325         global subface3
326         global subface4
327         global useselectedfaces
328         global selectface1
329         global selectface2
330         global selectface3
331         global selectface4
332         global deselface
333         global subfaceArray
334         
335         #Protrusions
336         makeprots = p0
337         faceschangedpercent = p1
338         minimumheight = p2
339         maximumheight = p3
340         subface1 = p4
341         subface2 = p5
342         subface3 = p6
343         subface4 = p7
344         minimumtaperpercent = p8
345         maximumtaperpercent = p9
346         useselectedfaces = p10
347         selectface1 = p11
348         selectface2 = p12
349         selectface3 = p13
350         selectface4 = p14
351         deselface = p15
352         makeSubfaceArray()
353         if len(subfaceArray) == 0:
354                 makeprots = 0
355         
356         if minimumheight > maximumheight:
357                 a = maximumheight
358                 maximimheight = minimumheight
359                 minimumheight = a
360         elif minimumtaperpercent > maximumtaperpercent:
361                 a = maximumtaperpercent
362                 maximimtaperpercent = minimumtaperpercent
363                 minimumtaperpercent = a
364
365 #Sets the global Doodad values
366 def setDoodadValues(d0,d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11,d12,d13,d14,d15,d16,d17):
367         
368         #Doodads
369         global makedoodads
370         global doodadfacepercent
371         global selectdoodad
372         global onlyonprotrusions
373         global doodad1
374         global doodad2
375         global doodad3
376         global doodad4
377         global doodad5
378         global doodad6
379         global doodadminperface
380         global doodadmaxperface
381         global doodadminsize
382         global doodadmaxsize
383         global doodadminheight
384         global doodadmaxheight
385         global doodadArray
386         global doodonselectedfaces
387         global selectdoodadtoponly
388         
389         #Doodads
390         makedoodads = d0
391         doodadfacepercent = d1
392         selectdoodad = d2
393         onlyonprotrusions = d3
394         doodad1 = d4
395         doodad2 = d5
396         doodad3 = d6
397         doodad4 = d7
398         doodad5 = d8
399         doodad6 = d9
400         doodadminperface = d10
401         doodadmaxperface = d11
402         doodadminsize = d12
403         doodadmaxsize = d13
404         doodadminheight = d14
405         doodadmaxheight = d15
406         doodonselectedfaces = d16
407         selectdoodadtoponly = d17
408         makeDoodadArray()
409         if len(doodadArray) == 0:
410                 makedoodads = 0
411         
412         elif doodadminperface > doodadmaxperface:
413                 a = doodadmaxperface
414                 doodadmaxperface = doodadminperface
415                 doodadminperface = a
416         elif doodadminsize > doodadmaxsize:
417                 a = doodadmaxsize
418                 doodadmaxsize = doodadminsize
419                 doodadminsize = a
420         elif doodadminheight > doodadmaxheight:
421                 a = doodadmaxheight
422                 doodadmaxheight = doodadminheight
423                 doodadminheight = a
424
425 #Sets other global values
426 def setOtherValues(g0,m0,m1,m2,m3,m4):
427         
428         #Global
429         global reassignMats
430         global makenewobj
431         global protSideMat
432         global protTopMat
433         global doodSideMat
434         global doodTopMat
435         
436         #Get Misc Variables
437         makenewobj = g0
438         reassignMats = m0
439         protSideMat = m1
440         protTopMat = m2
441         doodSideMat = m3
442         doodTopMat = m4
443
444 def discombobulate():
445         
446         #Global
447         global origmesh
448         global newmesh
449         global makenewobj
450         global origobj
451         global newobj
452         global messagetext
453         global errortext
454         global editmode
455         
456         #Protrusions
457         global makeprots
458         global minimumtaperpercent
459         global maximumtaperpercent
460         global faceschangedpercent
461         global minimumheight
462         global maximumheight
463         global subface1
464         global subface2
465         global subface3
466         global subface4
467         global useselectedfaces
468         global selectface1
469         global selectface2
470         global selectface3
471         global selectface4
472         global deselface
473         global subfaceArray
474         
475         #Doodads
476         global makedoodads
477         global doodadfacepercent
478         global selectdoodad
479         global onlyonprotrusions
480         global doodad1
481         global doodad2
482         global doodad3
483         global doodad4
484         global doodad5
485         global doodad6
486         global doodadminperface
487         global doodadmaxperface
488         global doodadminsize
489         global doodadmaxsize
490         global doodadminheight
491         global doodadmaxheight
492         global doodadArray
493         global doodonselectedfaces
494         global selectdoodadtoponly
495         
496         #Global
497         global materialArray
498         global reassignMats
499         global protSideMat
500         global protTopMat
501         global doodSideMat
502         global doodTopMat
503         global thereAreMats
504         global currmat
505         
506         origobj = Scene.GetCurrent().objects.active
507         if not origobj:
508                 glRasterPos2d(10,50)
509                 errortext = "YOU MUST SELECT AN OBJECT!"
510                 messagetext = ErrorText(errortext)
511                 Blender.Redraw()
512                 return
513
514         #Leave Editmode
515         editmode = Window.EditMode()
516         if editmode: Window.EditMode(0)
517
518         #Get Major Variables
519         
520         origmesh = origobj.getData()
521         
522         if origobj.type != 'Mesh':
523                 glRasterPos2d(10,50)
524                 errortext = "OBJECT MUST BE MESH!"
525                 messagetext = ErrorText(errortext)
526                 Blender.Redraw()
527                 return
528         
529         newmesh = NMesh.GetRaw()
530         materialArray = origmesh.getMaterials()
531         if len(materialArray) < 1:
532                 thereAreMats = 0
533         else:
534                 thereAreMats = 1
535         
536         #add material indices if necessary (only up to 4)
537         if thereAreMats == 1 and reassignMats == 1:
538                 if len(materialArray) < 4:
539                         if protSideMat > 4: protSideMat = 4
540                         if protTopMat > 4: protTopMat = 4
541                         if doodSideMat > 4: doodSideMat = 4
542                         if doodTopMat > 4: doodTopMat = 4
543                 else:
544                         if protSideMat > len(materialArray): protSideMat = len(materialArray)
545                         if protTopMat > len(materialArray): protTopMat = len(materialArray)
546                         if doodSideMat > len(materialArray): doodSideMat = len(materialArray)
547                         if doodTopMat > len(materialArray): doodTopMat = len(materialArray)
548                 
549                 #This only does something if there are less than 4 verts
550                 for matind in [protSideMat,protTopMat,doodSideMat,doodTopMat]:
551                         if matind > len(materialArray) and matind <= 4:
552                                 for i in xrange(len(materialArray),matind+1):
553                                         materialArray.append(Material.New("AddedMat " + str(i)))
554                                         
555         #Sets the materials
556         newmesh.setMaterials(materialArray)
557         
558         #Set the doodad settings
559         defaultdoodads.settings(selectdoodadtoponly,materialArray,reassignMats,thereAreMats,doodSideMat,doodTopMat)
560         #defaultdoodads.settings(selectdoodadtoponly,materialArray,reassignMats,thereAreMats,currmat)
561         
562         newmesh.verts.extend(origmesh.verts)
563         
564         #Start modifying faces
565         for currface in origmesh.faces:
566                 
567                 currmat = currface.materialIndex
568                 defaultdoodads.setCurrMat(currmat)
569                 
570                 #Check if it is a triangle
571                 if len(currface.v)<4:
572                         face = Face([newmesh.verts[currface.v[0].index],newmesh.verts[currface.v[1].index],newmesh.verts[currface.v[2].index]])
573                         if thereAreMats == 1:
574                                 face.materialIndex = currmat
575                         newmesh.faces.append(face)
576                         continue
577                 
578                 #Check whether or not to make protrusions
579                 if makeprots == 0:
580                         face = Face([newmesh.verts[currface.v[0].index],newmesh.verts[currface.v[1].index],newmesh.verts[currface.v[2].index],newmesh.verts[currface.v[3].index]])
581                         if thereAreMats == 1:
582                                 face.materialIndex = currmat
583                         newmesh.faces.append(face)
584                         if makedoodads == 1 and onlyonprotrusions == 0:
585                                 if doodonselectedfaces == 1:
586                                         if currface.sel:
587                                                 tempmesh = NMesh.GetRaw()
588                                                 tempmesh = defaultdoodads.createDoodad(doodadArray,face, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
589                                                 newmesh.verts.extend(tempmesh.verts)
590                                                 newmesh.faces.extend(tempmesh.faces)
591                                 else:
592                                         tempmesh = NMesh.GetRaw()
593                                         tempmesh = defaultdoodads.createDoodad(doodadArray,face, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
594                                         newmesh.verts.extend(tempmesh.verts)
595                                         newmesh.faces.extend(tempmesh.faces)
596                         continue
597                 
598                 #Check if only changing selected faces
599                 if useselectedfaces == 1:
600                         #check if currface is selected
601                         if currface.sel:
602                                 a = 1
603                         else:
604                                 face = Face([newmesh.verts[currface.v[0].index],newmesh.verts[currface.v[1].index],newmesh.verts[currface.v[2].index],newmesh.verts[currface.v[3].index]])
605                                 if thereAreMats == 1:
606                                         face.materialIndex = currmat
607                                 newmesh.faces.append(face)
608                                 if makedoodads == 1 and onlyonprotrusions == 0:
609                                         if doodonselectedfaces != 1:
610                                                 tempmesh = NMesh.GetRaw()
611                                                 tempmesh = defaultdoodads.createDoodad(doodadArray,face, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
612                                                 newmesh.verts.extend(tempmesh.verts)
613                                                 newmesh.faces.extend(tempmesh.faces)
614                                 continue
615                 #Check if face should be modified by random chance
616                 if randnum(0,1)>faceschangedpercent: 
617                         face = Face([newmesh.verts[currface.v[0].index],newmesh.verts[currface.v[1].index],newmesh.verts[currface.v[2].index],newmesh.verts[currface.v[3].index]])
618                         if thereAreMats == 1:
619                                 face.materialIndex = currmat
620                         newmesh.faces.append(face)
621                         if makedoodads == 1 and onlyonprotrusions == 0:
622                                 if doodonselectedfaces == 1:
623                                         if currface.sel:
624                                                 tempmesh = NMesh.GetRaw()
625                                                 tempmesh = defaultdoodads.createDoodad(doodadArray,face, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
626                                                 newmesh.verts.extend(tempmesh.verts)
627                                                 newmesh.faces.extend(tempmesh.faces)
628                                 else:
629                                         tempmesh = NMesh.GetRaw()
630                                         tempmesh = defaultdoodads.createDoodad(doodadArray,face, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
631                                         newmesh.verts.extend(tempmesh.verts)
632                                         newmesh.faces.extend(tempmesh.faces)
633                         continue
634                 
635                 center = Vector([0,0,0])
636                 for pt in currface.v:
637                         center = center + pt.co
638                 center = center / len(currface.v)
639                 
640                 #Determine amount of subfaces
641                 subfaces = round(randnum(1,len(subfaceArray)),0)
642                 subfaces = subfaceArray[(int(subfaces) - 1)]
643                 
644                 ######################## START DEALING WITH PROTRUSIONS #####################
645                 
646                 if subfaces == 1:
647                         prot = randnum(minimumheight,maximumheight)
648                         tempface = extrude(center,currface.no,prot,currface.v[0].index,currface.v[1].index,currface.v[2].index,currface.v[3].index,selectface1)
649                         if makedoodads == 1:
650                                 if doodonselectedfaces == 1:
651                                         if currface.sel:
652                                                 tempmesh = NMesh.GetRaw()
653                                                 tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
654                                                 newmesh.verts.extend(tempmesh.verts)
655                                                 newmesh.faces.extend(tempmesh.faces)
656                                 else:
657                                         tempmesh = NMesh.GetRaw()
658                                         tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
659                                         newmesh.verts.extend(tempmesh.verts)
660                                         newmesh.faces.extend(tempmesh.faces)
661                 
662                 elif subfaces == 2:
663                         orientation = int(round(randnum(0,1)))
664                         p1 = currface.v[orientation]
665                         p2 = currface.v[orientation + 1]
666                         p3 = ((p2.co - p1.co)/2) + p1.co
667                         ve1 = Vert(p3[0],p3[1],p3[2])
668                         ve1.sel = 0
669                         p1 = currface.v[2 + orientation]
670                         if orientation < 0.5:
671                                 p2 = currface.v[3]
672                         else:
673                                 p2 = currface.v[0]
674                         p3 = ((p2.co - p1.co)/2) + p1.co
675                         ve2 = Vert(p3[0],p3[1],p3[2])
676                         ve2.sel = 0
677                         if orientation < 0.5:
678                                 verti = currface.v[3]
679                                 p3 = verti.index
680                                 v1 = p3
681                                 verti = currface.v[0]
682                                 p0 = verti.index
683                                 v2 = p0
684                         else:
685                                 verti = currface.v[0]
686                                 p0 = verti.index
687                                 v1 = p0
688                                 verti = currface.v[1]
689                                 p1 = verti.index
690                                 v2 = p1
691                         newmesh.verts.append(ve1)
692                         newmesh.verts.append(ve2)
693                         index = len(newmesh.verts) - 2
694                         v4 = index + 1
695                         v3 = index
696                         center = Vector([0, 0, 0])
697                         for pt in [newmesh.verts[v1],newmesh.verts[v2],newmesh.verts[v3],newmesh.verts[v4]]:
698                                 center += pt.co
699                         center = center/4
700                         prot = randnum(minimumheight,maximumheight)
701                         tempface = extrude(center,currface.no,prot,v1,v2,v3,v4,selectface2)
702                         if makedoodads == 1:
703                                 if doodonselectedfaces == 1:
704                                         if currface.sel:
705                                                 tempmesh = NMesh.GetRaw()
706                                                 tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
707                                                 newmesh.verts.extend(tempmesh.verts)
708                                                 newmesh.faces.extend(tempmesh.faces)
709                                 else:
710                                         tempmesh = NMesh.GetRaw()
711                                         tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
712                                         newmesh.verts.extend(tempmesh.verts)
713                                         newmesh.faces.extend(tempmesh.faces)
714                         if orientation < 0.5:
715                                 verti = currface.v[1]
716                                 p1 = verti.index
717                                 v1 = p1
718                                 verti = currface.v[2]
719                                 p2 = verti.index
720                                 v2 = p2
721                         else:
722                                 verti = currface.v[2]
723                                 p2 = verti.index
724                                 v1 = p2
725                                 verti = currface.v[3]
726                                 p3 = verti.index
727                                 v2 = p3
728                         center = Vector([0]*3)
729                         for pt in [newmesh.verts[v1],newmesh.verts[v2],newmesh.verts[v3],newmesh.verts[v4]]:
730                                 center += pt.co
731                         center = center/4
732                         prot = randnum(minimumheight,maximumheight)
733                         tempface = extrude(center,currface.no,prot,v1,v2,v4,v3,selectface2)
734                         if makedoodads == 1:
735                                 if doodonselectedfaces == 1:
736                                         if currface.sel:
737                                                 tempmesh = NMesh.GetRaw()
738                                                 tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
739                                                 newmesh.verts.extend(tempmesh.verts)
740                                                 newmesh.faces.extend(tempmesh.faces)
741                                 else:
742                                         tempmesh = NMesh.GetRaw()
743                                         tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
744                                         newmesh.verts.extend(tempmesh.verts)
745                                         newmesh.faces.extend(tempmesh.faces)
746                         if orientation < 0.5:
747                                 face = Face([newmesh.verts[p0],newmesh.verts[p1],newmesh.verts[v3]])
748                                 if thereAreMats == 1:
749                                         if reassignMats == 0 or protSideMat == 0:
750                                                 face.materialIndex = currmat
751                                         else:
752                                                 face.materialIndex = protSideMat-1
753                                 newmesh.faces.append(face)
754                                 face = Face([newmesh.verts[p2],newmesh.verts[p3],newmesh.verts[v4]])
755                                 if thereAreMats == 1:
756                                         if reassignMats == 0 or protSideMat == 0:
757                                                 face.materialIndex = currmat
758                                         else:
759                                                 face.materialIndex = protSideMat-1
760                                 newmesh.faces.append(face)
761                         else:
762                                 face = Face([newmesh.verts[p1],newmesh.verts[p2],newmesh.verts[v3]])
763                                 if thereAreMats == 1:
764                                         if reassignMats == 0 or protSideMat == 0:
765                                                 face.materialIndex = currmat
766                                         else:
767                                                 face.materialIndex = protSideMat-1
768                                 newmesh.faces.append(face)
769                                 face = Face([newmesh.verts[p3],newmesh.verts[p0],newmesh.verts[v4]])
770                                 if thereAreMats == 1:
771                                         if reassignMats == 0 or protSideMat == 0:
772                                                 face.materialIndex = currmat
773                                         else:
774                                                 face.materialIndex = protSideMat-1
775                                 newmesh.faces.append(face)
776                         
777                 elif subfaces == 3:
778                         layer2inds = []
779                         layer2verts = []
780                         orientation = int(round(randnum(0,1)))
781                         rotation = int(round(randnum(0,1)))
782                         p1 = currface.v[orientation]
783                         p2 = currface.v[orientation + 1]
784                         p3 = ((p2.co - p1.co)/2) + p1.co
785                         ve1 = Vert(p3[0],p3[1],p3[2])
786                         ve1.sel = 0
787                         p1 = currface.v[2 + orientation]
788                         if orientation < 0.5:
789                                 p2 = currface.v[3]
790                         else:
791                                 p2 = currface.v[0]
792                         p3 = ((p2.co - p1.co)/2) + p1.co
793                         ve2 = Vert(p3[0],p3[1],p3[2])
794                         ve2.sel = 0
795                         fp = []
796         
797                         #make first protrusion
798                         if rotation < 0.5:
799                                 if orientation < 0.5:
800                                         verti = currface.v[3]
801                                         fp.append(verti.index)
802                                         v1 = verti.index
803                                         verti = currface.v[0]
804                                         fp.append(verti.index)
805                                         v2 = verti.index
806                                         layer2verts.extend([newmesh.verts[currface.v[1].index],newmesh.verts[currface.v[2].index]])
807                                 else:
808                                         verti = currface.v[0]
809                                         fp.append(verti.index)
810                                         v1 = verti.index
811                                         verti = currface.v[1]
812                                         fp.append(verti.index)
813                                         v2 = verti.index
814                                         layer2verts.extend([newmesh.verts[currface.v[2].index],newmesh.verts[currface.v[3].index]])
815                                 newmesh.verts.append(ve1)
816                                 newmesh.verts.append(ve2)
817                                 index = len(newmesh.verts) - 2
818                                 v4 = index + 1
819                                 v3 = index
820                                 center = Vector([0]*3)
821                                 for pt in [newmesh.verts[v1],newmesh.verts[v2],newmesh.verts[v3],newmesh.verts[v4]]:
822                                         center += pt.co
823                                 center = center/4
824                                 prot = randnum(minimumheight,maximumheight)
825                                 layer2inds.extend([v3,v4])
826                                 tempface = extrude(center,currface.no,prot,v1,v2,v3,v4,selectface3)
827                                 if makedoodads == 1:
828                                         if doodonselectedfaces == 1:
829                                                 if currface.sel:
830                                                         tempmesh = NMesh.GetRaw()
831                                                         tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
832                                                         newmesh.verts.extend(tempmesh.verts)
833                                                         newmesh.faces.extend(tempmesh.faces)
834                                         else:
835                                                 tempmesh = NMesh.GetRaw()
836                                                 tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
837                                                 newmesh.verts.extend(tempmesh.verts)
838                                                 newmesh.faces.extend(tempmesh.faces)
839                         #Still first protrusion
840                         else:
841                                 if orientation < 0.5:
842                                         verti = currface.v[1]
843                                         fp.append(verti.index)
844                                         v1 = verti.index
845                                         verti = currface.v[2]
846                                         fp.append(verti.index)
847                                         v2 = verti.index
848                                         layer2verts.extend([newmesh.verts[currface.v[0].index],newmesh.verts[currface.v[3].index]])
849                                 else:
850                                         verti = currface.v[2]
851                                         fp.append(verti.index)
852                                         v1 = verti.index
853                                         verti = currface.v[3]
854                                         fp.append(verti.index)
855                                         v2 = verti.index
856                                         layer2verts.extend([newmesh.verts[currface.v[1].index],newmesh.verts[currface.v[0].index]])
857                                 newmesh.verts.append(ve2)
858                                 newmesh.verts.append(ve1)
859                                 index = len(newmesh.verts) - 2
860                                 v4 = index
861                                 v3 = index + 1
862                                 center = Vector([0]*3)
863                                 for pt in [newmesh.verts[v1],newmesh.verts[v2],newmesh.verts[v3],newmesh.verts[v4]]:
864                                         center += pt.co
865                                 center = center/4
866                                 prot = randnum(minimumheight,maximumheight)
867                                 layer2inds.extend([index, index +1])
868                                 tempface = extrude(center,currface.no,prot,v1,v2,v4,v3,selectface3)
869                                 if makedoodads == 1:
870                                         if doodonselectedfaces == 1:
871                                                 if currface.sel:
872                                                         tempmesh = NMesh.GetRaw()
873                                                         tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
874                                                         newmesh.verts.extend(tempmesh.verts)
875                                                         newmesh.faces.extend(tempmesh.faces)
876                                         else:
877                                                 tempmesh = NMesh.GetRaw()
878                                                 tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
879                                                 newmesh.verts.extend(tempmesh.verts)
880                                                 newmesh.faces.extend(tempmesh.faces)
881                         
882                         #split next rect(pre-arranged, no orientation crud)--make flag in extruder for only one existing vert in mesh
883                         p1 = newmesh.verts[layer2inds[0]]
884                         p2 = newmesh.verts[layer2inds[1]]
885                         p3 = ((p2.co - p1.co)/2) + p1.co
886                         ve3 = Vert(p3[0],p3[1],p3[2])
887                         ve3.sel = 0
888                         p1 = layer2verts[0]
889                         p2 = layer2verts[1]
890                         p3 = ((p2.co - p1.co)/2) + p1.co
891                         ve4 = Vert(p3[0],p3[1],p3[2])
892                         ve4.sel = 0
893                         newmesh.verts.append(ve3)
894                         newmesh.verts.append(ve4)
895                         tempindex = len(newmesh.verts) - 2
896                         v5 = tempindex
897                         v6 = tempindex + 1
898                         verti = layer2verts[0]
899                         t0 = verti.index
900                         center = Vector([0]*3)
901                         for pt in [newmesh.verts[v5],newmesh.verts[v6],newmesh.verts[t0],newmesh.verts[v3]]:
902                                 center += pt.co
903                         center = center/4
904                         prot = randnum(minimumheight,maximumheight)
905                         if rotation < 0.5: flino = 1
906                         else: flino = 0
907                         tempface = extrude(center,currface.no,prot,v3,v5,v6,t0,selectface3,flino)
908                         if makedoodads == 1:
909                                 if doodonselectedfaces == 1:
910                                         if currface.sel:
911                                                 tempmesh = NMesh.GetRaw()
912                                                 tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
913                                                 newmesh.verts.extend(tempmesh.verts)
914                                                 newmesh.faces.extend(tempmesh.faces)
915                                         tempmesh = NMesh.GetRaw()
916                                         tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
917                                         newmesh.verts.extend(tempmesh.verts)
918                                         newmesh.faces.extend(tempmesh.faces)
919                         if rotation < 0.5:
920                                 fpt = t0
921                                 face = Face([newmesh.verts[fp[1]],newmesh.verts[fpt],newmesh.verts[v3]])
922                                 if thereAreMats == 1:
923                                         if reassignMats == 0 or protSideMat == 0:
924                                                 face.materialIndex = currmat
925                                         else:
926                                                 face.materialIndex = protSideMat-1
927                                 newmesh.faces.append(face)
928                         else:
929                                 fpt = t0
930                                 face = Face([newmesh.verts[fp[0]],newmesh.verts[v3],newmesh.verts[fpt]])
931                                 if thereAreMats == 1:
932                                         if reassignMats == 0 or protSideMat == 0:
933                                                 face.materialIndex = currmat
934                                         else:
935                                                 face.materialIndex = protSideMat-1
936                                 newmesh.faces.append(face)
937                         verti = layer2verts[1]
938                         tempindex = verti.index
939                         center = Vector([0]*3)
940                         for pt in [newmesh.verts[v5],newmesh.verts[v6],newmesh.verts[tempindex],newmesh.verts[v4]]:
941                                 center += pt.co
942                         center = center/4
943                         prot = randnum(minimumheight,maximumheight)
944                         tempface = extrude(center,currface.no,prot,v6,v5,v4,tempindex,selectface3,flino)
945                         if makedoodads == 1:
946                                 if doodonselectedfaces == 1:
947                                         if currface.sel:
948                                                 tempmesh = NMesh.GetRaw()
949                                                 tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
950                                                 newmesh.verts.extend(tempmesh.verts)
951                                                 newmesh.faces.extend(tempmesh.faces)
952                                 else:
953                                         tempmesh = NMesh.GetRaw()
954                                         tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
955                                         newmesh.verts.extend(tempmesh.verts)
956                                         newmesh.faces.extend(tempmesh.faces)
957                         if rotation < 0.5:
958                                 face = Face([newmesh.verts[tempindex],newmesh.verts[fp[0]],newmesh.verts[v4]])
959                                 if thereAreMats == 1:
960                                         if reassignMats == 0 or protSideMat == 0:
961                                                 face.materialIndex = currmat
962                                         else:
963                                                 face.materialIndex = protSideMat-1
964                                 newmesh.faces.append(face)
965                                 face = Face([newmesh.verts[fpt],newmesh.verts[tempindex],newmesh.verts[v6]])
966                                 if thereAreMats == 1:
967                                         if reassignMats == 0 or protSideMat == 0:
968                                                 face.materialIndex = currmat
969                                         else:
970                                                 face.materialIndex = protSideMat-1
971                                 newmesh.faces.append(face)
972                         else:
973                                 face = Face([newmesh.verts[tempindex],newmesh.verts[v4],newmesh.verts[fp[1]]])
974                                 if thereAreMats == 1:
975                                         if reassignMats == 0 or protSideMat == 0:
976                                                 face.materialIndex = currmat
977                                         else:
978                                                 face.materialIndex = protSideMat-1
979                                 newmesh.faces.append(face)
980                                 face = Face([newmesh.verts[tempindex],newmesh.verts[fpt],newmesh.verts[v6]])
981                                 if thereAreMats == 1:
982                                         if reassignMats == 0 or protSideMat == 0:
983                                                 face.materialIndex = currmat
984                                         else:
985                                                 face.materialIndex = protSideMat-1
986                                 newmesh.faces.append(face)
987                         
988                 else:
989                         #get all points
990                         verti = currface.v[0]
991                         p0 = verti.index
992                         
993                         verti = currface.v[1]
994                         p1 = verti.index
995                 
996                         pt = ((newmesh.verts[p1].co - newmesh.verts[p0].co)/2) + newmesh.verts[p0].co
997                         v1 = Vert(pt[0],pt[1],pt[2])
998                         v1.sel = 0
999         
1000                         verti = currface.v[2]
1001                         p2 = verti.index
1002
1003                         pt =  ((newmesh.verts[p2].co - newmesh.verts[p1].co)/2) + newmesh.verts[p1].co
1004                         v2 = Vert(pt[0],pt[1],pt[2])
1005                         v2.sel = 0
1006
1007                         verti = currface.v[3]
1008                         p3 = verti.index
1009
1010                         pt =  ((newmesh.verts[p3].co - newmesh.verts[p2].co)/2) + newmesh.verts[p2].co
1011                         v3 = Vert(pt[0],pt[1],pt[2])
1012                         v3.sel = 0
1013
1014                         pt =  ((newmesh.verts[p0].co - newmesh.verts[p3].co)/2) + newmesh.verts[p3].co
1015                         v4 = Vert(pt[0],pt[1],pt[2])
1016                         v4.sel = 0
1017
1018                         pt =  ((v3.co - v1.co)/2) + v1.co
1019                         m = Vert(pt[0],pt[1],pt[2])
1020                         m.sel = 0
1021                         
1022                         #extrusion 1
1023                         newmesh.verts.extend([v1,m,v4])
1024                         index = len(newmesh.verts) - 3
1025                         v1 = index
1026                         m = index + 1
1027                         v4 = index + 2
1028                         center = Vector([0]*3)
1029                         for pt in [newmesh.verts[p0],newmesh.verts[v1],newmesh.verts[m],newmesh.verts[v4]]:
1030                                 center += pt.co
1031                         center = center/4
1032                         prot = randnum(minimumheight,maximumheight)
1033                         tempface = extrude(center,currface.no,prot,p0,v1,m,v4,selectface4)
1034                         if makedoodads == 1:
1035                                 if doodonselectedfaces == 1:
1036                                         if currface.sel:
1037                                                 tempmesh = NMesh.GetRaw()
1038                                                 tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
1039                                                 newmesh.verts.extend(tempmesh.verts)
1040                                                 newmesh.faces.extend(tempmesh.faces)
1041                                 else:
1042                                         tempmesh = NMesh.GetRaw()
1043                                         tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
1044                                         newmesh.verts.extend(tempmesh.verts)
1045                                         newmesh.faces.extend(tempmesh.faces)
1046                         
1047                         #extrusion 2
1048                         newmesh.verts.extend([v2])
1049                         index = len(newmesh.verts) - 1
1050                         v2 = index
1051                         center = Vector([0]*3)
1052                         for pt in [newmesh.verts[m],newmesh.verts[v1],newmesh.verts[p1],newmesh.verts[v2]]:
1053                                 center += pt.co
1054                         center = center/4
1055                         prot = randnum(minimumheight,maximumheight)
1056                         tempface = extrude(center,currface.no,prot,m,v1,p1,v2,selectface4)
1057                         if makedoodads == 1:
1058                                 if doodonselectedfaces == 1:
1059                                         if currface.sel:
1060                                                 tempmesh = NMesh.GetRaw()
1061                                                 tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
1062                                                 newmesh.verts.extend(tempmesh.verts)
1063                                                 newmesh.faces.extend(tempmesh.faces)
1064                                 else:
1065                                         tempmesh = NMesh.GetRaw()
1066                                         tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
1067                                         newmesh.verts.extend(tempmesh.verts)
1068                                         newmesh.faces.extend(tempmesh.faces)
1069                         
1070                         #extrusion 3
1071                         newmesh.verts.extend([v3])
1072                         index = len(newmesh.verts) - 1
1073                         v3 = index
1074                         center = Vector([0]*3)
1075                         for pt in [newmesh.verts[m],newmesh.verts[v2],newmesh.verts[p2],newmesh.verts[v3]]:
1076                                 center += pt.co
1077                         center = center/4
1078                         prot = randnum(minimumheight,maximumheight)
1079                         tempface = extrude(center,currface.no,prot,m,v2,p2,v3,selectface4)
1080                         if makedoodads == 1:
1081                                 if doodonselectedfaces == 1:
1082                                         if currface.sel:
1083                                                 tempmesh = NMesh.GetRaw()
1084                                                 tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
1085                                                 newmesh.verts.extend(tempmesh.verts)
1086                                                 newmesh.faces.extend(tempmesh.faces)
1087                                 else:
1088                                         tempmesh = NMesh.GetRaw()
1089                                         tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
1090                                         newmesh.verts.extend(tempmesh.verts)
1091                                         newmesh.faces.extend(tempmesh.faces)
1092                         
1093                         #extrusion 4
1094                         center = Vector([0]*3)
1095                         for pt in [newmesh.verts[m],newmesh.verts[v3],newmesh.verts[p3],newmesh.verts[v4]]:
1096                                 center += pt.co
1097                         center = center/4
1098                         prot = randnum(minimumheight,maximumheight)
1099                         tempface = extrude(center,currface.no,prot,v4,m,v3,p3,selectface4)
1100                         if makedoodads == 1:
1101                                 if doodonselectedfaces == 1:
1102                                         if currface.sel:
1103                                                 tempmesh = NMesh.GetRaw()
1104                                                 tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
1105                                                 newmesh.verts.extend(tempmesh.verts)
1106                                                 newmesh.faces.extend(tempmesh.faces)
1107                                 else:
1108                                         tempmesh = NMesh.GetRaw()
1109                                         tempmesh = defaultdoodads.createDoodad(doodadArray, tempface, doodadminsize, doodadmaxsize, doodadminheight,doodadmaxheight, selectdoodad, doodadminperface, doodadmaxperface, doodadfacepercent)
1110                                         newmesh.verts.extend(tempmesh.verts)
1111                                         newmesh.faces.extend(tempmesh.faces)
1112                         
1113                         face = Face([newmesh.verts[p0],newmesh.verts[p1],newmesh.verts[v1]])
1114                         if thereAreMats == 1:
1115                                 if reassignMats == 0 or protSideMat == 0:
1116                                         face.materialIndex = currmat
1117                                 else:
1118                                         face.materialIndex = protSideMat-1
1119                         newmesh.faces.append(face)
1120                         face = Face([newmesh.verts[p1],newmesh.verts[p2],newmesh.verts[v2]])
1121                         if thereAreMats == 1:
1122                                 if reassignMats == 0 or protSideMat == 0:
1123                                         face.materialIndex = currmat
1124                                 else:
1125                                         face.materialIndex = protSideMat-1
1126                         newmesh.faces.append(face)
1127                         face = Face([newmesh.verts[p2],newmesh.verts[p3],newmesh.verts[v3]])
1128                         if thereAreMats == 1:
1129                                 if reassignMats == 0 or protSideMat == 0:
1130                                         face.materialIndex = currmat
1131                                 else:
1132                                         face.materialIndex = protSideMat-1
1133                         newmesh.faces.append(face)
1134                         face = Face([newmesh.verts[p3],newmesh.verts[p0],newmesh.verts[v4]])
1135                         if thereAreMats == 1:
1136                                 if reassignMats == 0 or protSideMat == 0:
1137                                         face.materialIndex = currmat
1138                                 else:
1139                                         face.materialIndex = protSideMat-1
1140                         newmesh.faces.append(face)
1141                         
1142         #NMesh.PutRaw(newmesh)
1143         if deselface == 1:
1144                 for unvert in origmesh.verts:
1145                         newmesh.verts[unvert.index].sel = 0
1146         if makenewobj == 1:
1147                 newobj = origobj.__copy__()
1148                 newobj.link(newmesh)
1149                 scene = Blender.Scene.GetCurrent()
1150                 scene.objects.link(newobj)
1151                 origobj.sel = 0
1152         else:
1153                 origobj.link(newmesh)
1154         
1155         #Return to Editmode if previously in it
1156         if editmode: Window.EditMode(1)
1157
1158 ####################### gui ######################
1159 from Blender.BGL import *
1160 from Blender.Draw import *
1161
1162 def ErrorText(errortext):
1163         Window.WaitCursor(0)
1164         Text(errortext)
1165         PupMenu("ERROR: %s" % errortext.lower())
1166
1167 #Global Buttons
1168 makenewobject = Create(makenewobj)
1169 messagetext = Create(errortext)
1170
1171 #Protrusion Buttons
1172 doprots = Create(makeprots)
1173 facechange = Create(faceschangedpercent*100)
1174 minheight = Create(minimumheight)
1175 maxheight = Create(maximumheight)
1176 sub1 = Create(subface1)
1177 sub2 = Create(subface2)
1178 sub3 = Create(subface3)
1179 sub4 = Create(subface4)
1180 mintaper = Create(minimumtaperpercent*100)
1181 maxtaper = Create(maximumtaperpercent*100)
1182 useselected = Create(useselectedfaces)
1183 selface1 = Create(selectface1)
1184 selface2 = Create(selectface2)
1185 selface3 = Create(selectface3)
1186 selface4 = Create(selectface4)
1187 deselectvertices = Create(deselface)
1188 #selectbyverts = Create(vertselected)
1189
1190 #Doodad Buttons
1191 dodoodads = Create(makedoodads)
1192 doodadfacechange = Create(doodadfacepercent*100)
1193 seldoodad = Create(selectdoodad)
1194 onprot = Create(onlyonprotrusions)
1195 dood1 = Create(doodad1)
1196 dood2 = Create(doodad2)
1197 dood3 = Create(doodad3)
1198 dood4 = Create(doodad4)
1199 dood5 = Create(doodad5)
1200 dood6 = Create(doodad6)
1201 doodadminamount = Create(doodadminperface)
1202 doodadmaxamount = Create(doodadmaxperface)
1203 doodsizemin = Create(doodadminsize*100)
1204 doodsizemax = Create(doodadmaxsize*100)
1205 doodheightmin = Create(doodadminheight)
1206 doodheightmax = Create(doodadmaxheight)
1207 doodonselface = Create(doodonselectedfaces)
1208 seldoodtop = Create(selectdoodadtoponly)
1209
1210 #Material Buttons
1211 assignNewMats = Create(reassignMats)
1212 replProtSideIndex = Create(protSideMat)
1213 replProtTopIndex = Create(protTopMat)
1214 replDoodSideIndex = Create(doodSideMat)
1215 replDoodTopIndex = Create(doodTopMat)
1216
1217 # Events
1218 EVENT_NONE = 1
1219 EVENT_DISCOMBOBULATE = 2
1220 EVENT_EXIT = 3
1221
1222 # Additions for moving gui
1223 hadd = 0
1224 wadd = 0
1225 thadd = 410
1226 phadd = 245
1227 pwadd = 0
1228 dhadd = 55
1229 dwadd = 0
1230 ghadd = 10
1231 gwadd = 0
1232 mhadd = 55
1233 mwadd = 312
1234
1235 def colorbox(x,y,xright,bottom):
1236    glColor3f(0.75, 0.75, 0.75)
1237    glRecti(x + 1, y + 1, xright - 1, bottom - 1)
1238
1239 firstDraw = 1
1240
1241 def draw():
1242         
1243         #Protrusions
1244         global doprots
1245         global facechange
1246         global minheight
1247         global maxheight
1248         global sub1
1249         global sub2
1250         global sub3
1251         global sub4
1252         global mintaper
1253         global maxtaper
1254         global useselected
1255         global selface1
1256         global selface2
1257         global selface3
1258         global selface4
1259         global deselectvertices
1260         #global selectbyverts
1261         
1262         #Doodads
1263         global dodoodads
1264         global doodadfacechange
1265         global seldoodad
1266         global onprot
1267         global dood1
1268         global dood2
1269         global dood3
1270         global dood4
1271         global dood5
1272         global dood6
1273         global doodadminamount
1274         global doodadmaxamount
1275         global doodsizemin
1276         global doodsizemax
1277         global doodheightmin
1278         global doodheightmax
1279         global doodonselface
1280         global seldoodtop
1281         
1282         #Materials
1283         global assignNewMats
1284         global replProtSideIndex
1285         global replProtTopIndex
1286         global replDoodSideIndex
1287         global replDoodTopIndex
1288         
1289         #Global Settings
1290         global makenewobject
1291         global messagetext
1292         global errortext
1293         global EVENT_NONE,EVENT_DRAW,EVENT_EXIT,EVENT_UP,EVENT_DOWN,EVENT_LEFT,EVENT_RIGHT
1294         
1295         # Additions for moving gui
1296         global hadd
1297         global wadd
1298         global thadd
1299         global phadd
1300         global pwadd
1301         global dhadd
1302         global dwadd
1303         global ghadd
1304         global gwadd
1305         global mhadd
1306         global mwadd
1307         
1308         #This is for creating the initial layout
1309         global firstDraw
1310         if(firstDraw == 1):
1311                 if(((Window.GetAreaSize()[1])*1.7) < Window.GetAreaSize()[0]):
1312                         thadd = 180
1313                         phadd = 10
1314                         dhadd = 10
1315                         mhadd = 55
1316                         ghadd = 10
1317                         pwadd = 0
1318                         dwadd = 305
1319                         mwadd = 610
1320                         gwadd = 610
1321                 else:
1322                         thadd = 505
1323                         phadd = 346
1324                         dhadd = 160
1325                         mhadd = 56
1326                         ghadd = 10
1327                         pwadd = 0
1328                         dwadd = 0
1329                         mwadd = 0
1330                         gwadd = 0
1331                 firstDraw = 0
1332         
1333         
1334         #Title :420high
1335         glClearColor(0.6, 0.6, 0.6, 1.0)
1336         glClear(GL_COLOR_BUFFER_BIT)
1337         glColor3f(0.0,0.0,0.0)
1338         glRasterPos2d(8+wadd, thadd+hadd)
1339         Text("Discombobulator v2.1b")
1340         
1341         #Protrusion
1342         colorbox(8+pwadd+wadd,150+phadd+hadd,312+pwadd+wadd,phadd-5+hadd)
1343         glColor3f(0.0,0.0,0.0)
1344         glRasterPos2d(12+pwadd+wadd, 140+phadd+hadd)
1345         Text("Protrusions:")
1346         doprots = Toggle("Make Protrusions",EVENT_NONE,12+pwadd+wadd,117+phadd+hadd,145,18,doprots.val,"Make Protrusions?")
1347         facechange = Number("Face %: ",EVENT_NONE,162+pwadd+wadd,117+phadd+hadd,145,18,facechange.val,0,100,"Percentage of faces that will grow protrusions")
1348         useselected = Toggle("Only selected faces",EVENT_NONE,12+pwadd+wadd,97+phadd+hadd,145,18,useselected.val,"If on, only selected faces will be modified")
1349         deselectvertices = Toggle("Deselect Selected",EVENT_NONE,162+pwadd+wadd,97+phadd+hadd,145,18,deselectvertices.val,"Deselects any selected vertex except for ones selected by \"Select Tops\"")
1350         
1351         #Protrusion properties
1352         glColor3f(0.0,0.0,0.0)
1353         glRasterPos2d(12+pwadd+wadd, 80+phadd+hadd)
1354         Text("Protrusion Properties:")
1355         BeginAlign()
1356         minheight = Number("Min Height: ",EVENT_NONE,12+pwadd+wadd,57+phadd+hadd,145,18,minheight.val,-100.0,100.0,"Minimum height of any protrusion")
1357         maxheight = Number("Max Height: ",EVENT_NONE,162+pwadd+wadd,57+phadd+hadd,145,18,maxheight.val,-100.0,100.0,"Maximum height of any protrusion")
1358         EndAlign()
1359         BeginAlign()
1360         mintaper = Number("Min Taper %: ",EVENT_NONE,12+pwadd+wadd,37+phadd+hadd,145,18,mintaper.val,0,100,"Minimum taper percentage of protrusion")
1361         maxtaper = Number("Max Taper %: ",EVENT_NONE,162+pwadd+wadd,37+phadd+hadd,145,18,maxtaper.val,0,100,"Maximum taper percentage of protrusion")
1362         EndAlign()
1363         glRasterPos2d(19+pwadd+wadd, 22+phadd+hadd)
1364         Text("Number of protrusions:")
1365         BeginAlign()
1366         sub1 = Toggle("1",EVENT_NONE,12+pwadd+wadd,phadd+hadd,34,18,sub1.val,"One Protrusion")
1367         sub2 = Toggle("2",EVENT_NONE,48+pwadd+wadd,phadd+hadd,34,18,sub2.val,"Two Protrusions")
1368         sub3 = Toggle("3",EVENT_NONE,84+pwadd+wadd,phadd+hadd,34,18,sub3.val,"Three Protrusions")
1369         sub4 = Toggle("4",EVENT_NONE,120+pwadd+wadd,phadd+hadd,34,18,sub4.val,"Four Protrusions")
1370         EndAlign()
1371         glRasterPos2d(195+pwadd+wadd, 22+phadd+hadd)
1372         Text("Select tops of:")
1373         BeginAlign()
1374         selface1 = Toggle("1",EVENT_NONE,165+pwadd+wadd,phadd+hadd,34,18,selface1.val,"Select the tip of the protrusion when it is created")
1375         selface2 = Toggle("2",EVENT_NONE,201+pwadd+wadd,phadd+hadd,34,18,selface2.val,"Select the tips of each protrusion when they are created")
1376         selface3 = Toggle("3",EVENT_NONE,237+pwadd+wadd,phadd+hadd,34,18,selface3.val,"Select the tips of each protrusion when they are created")
1377         selface4 = Toggle("4",EVENT_NONE,273+pwadd+wadd,phadd+hadd,34,18,selface4.val,"Select the tips of each protrusion when they are created")
1378         EndAlign()
1379         #Doodads
1380         colorbox(8+dwadd+wadd,175+dhadd+hadd,312+dwadd+wadd,dhadd-5+hadd)
1381         glColor3f(0.0,0.0,0.0)
1382         glRasterPos2d(12+dwadd+wadd, 165+dhadd+hadd)
1383         Text("Doodads:")
1384         BeginAlign()
1385         dood1 = Toggle("1 Box",EVENT_NONE,12+dwadd+wadd,142+dhadd+hadd,45,18,dood1.val,"Creates a rectangular box")
1386         dood2 = Toggle("2 Box",EVENT_NONE,61+dwadd+wadd,142+dhadd+hadd,45,18,dood2.val,"Creates 2 side-by-side rectangular boxes")
1387         dood3 = Toggle("3 Box",EVENT_NONE,110+dwadd+wadd,142+dhadd+hadd,45,18,dood3.val,"Creates 3 side-by-side rectangular boxes")
1388         EndAlign()
1389         BeginAlign()
1390         dood4 = Toggle("\"L\"",EVENT_NONE,164+dwadd+wadd,142+dhadd+hadd,45,18,dood4.val,"Creates a Tetris-style \"L\" shape")
1391         dood5 = Toggle("\"T\"",EVENT_NONE,213+dwadd+wadd,142+dhadd+hadd,45,18,dood5.val,"Creates a Tetris-style \"T\" shape")
1392         dood6 = Toggle("\"S\"",EVENT_NONE,262+dwadd+wadd,142+dhadd+hadd,45,18,dood6.val,"Creates a sort-of \"S\" or \"Z\" shape")
1393         EndAlign()
1394         dodoodads = Toggle("Make Doodads",EVENT_NONE,12+dwadd+wadd,120+dhadd+hadd,145,18,dodoodads.val,"Make Doodads?")
1395         doodadfacechange = Number("Face %: ",EVENT_NONE,162+dwadd+wadd,120+dhadd+hadd,145,18,doodadfacechange.val,0,100,"Percentage of faces that will gain doodads")
1396         seldoodad = Toggle("Select Doodads",EVENT_NONE,12+dwadd+wadd,100+dhadd+hadd,145,18,seldoodad.val,"Selects doodads when they are created")
1397         seldoodtop = Toggle("Only Select Tops",EVENT_NONE,162+dwadd+wadd,100+dhadd+hadd,145,18,seldoodtop.val,"Only Selects tops of doodads when\"Select Doodads\" is on")
1398         doodonselface = Toggle("Only selected faces",EVENT_NONE,12+dwadd+wadd,80+dhadd+hadd,145,18,doodonselface.val,"Only create doodads on selected faces")
1399         onprot = Toggle("Only on Protrusions",EVENT_NONE,162+dwadd+wadd,80+dhadd+hadd,145,18,onprot.val,"Only place doodads on protrusions")
1400         
1401         #Doodad Properties
1402         glColor3f(0.0,0.0,0.0)
1403         glRasterPos2d(12+dwadd+wadd, 63+dhadd+hadd)
1404         Text("Doodad Properties:")
1405         BeginAlign()
1406         doodadminamount = Number("Min Amount: ",EVENT_NONE,12+dwadd+wadd,40+dhadd+hadd,145,18,doodadminamount.val,0,100,"Minimum number of doodads per face")
1407         doodadmaxamount = Number("Max Amount: ",EVENT_NONE,162+dwadd+wadd,40+dhadd+hadd,145,18,doodadmaxamount.val,0,100,"Maximum number of doodads per face")
1408         EndAlign()
1409         BeginAlign()
1410         doodheightmin = Number("Min Height: ",EVENT_NONE,12+dwadd+wadd,20+dhadd+hadd,145,18,doodheightmin.val,0.0,100.0,"Minimum height of any doodad")
1411         doodheightmax = Number("Max Height: ",EVENT_NONE,162+dwadd+wadd,20+dhadd+hadd,145,18,doodheightmax.val,0.0,100.0,"Maximum height of any doodad")
1412         EndAlign()
1413         BeginAlign()
1414         doodsizemin = Number("Min Size %: ",EVENT_NONE,12+dwadd+wadd,dhadd+hadd,145,18,doodsizemin.val,0.0,100.0,"Minimum size of any doodad in percentage of face")
1415         doodsizemax = Number("Max Size %: ",EVENT_NONE,162+dwadd+wadd,dhadd+hadd,145,18,doodsizemax.val,0.0,100.0,"Maximum size of any doodad in percentage of face")
1416         EndAlign()
1417         
1418         #Materials
1419         colorbox(8+mwadd+wadd,93+mhadd+hadd,312+mwadd+wadd,mhadd-5+hadd)
1420         glColor3f(0.0,0.0,0.0)
1421         glRasterPos2d(12+mwadd+wadd, 83+mhadd+hadd)
1422         Text("Materials:")
1423         glRasterPos2d(12+mwadd+wadd, 43+mhadd+hadd)
1424         Text("Assigned Material Indices:")
1425         assignNewMats = Toggle("Assign materials by part",EVENT_NONE,32+mwadd+wadd,60+mhadd+hadd,256,18,assignNewMats.val,"Otherwise, previous materials will be preserved")
1426         replProtSideIndex = Number("Protrusion Sides:",EVENT_NONE,12+mwadd+wadd,20+mhadd+hadd,145,18,replProtSideIndex.val,0,16,"Material index assigned to sides of protrusions")
1427         replProtTopIndex = Number("Protrusion Tops:",EVENT_NONE,162+mwadd+wadd,20+mhadd+hadd,145,18,replProtTopIndex.val,0,16,"Material index assigned to tops of protrusions")
1428         replDoodSideIndex = Number("Doodad Sides:",EVENT_NONE,12+mwadd+wadd,mhadd+hadd,145,18,replDoodSideIndex.val,0,16,"Material index assigned to sides of doodads")
1429         replDoodTopIndex = Number("Doodad Tops:",EVENT_NONE,162+mwadd+wadd,mhadd+hadd,145,18,replDoodTopIndex.val,0,16,"Material index assigned to tops and bottoms of doodads")
1430         
1431         #Global Parts
1432         colorbox(8+gwadd+wadd,35+ghadd+hadd,312+gwadd+wadd,ghadd-5+hadd)
1433         glColor3f(1.0,0.0,0.0)
1434         glRasterPos2d(12+gwadd+wadd,25+ghadd+hadd)
1435         messagetext = Text(errortext)
1436         glColor3f(0.0,0.0,0.0)
1437         makenewobject = Toggle("Copy Before Modifying",EVENT_NONE,162+gwadd+wadd,ghadd+hadd,145,18,makenewobject.val,"If selected, the original object will be copied before it is changed")
1438         Button("Discombobulate",EVENT_DISCOMBOBULATE,12+gwadd+wadd,ghadd+hadd,100,18)
1439         Button("Exit",EVENT_EXIT,120+gwadd+wadd,ghadd+hadd,30,18)
1440
1441 def event(evt, val):
1442         global wadd
1443         global hadd
1444         
1445         if (evt == RIGHTARROWKEY and val):
1446                 wadd = wadd + 20
1447                 Redraw(1)
1448         if (evt == LEFTARROWKEY and val):
1449                 wadd = wadd - 20
1450                 Redraw(1)
1451         if (evt == UPARROWKEY and val):
1452                 hadd = hadd + 20
1453                 Redraw(1)
1454         if (evt == DOWNARROWKEY and val):
1455                 hadd = hadd - 20
1456                 Redraw(1)
1457         if (evt == QKEY and not val): 
1458                 Exit()
1459
1460 def bevent(evt):
1461         
1462         #Protrusions
1463         global doprots
1464         global facechange
1465         global minheight
1466         global maxheight
1467         global sub1
1468         global sub2
1469         global sub3
1470         global sub4
1471         global mintaper
1472         global maxtaper
1473         global useselected
1474         global selface1
1475         global selface2
1476         global selface3
1477         global selface4
1478         global deselectvertices
1479         #global selectbyverts
1480         
1481         #Doodads
1482         global dodoodads
1483         global doodadfacechange
1484         global seldoodad
1485         global onprot
1486         global dood1
1487         global dood2
1488         global dood3
1489         global dood4
1490         global dood5
1491         global dood6
1492         global doodadminamount
1493         global doodadmaxamount
1494         global doodsizemin
1495         global doodsizemax
1496         global doodheightmin
1497         global doodheightmax
1498         global doodonselface
1499         global seldoodtop
1500         
1501         #Materials
1502         global assignNewMats
1503         global replProtSideIndex
1504         global replProtTopIndex
1505         global replDoodSideIndex
1506         global replDoodTopIndex
1507         
1508         #Global Settings
1509         global makenewobject
1510         global messagetext
1511         global errortext
1512         global EVENT_NONE,EVENT_DRAW,EVENT_EXIT
1513
1514         ######### Manages GUI events
1515         if evt==EVENT_EXIT: 
1516                 Exit()
1517         elif evt==EVENT_DISCOMBOBULATE:
1518                 Window.WaitCursor(1)
1519                 setProtrusionValues(doprots.val,facechange.val/100,minheight.val,maxheight.val,sub1.val,sub2.val,sub3.val,sub4.val,mintaper.val/100,maxtaper.val/100,useselected.val,selface1.val,selface2.val,selface3.val,selface4.val,deselectvertices.val)
1520                 setDoodadValues(dodoodads.val,doodadfacechange.val/100,seldoodad.val,onprot.val,dood1.val,dood2.val,dood3.val,dood4.val,dood5.val,dood6.val,doodadminamount.val,doodadmaxamount.val,doodsizemin.val/100,doodsizemax.val/100,doodheightmin.val,doodheightmax.val,doodonselface.val,seldoodtop.val)
1521                 setOtherValues(makenewobject.val,assignNewMats.val,replProtSideIndex.val,replProtTopIndex.val,replDoodSideIndex.val,replDoodTopIndex.val)
1522                 discombobulate()
1523                 Window.WaitCursor(0)
1524                 Blender.Redraw()
1525
1526 Register(draw, event, bevent)