Scripts:
[blender.git] / release / scripts / unweld044.py
1 #!BPY
2 """ Registration info for Blender menus: <- these words are ignored
3 Name: 'UnWeld'
4 Blender: 234
5 Group: 'Mesh'
6 Tip: 'Unweld all faces from a selected and common vertex. Made vertex bevelling.'
7 """
8
9 # $Id$
10 #
11 # ------------------------------------------
12 # Un-Weld script 0.4.4 beta
13 #
14 # split all faces from one selected vertex
15 # (c) 2004 J-M Soler released under Blender Artistic License
16 #----------------------------------------------
17 # Official Page :
18 # http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_faces2vertex.htm#exemple 
19 # Communicate problems and errors on:
20 # http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender 
21 #----------------------------------------------
22 # Blender Artistic License
23 # http://download.blender.org/documentation/html/x21254.html
24 #---------------------------------------------
25 # Changelog
26 #----------------------------------------------
27 # 25/05 :
28 # -- separate choise, normal (same place) or spread at random, middle of the face
29 # -- works on several vertices too
30 # -- Quite vertex bevelling on <<lone>> vertex : create hole in faces around this
31 # vertex
32 # 03/06 :
33 # -- a sort of "bevelled vertex" extrusion controled by horizontal mouse
34 # displacement. just a beta test to the mouse control.
35 #----------------------------------------------
36 # Page officielle :
37 #   http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_faces2vertex.htm#exemple
38 # Communiquer les problemes et erreurs sur:
39 #   http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender
40 # Blender Artistic License
41 #    http://download.blender.org/documentation/html/x21254.html
42 #--------------------------------------------- 
43 # Changelog
44 #----------------------------------------------
45 #      25/05 :
46 #           -- separation du choix, normal ou dispersion hasardeuse, milieu de face
47 #           -- sommets multiples / 
48 #           -- Quite vertex bevelling on lone vertex : create hole in faces around the
49 #              vertex 
50 #     03/06 :
51 #           -- a sort of "bevelled vertex" extrusion controled by horizontal mouse
52 #              displacement
53 #----------------------------------------------
54
55 import Blender
56 from Blender import Noise
57 from Blender.Draw import *
58 from Blender.BGL import *
59
60 Blender.Window.EditMode(0)
61
62 Nr=Noise.random
63 decal=0.03
64 t=[0.0,0.0,0.0]
65 pl=[]
66 orig=[]
67
68 DEBUG = 0
69 SUBSURF=0
70 DIM=Create(1.0)
71
72 def  Tampon(v,t):
73       for n in range(len(v)): t[n]=t[n]+v[n]
74       return t
75    
76 def  freeTampon(t):
77       for n in range(3): t[n]=0.0
78       return t
79
80 def  TamponMoyen(t,f):      
81       for n in range(3): t[n]/=len(f)
82       return t
83
84 def  appliqueMoyenne(v,t):
85       for n in range(len(v)): v[n]=t[n]
86       return v
87
88 def docF(f0,f):
89       try:
90           f0.mat=f.mat
91           f0.uv=f.uv 
92           f0.col=f.col
93           f0.image=f.image
94           return f0
95       except:
96           pass    
97
98 def listConnecterFace(me,lebon):
99                listf2v={}
100                #tri des faces connectees aux sommets selectionnes                           
101                for f in me.faces:
102                  for v in f.v:
103                    if v==lebon:
104                       if v.index not in listf2v.keys():
105                           listf2v[me.verts.index(v)]=[f]
106                       elif f not in listf2v[me.verts.index(v)]:
107                          listf2v[me.verts.index(v)].append(f)
108                return listf2v
109
110 def creerFaceSupplementaire(me,lebon,listf2v):
111                global t
112                for f in listf2v[lebon.index]:
113                   f0=Blender.NMesh.Face()
114                   if result==3: t=freeTampon(t)
115                   for v in f.v:
116                      if result==3: t=Tampon(v,t)
117                      if v!=lebon:
118                         f0.append(v)
119                      else:
120                         if result==2:                           
121                            nv=Blender.NMesh.Vert(lebon.co[0]+Nr()*decal,lebon.co[1]+Nr()*decal,lebon.co[2]+Nr()*decal)
122                         else:
123                            nv=Blender.NMesh.Vert(lebon.co[0],lebon.co[1],lebon.co[2])
124                         me.verts.append(nv)
125                         f0.append(me.verts[me.verts.index(nv)])
126                         localise=me.verts.index(nv)                          
127                      docF(f0,f)   
128                      
129                   if result==3:
130                          t=TamponMoyen(t,f0.v)
131                          me.verts[localise]=appliqueMoyenne(me.verts[localise],t)
132                   me.faces.append(f0)                  
133                del me.verts[me.verts.index(lebon)]
134                for f in listf2v[lebon.index]:
135                   del me.faces[me.faces.index(f)]
136                return me
137
138 def collecte_edge(listf2v,me,lebon):
139       back=0
140       edgelist = []
141       vertlist = []
142       if DEBUG : print listf2v    
143       for face in listf2v[lebon.index]:
144           if len(face.v) == 4:
145               vlist = [0,1,2,3,0]
146           elif len(face.v) == 3:
147               vlist = [0,1,2,0]
148           else:
149               vlist = [0,1]
150           for i in range(len(vlist)-1):              
151               vert0 = min(face.v[vlist[i]].index,face.v[vlist[i+1]].index)
152               vert1 = max(face.v[vlist[i]].index,face.v[vlist[i+1]].index)              
153               edgeinlist = 0
154               if vert0==lebon.index or vert1==lebon.index:                 
155                  for edge in edgelist:
156                     if ((edge[0]==vert0) and (edge[1]==vert1)):
157                         edgeinlist = 1
158                         edge[2] = edge[2]+1
159                         edge.append(me.faces.index(face))
160                         break                  
161                  if edgeinlist==0:
162                     edge = [vert0,vert1,1,me.faces.index(face)]
163                     edgelist.append(edge)
164                     
165       for  edge in edgelist:
166         #print edge
167         if len(edge)==4:
168                    del edgelist[edgelist.index(edge)]
169                            
170       edges=len(edgelist)
171       if DEBUG : print 'number of edges : ',edges," Edge list : " ,edgelist    
172       return edges, edgelist     
173
174 MouseClickG= Blender.Draw.LEFTMOUSE
175 MouseClickD= Blender.Draw.RIGHTMOUSE
176 MouseClickM= Blender.Draw.MIDDLEMOUSE
177
178 mouse_x=1
179 mouse_y=1
180
181 x=1
182 y=1
183
184 debut=0
185
186 def D():
187   size=Buffer(GL_FLOAT, 4)
188   glGetFloatv(GL_SCISSOR_BOX, size)
189   size= size.list 
190   glColor3f(0.1, 0.1, 0.15)
191   glRasterPos2f(10, size[3]-16)
192   Text("Quit = Qkey")
193   glRasterPos2f(10, size[3]-36)
194   Text("Mouse to the Rigth = Increase")
195   glRasterPos2f(10, size[3]-56)
196   Text("Mouse to the Left = Decrease")
197
198 def E(evt,val):
199  global mouse_x,x,pl,orig,me,debut
200  global mouse_y,y, MouseClickG,MouseClickD,MouseClickM
201  if (evt== QKEY or evt== ESCKEY): Exit()
202  
203  if (evt == MOUSEX): 
204        mouse_x = val
205        pos=x-mouse_x
206        x=mouse_x
207        if pos==0:
208           pos=1
209        deplace(pl,orig,abs(pos)/pos)
210  
211  if (evt == MOUSEY): mouse_y = val
212
213 def BE(evt):
214  pass
215
216
217 def deplace(pl,orig,n):
218     global me, OBJECT
219     for p in pl:
220        #print p, orig,len(me.verts) 
221        me.verts[p].co[0]+=n*orig[0]
222        me.verts[p].co[1]+=n*orig[1]
223        me.verts[p].co[2]+=n*orig[2]
224     me.update()
225     Blender.Redraw()
226
227
228 def VertexBevel(result):
229               global t,pl, orig,me,  SUBSURF
230               unique=0
231               for v in me.verts:
232                   if v.sel==1:
233                      lebon=v   
234                      unique+=1
235
236               if  unique==1:
237                     edges=0
238                     edgelist=[]
239                     vertlist=[]
240                     orig=lebon.no[:]
241                     listf2v=listConnecterFace(me,lebon)
242                     edges, edgelist = collecte_edge(listf2v,me,lebon)
243                     for f in listf2v[lebon.index]:
244                        f0=Blender.NMesh.Face()
245                        for v in f.v:
246                           if v!=lebon:
247                              f0.append(v)
248                           else:
249                               nv=Blender.NMesh.Vert(lebon.co[0],lebon.co[1],lebon.co[2])                           
250                               nv.sel=1 
251                               me.verts.append(nv)
252                               f0.append(me.verts[me.verts.index(nv)])
253                               for e in edgelist:
254                                  if e[-1]==me.faces.index(f) or e[-2]==me.faces.index(f):
255                                      if me.verts.index(nv) not in e:
256                                         e.insert(0,me.verts.index(nv))
257                        docF(f0,f)               
258                        me.faces.append(f0)                       
259                        vertlist.append([me.verts.index(nv),me.faces.index(f)])
260                     for e in  edgelist :
261                         del e[e.index(lebon.index)]
262                         f0=Blender.NMesh.Face()
263                         for n in range(3): 
264                            f0.v.append(me.verts[e[n]])
265                         me.faces.append(f0);
266                      
267                     for ve in vertlist:
268                          t=freeTampon(t)
269                          for v in me.faces[ve[1]].v:
270                               t=Tampon(v,t)                     
271                          t=TamponMoyen(t,me.faces[ve[1]].v)
272                          ve.append(t[:])        
273                          me.verts[ve[0]]=appliqueMoyenne(me.verts[ve[0]],t)
274
275                     def swap(x,y):
276                         return y,x
277
278                     p=[[edgelist[0][0],edgelist[0][1]]] 
279                     while len(p)!=len(edgelist): 
280                       for n in range(1,len(edgelist)) :
281                            if p[-1][1]== edgelist[n][0]:
282                               p.append([edgelist[n][0],edgelist[n][1]])
283                               n+=1
284                            elif p[-1][1]== edgelist[n][1]:
285                               edgelist[n][0],edgelist[n][1]=swap(edgelist[n][0],edgelist[n][1])
286                               p.append([edgelist[n][0],edgelist[n][1]])
287                               n+=1
288                     if len(p)%2==0:
289                           P0=p[:(len(p))/2] ; P1=p[len(p)/2:]; P1.reverse()
290                           for s in range(len(P0)-1):
291                              f0=Blender.NMesh.Face()
292                              table=[P0[s][0],P0[s][1],P1[s+1][0],P1[s+1][1]]
293                              for t in table:f0.v.append(me.verts[t])
294                              me.faces.append(f0) 
295                     elif len(p) >3 :   
296                           P0=p[:(len(p)-1)/2];P1=p[(len(p)-1)/2:-1]; P1.reverse()
297                           for s in range(len(P0)-1):
298                              f0=Blender.NMesh.Face()
299                              table=[P0[s][0],P0[s][1],P1[s+1][0],P1[s+1][1]]
300                              for t in table:f0.v.append(me.verts[t])
301                              me.faces.append(f0) 
302                           f0=Blender.NMesh.Face()
303                           table=[p[-1][0],P0[0][0],P1[-1][1]]
304                           for t in table:f0.v.append(me.verts[t])
305                           me.faces.append(f0) 
306
307                     elif len(p) ==3 :   
308                           if DEBUG :print P0,P1      
309                           f0=Blender.NMesh.Face()
310                           table=[p[0][0],p[0][1],p[1][1]]
311                           for t in table:f0.v.append(me.verts[t])
312                           me.faces.append(f0) 
313
314                     for f in listf2v[lebon.index]:
315                        del me.faces[me.faces.index(f)]  
316                     del me.verts[me.verts.index(lebon)]
317                     me.update()
318
319                     if me.mode&Blender.NMesh.Modes['SUBSURF']:
320                        me.mode-=Blender.NMesh.Modes['SUBSURF']
321                        SUBSURF=1 
322                        me.update()
323                        OBJECT[0].makeDisplayList() 
324
325                     if result==5:
326                        pl=[]
327                        for s in me.verts:
328                            if s.sel==1:
329                               pl.append(s.index)
330                        Blender.Draw.Register(D,E,BE)
331
332                     """
333                     if SUBSURF==1 :
334                        me.mode+=Blender.NMesh.Modes['SUBSURF']
335                        me.update()
336                        OBJECT[0].makeDisplayList() 
337                     """  
338               else:
339                   name = " It could leave only one selected vertex %t | ok %x1 ?"
340                   result = Blender.Draw.PupMenu(name)
341
342 OBJECT=Blender.Object.GetSelected()
343
344 if len(OBJECT)!=0:
345    if  OBJECT[0].getType()=='Mesh':
346        name = "Un-Weld, OK ? %t| unbind points %x1| with noise ? %x2| middle face ? %x3| static bevel vertex ? %x4| moving bevel vertex ? %x5|"
347        result = Blender.Draw.PupMenu(name)
348        if result:
349            me=OBJECT[0].getData()
350            unique=0
351            if result<4:
352               #tri des sommets selectionnes
353               for v in me.verts:
354                   if v.sel==1:
355                     lebon=v    
356                     if DEBUG : print lebon
357                     #dictionnaires des faces connectees aux sommets selectionnes
358                     listf2v=listConnecterFace(me,lebon)
359                     me=creerFaceSupplementaire(me,lebon,listf2v)
360                     OBJECT[0].link(me)
361                     OBJECT[0].makeDisplayList()
362            else:
363                VertexBevel(result)
364                OBJECT[0].makeDisplayList()
365                     
366    else:
367        name = "Nothing to do! Are you sure ?"
368        result = Blender.Draw.PupMenu(name)
369
370