Integrated Freestyle to rendering pipeline
[blender.git] / release / scripts / unweld.py
1 #!BPY
2 """ Registration info for Blender menus: <- these words are ignored
3 Name: 'Unweld vertex/ices'
4 Blender: 243
5 Group: 'Mesh'
6 Tip: 'Unweld all faces from a (or several) selected and common vertex. Made vertex bevelling'
7 """
8
9 __author__ = "Jean-Michel Soler (jms)"
10 __url__ = ("blender", "blenderartists.org",
11 "Script's homepage, http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_faces2vertex.htm#exemple",
12 "Communicate problems and errors, http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender")
13 __version__ = "0.4.6 "
14 __bpydoc__ = """\
15 This script unwelds faces from one or several selected vertex/vertices.
16
17 Usage:
18
19 In edit mode Select at least one vertex, then run this script.
20
21 The options are:
22
23 - unbind points;<br>
24                 a new point is added to each face connected to the selected one.
25                 
26 - with noise;<br>
27                 the new points location is varied with noise
28                 
29 - middle face;<br>
30                 the new point is located at the center of face to which it is connected
31 """
32
33 # ------------------------------------------
34 # Un-Weld script 0.4.6 
35 # name="UnWeld"
36 # Tip= 'Unweld all faces from a selected and common vertex.'
37 # date='06/08/2006'
38 # split all faces from one selected vertex
39 # (c) 2004 J-M Soler released under GPL licence
40 #----------------------------------------------
41 # Official Page :
42 # website = 'http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_faces2vertex.htm#exemple'
43 # Communicate problems and errors on:
44 # community = 'http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender'
45 #----------------------------------------------
46 # Blender Artistic License
47 # http://download.blender.org/documentation/html/x21254.html
48 #---------------------------------------------
49 # Changelog
50 #----------------------------------------------
51 # 25/05 :
52 # -- separate choice, normal (same place) or spread at random, middle of the face
53 # -- works on several vertices too
54 # -- Quite vertex bevelling on <<lone>> vertex : create hole in faces around this
55 # vertex
56 # 03/06 :
57 # -- a sort of "bevelled vertex" extrusion controled by horizontal mouse
58 # displacement. just a beta test to the mouse control.
59 # 08/08 :
60 # -- minor correction to completely disconnect face.
61 #----------------------------------------------
62 # Page officielle :
63 #   http://jmsoler.free.fr/didacticiel/blender/tutor/cpl_faces2vertex.htm#exemple
64 # Commsoler les problemes et erreurs sur:
65 #   http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender
66 # Blender Artistic License
67 #    http://download.blender.org/documentation/html/x21254.html
68 #--------------------------------------------- 
69 # Changelog
70 #----------------------------------------------
71 #     25/05 :
72 #           -- separation du choix, normal ou dispersion hasardeuse, 
73 #              milieu de face
74 #           -- sommets multiples / 
75 #           -- presque  unvertex bevelling sur un vertex solitaire : cree
76 #              un trou dans la facette autour du sommet
77 #     03/06 :
78 #           -- une sorte de vertex extruder en biseau, controle par
79 #              movement horizontal de la souris 
80 #     08/08 :
81 #           -- correction mineure pour s'assurer que les faces soient 
82 #              entierment deconnectees
83 #----------------------------------------------
84
85 import Blender
86 from Blender import Noise
87 from Blender.Draw import *
88 from Blender.BGL import *
89 import BPyMessages
90 # $Id$
91
92 NR=Noise.random
93 DECAL=0.03
94 t=[0.0,0.0,0.0]
95 pl=[]
96 orig=[]
97
98 DEBUG = 0
99 SUBSURF=0
100 DIM=Create(1.0)
101
102 def  Buffer(v,t):
103         if DEBUG : print dir(v)
104         for n in range(len(v)): t[n]=t[n]+v[n]
105         return t
106
107 def  freeBuffer(t):
108         for n in range(3): t[n]=0.0
109         return t
110
111 def  ModalBuffer(t,f):      
112         for n in range(3): t[n]/=len(f)
113         return t
114
115 def  applyModalValue(v,t):
116         for n in range(len(v)): v[n]=t[n]
117         return v
118
119 def docF(f0,f):
120
121         if f0 and f:
122                 f0.mat=f.mat
123                 if f.uv :
124                         f0.uv=f.uv 
125                 if f.col :
126                         f0.col=f.col
127                 if f.image :
128                         f0.image=f.image
129                 f0.smooth=f.smooth
130                 f0.mode=f.mode
131                 f0.flag=f.flag
132                 return f0
133         
134
135 def connectedFacesList(me,thegood):
136         listf2v={}
137         #tri des faces connectees aux sommets selectionnes                           
138         for f in me.faces:
139                 for v in f.v:
140                         if v==thegood:
141                                 if v.index not in listf2v: # .keys()
142                                         listf2v[me.verts.index(v)]=[f]
143                                 elif f not in listf2v[me.verts.index(v)]:
144                                         listf2v[me.verts.index(v)].append(f)
145         return listf2v
146
147
148 def createAdditionalFace(me,thegood,listf2v):
149         global t
150         for f in listf2v[thegood.index]:
151                 f0=Blender.NMesh.Face()
152                 if result==3: t=freeBuffer(t)
153                 for v in f.v:
154                         if result==3: t=Buffer(v,t)
155                         if v!=thegood:
156                                 f0.append(v)
157                         else:
158                                 if result==2:                           
159                                         nv=Blender.NMesh.Vert(thegood.co[0]+NR()*DECAL,
160                                                 thegood.co[1]+NR()*DECAL,
161                                                 thegood.co[2]+NR()*DECAL)
162                                 else:
163                                                 nv=Blender.NMesh.Vert(thegood.co[0],
164                                                         thegood.co[1],
165                                                         thegood.co[2])
166                                 nv.sel=1
167                                 me.verts.append(nv)
168                                 f0.append(me.verts[me.verts.index(nv)])
169                                 localise=me.verts.index(nv)                          
170                         docF(f0,f)   
171                 if result==3:
172                                          t=ModalBuffer(t,f0.v)
173                                          me.verts[localise]=applyModalValue(me.verts[localise],t)
174                 me.faces.append(f0)                  
175         del me.verts[me.verts.index(thegood)]
176         for f in listf2v[thegood.index]:
177                         del me.faces[me.faces.index(f)]
178         return me
179
180 def collecte_edge(listf2v,me,thegood):
181         back=0
182         edgelist = []
183         vertlist = []
184         if DEBUG : print listf2v    
185         for face in listf2v[thegood.index]:
186                 if len(face.v) == 4:
187                         vlist = [0,1,2,3,0]
188                 elif len(face.v) == 3:
189                         vlist = [0,1,2,0]
190                 else:
191                         vlist = [0,1]
192                 for i in xrange(len(vlist)-1):              
193                         vert0 = min(face.v[vlist[i]].index,face.v[vlist[i+1]].index)
194                         vert1 = max(face.v[vlist[i]].index,face.v[vlist[i+1]].index)              
195                         edgeinlist = 0
196                         if vert0==thegood.index or vert1==thegood.index:                 
197                                 for edge in edgelist:
198                                         if ((edge[0]==vert0) and (edge[1]==vert1)):
199                                                 edgeinlist = 1
200                                                 edge[2] = edge[2]+1
201                                                 edge.append(me.faces.index(face))
202                                                 break                  
203                                 if edgeinlist==0:
204                                         edge = [vert0,vert1,1,me.faces.index(face)]
205                                         edgelist.append(edge)
206                                         
207         for i, edge in enumerate(edgelist):
208                 #print edge
209                 if len(edge)==4:
210                         del edgelist[i]
211                                 
212         edges=len(edgelist)
213         if DEBUG : print 'number of edges : ',edges," Edge list : " ,edgelist    
214         return edges, edgelist     
215
216 import bpy
217 OBJECT= bpy.data.scenes.active.objects.active
218
219 if OBJECT and OBJECT.type=='Mesh':
220         if OBJECT.getData(mesh=1).multires:
221                 BPyMessages.Error_NoMeshMultiresEdit()
222         elif not BPyMessages.Warning_MeshDistroyLayers(OBJECT.getData(mesh=1)):
223                 pass
224         else:
225                 EDITMODE=Blender.Window.EditMode()
226                 Blender.Window.EditMode(0)
227                 name = "Unweld %t|Unbind Points %x1|With Noise %x2|Middle Face %x3"
228                 result = Blender.Draw.PupMenu(name)
229                 if result:
230                         me=OBJECT.getData()
231                         
232                         for v in me.verts:
233                                 if v.sel:
234                                         thegood=v    
235                                         if DEBUG : print thegood
236                                         listf2v=connectedFacesList(me,thegood)
237                                         if listf2v:
238                                                 me=createAdditionalFace(me,thegood,listf2v)
239                                                 #OBJECT.link(me)
240                                                 me.update()
241                         
242                         OBJECT.makeDisplayList()
243                         
244                 Blender.Window.EditMode(EDITMODE)
245         
246 else:
247         BPyMessages.Error_NoMeshActive()