#!BPY """ Name: 'Align Verts to Grid' Blender: 232 Group: 'Object' Tooltip: 'Moves the verts of the mesh to a granuality you specify' """ __author__ = ["Nick Lawson"] __url__ = ("blender", "elysiun") __version__ = "1.0.0" __bpydoc__ = """\ This tool moves the vertices of the mesh to the nearest multiple of a given size. It does so in world, not object space! It works on curves too. Usage: Select a mesh, select a bunch of vertices and then activate this tool. It will only apply it to the selected vertices. """ import Blender from Blender import * from Blender.sys import time from math import * def RoundToNearest(value,divisor): if (abs(divisor) < float(0.000001)): return value halfit = float(divisor) / 2.0 if (value < 0): halfit = -halfit newvalue = float(value) + float(halfit) newvalue2 = int(float(newvalue) / float(divisor)) finalvalue = float(newvalue2) * float(divisor) return finalvalue def DoMesh(whichmesh,spacemat,invspacemat,roundnum): vertsel = [] SEL = [s for s in whichmesh.verts if s.sel] for curvert in SEL : newvert = Mathutils.Vector() newvert.x = curvert.co[0] newvert.y = curvert.co[1] newvert.z = curvert.co[2] newvert.resize4D() """ newpos = Mathutils.VecMultMat(newvert,spacemat) """ newpos = newvert * spacemat newpos.x = RoundToNearest(newpos.x,roundnum) newpos.y = RoundToNearest(newpos.y,roundnum) newpos.z = RoundToNearest(newpos.z,roundnum) """ finalpos = Mathutils.VecMultMat(newpos,invspacemat) """ finalpos = newpos * invspacemat curvert.co[0] = finalpos.x curvert.co[1] = finalpos.y curvert.co[2] = finalpos.z whichmesh.update() return def DoCurve(whichcurve,spacemat,invspacemat,roundnum): numcurves = len(whichcurve) for curvenum in range(0,numcurves): numpts = len(whichcurve[curvenum]) for pointnum in range(0,numpts): currentpoint = whichcurve.getControlPoint(curvenum,pointnum) if (whichcurve.isNurb()==0): #list of 9 coords per point newvert = Mathutils.Vector(currentpoint[0:3]) newvert.resize4D() newpos = Mathutils.VecMultMat(newvert,spacemat) newpos.x = RoundToNearest(newpos.x,roundnum) newpos.y = RoundToNearest(newpos.y,roundnum) newpos.z = RoundToNearest(newpos.z,roundnum) finalpos = Mathutils.VecMultMat(newpos,invspacemat) finalist = [] for floatval in [finalpos.x,finalpos.y,finalpos.z]: finalist.append(floatval) newvert = Mathutils.Vector(currentpoint[3:6]) newvert.resize4D() newpos = Mathutils.VecMultMat(newvert,spacemat) newpos.x = RoundToNearest(newpos.x,roundnum) newpos.y = RoundToNearest(newpos.y,roundnum) newpos.z = RoundToNearest(newpos.z,roundnum) finalpos = Mathutils.VecMultMat(newpos,invspacemat) for floatval in [finalpos.x,finalpos.y,finalpos.z]: finalist.append(floatval) newvert = Mathutils.Vector(currentpoint[6:9]) newvert.resize4D() newpos = Mathutils.VecMultMat(newvert,spacemat) newpos.x = RoundToNearest(newpos.x,roundnum) newpos.y = RoundToNearest(newpos.y,roundnum) newpos.z = RoundToNearest(newpos.z,roundnum) finalpos = Mathutils.VecMultMat(newpos,invspacemat) for floatval in [finalpos.x,finalpos.y,finalpos.z]: finalist.append(floatval) whichcurve.setControlPoint(curvenum,pointnum,finalist) else: avertit = Mathutils.Vector(currentpoint) newpos = Mathutils.VecMultMat(avertit,spacemat) newpos.x = RoundToNearest(newpos.x,roundnum) newpos.y = RoundToNearest(newpos.y,roundnum) newpos.z = RoundToNearest(newpos.z,roundnum) finalpos = Mathutils.VecMultMat(newpos,invspacemat) finallist = [finalpos.x,finalpos.y,finalpos.z,finalpos.w] whichcurve.setControlPoint(curvenum,pointnum,finallist) whichcurve.update() return def DoShifter(whichobject,amount): if (whichobject.getType()!='Curve'): if (whichobject.getType()!='Mesh'): Draw.PupMenu("Only works on Curves or Meshes. Sorry."); return mObjectToWorldSpace = whichobject.getMatrix('worldspace') mWorldToObjectSpace = whichobject.getMatrix('worldspace') mWorldToObjectSpace.invert() mydata = whichobject.getData() # now its a mesh if (whichobject.getType()=='Curve'): DoCurve(mydata,mObjectToWorldSpace,mWorldToObjectSpace,amount) else: finalmesh = NMesh.GetRaw(mydata.name) DoMesh(finalmesh,mObjectToWorldSpace,mWorldToObjectSpace,amount) # we get the value last set from the registry dict = Registry.GetKey('Vert_To_Grid') sizegranularity = 0.5 if dict: sizegranularity = dict['granularity'] in_editmode = Window.EditMode() if in_editmode: Window.EditMode(0) # change mesh cursorpos = Window.GetCursorPos() selected_objects = Object.GetSelected() if (len(selected_objects)<1): Draw.PupMenu("Please select at least one object.") Window.RedrawAll() else: sizegranularity = Draw.PupFloatInput("Cell Size:",sizegranularity,0.0001,10000,25,2) if (sizegranularity != None): for CurObj in selected_objects: DoShifter(CurObj,sizegranularity) if in_editmode: Window.EditMode(1) Window.RedrawAll() # save to registry dict = {} dict['granularity'] = sizegranularity Registry.SetKey('Vert_To_Grid',dict) print '....'