#!BPY """ Name: 'Copy/Paste vertex weight' Blender: 247 Group: 'Mesh' Tooltip: 'Copy/Paste vertex weight' """ __author__ = "Ivo Grigull" __url__ = ("homepage", "http://www.ivogrigull.com") __version__ = "0.1" __bpydoc__ = """ Copy/Paste vertex weight ------------------------------ Menu: Script Window -> Copy/Paste vertex weight With this script you can pick a vertex to copy it's weight and paste it to multiple other vertices. If you selected more than one vert in the first step and click on paste, the applied weights will be averaged. This is useful to match or repair weights between different mesh parts. In my example i am attaching a belt buckle to the belly of my character. There is another Button called 'Average Vertex Weights'. I could also just have named it 'smooth'. It will smooth the selected vertex weights with a fallof within the selection. """ # Copyright (C) 2008: Ivo Grigull # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software Foundation, # Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. import Blender from Blender import Draw, BGL, Armature from Blender import Draw, Window import BPyMesh global tmp def event(evt, val): # the function to handle input events if evt == Draw.ESCKEY: Draw.Exit() # exit when user presses ESC return else: return # no need to redraw if nothing changed Draw.Redraw(1) def button_event(evt): return def doCopy(evt, eval): in_editmode = Window.EditMode() if in_editmode: Window.EditMode(0) ob = Blender.Object.GetSelected()[0] me = ob.getData( mesh=1 ) verts = me.verts global tmp tmp = [f for f in verts if f.sel] print tmp if in_editmode: Window.EditMode(1) def doPaste(evt, eval): in_editmode = Window.EditMode() if in_editmode: Window.EditMode(0) ob = Blender.Object.GetSelected()[0] me = ob.getData( mesh=1 ) verts = me.verts vsel = [f for f in verts if f.sel] global tmp groupNames, vWeightDict= BPyMesh.meshWeight2Dict(me) mergelist = [] for n in tmp: mergelist.append( vWeightDict[n.index].copy() ) for n in vsel: # vWeightDict[n.index] = vWeightDict[tmp].copy() vWeightDict[n.index] = BPyMesh.dictWeightMerge( mergelist ) BPyMesh.dict2MeshWeight(me, groupNames, vWeightDict) if in_editmode: Window.EditMode(1) def mergeDict( dict1, dict2, ratio ): for n in dict1.keys(): dict1[n] *= 1-ratio for n in dict2.keys(): if dict1.has_key(n): dict1[n] += dict2[n] * ratio else: dict1[n] = dict2[n] * ratio return dict1 # smoothed the weights of the selected weights with a fallof to the vertex most far away. # def doAverage(ect, eval): in_editmode = Window.EditMode() if in_editmode: Window.EditMode(0) ob = Blender.Object.GetSelected()[0] me = ob.getData( mesh=1 ) verts = me.verts groupNames, vWeightDict= BPyMesh.meshWeight2Dict(me) vsel = [f for f in verts if f.sel] center = Blender.Mathutils.Vector( 0,0,0 ) mergelist = [] for n in vsel: mergelist.append( vWeightDict[n.index].copy() ) center += n.co avg = BPyMesh.dictWeightMerge( mergelist ) center /= len(vsel) # print center largestdist = 0.0 for n in vsel: dist = (center - n.co).length if dist > largestdist: largestdist = dist # print 'largest: %f' % largestdist normalfac = 1/largestdist # print 'Normfac: %f' % normalfac for n in vsel: dist = 1 - ((center - n.co).length * normalfac) print 'V dist: %f' % dist # vWeightDict[n.index] = BPyMesh.dictWeightMerge( [vWeightDict[n.index], avg] ) vWeightDict[n.index] = mergeDict( vWeightDict[n.index].copy(), avg.copy(), dist ) BPyMesh.dict2MeshWeight(me, groupNames, vWeightDict) if in_editmode: Window.EditMode(1) def doExit(evt, eval): Draw.Exit() return def gui(): # the function to draw the screen Draw.PushButton("Copy Vertex weight(s)", 1, 0, 80, 200, 20, "You can copy one or multiple vertex weights", doCopy) Draw.PushButton("Paste average weight on vertices", 2, 0, 55, 200, 20, "Paste weights on multiple vertices", doPaste) Draw.PushButton("Average vertex weights", 2, 0, 30, 200, 20, "Average or smooth selected vertices", doAverage) Draw.PushButton("Exit", 2, 60, 5, 60, 20, "Pase", doExit) Draw.Register(gui, event, button_event) # registering the 3 callbacks