Difference between revisions of "Pyhton Scripts"
Frankiezafe (Talk | contribs) (→GlueVertices) |
Frankiezafe (Talk | contribs) (→GlueVertices) |
||
| Line 144: | Line 144: | ||
from bpy import context | from bpy import context | ||
from math import sqrt | from math import sqrt | ||
| + | from mathutils import Vector | ||
| + | # BEFORE launching script, SELECT the vertices to test | ||
| + | |||
| + | # config | ||
TOLERANCE = 0.00001 | TOLERANCE = 0.00001 | ||
| + | |||
| + | # globals | ||
MERGED_COUNT = 0 | MERGED_COUNT = 0 | ||
| + | LAST_INDEX = 0 | ||
| + | VSELECTED = [] | ||
| + | VMERGES = {} | ||
| + | VMERGEPOS = [] | ||
def getDistance( v1, v2 ): | def getDistance( v1, v2 ): | ||
| − | |||
| − | |||
| − | |||
distance = sqrt( (v1.co[0] - v2.co[0])**2 + (v1.co[1] - v2.co[1])**2 + (v1.co[2] - v2.co[2])**2) | distance = sqrt( (v1.co[0] - v2.co[0])**2 + (v1.co[1] - v2.co[1])**2 + (v1.co[2] - v2.co[2])**2) | ||
| − | #print(distance) | + | #print(distance) |
return distance | return distance | ||
| − | def | + | def getDistance2Vector( vertex, vector ): |
| − | + | distance = sqrt( (vertex.co[0] - vector.x)**2 + (vertex.co[1] - vector.y)**2 + (vertex.co[2] - vector.z)**2) | |
| − | + | #print(distance) | |
| − | + | return distance | |
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | return | + | |
obj = context.active_object | obj = context.active_object | ||
print( "scanning", obj.data.vertices, "vertices" ) | print( "scanning", obj.data.vertices, "vertices" ) | ||
| − | + | bpy.ops.object.mode_set(mode="OBJECT") | |
| + | |||
| + | vall = obj.data.vertices | ||
| + | for v in vall: | ||
| + | if v.select: | ||
| + | VSELECTED.append( v ) | ||
| + | |||
| + | print( "***********", len( VSELECTED ), "vertices to verify" ) | ||
| + | |||
| + | # making merge groups | ||
| + | vselnum = len( VSELECTED ) | ||
| + | i = 0 | ||
| + | for v in VSELECTED: | ||
| + | #print( v.co, i ) | ||
| + | for j in range( i + 1, vselnum ): | ||
| + | if j >= vselnum: | ||
| + | break | ||
| + | vo = VSELECTED[ j ] | ||
| + | d = getDistance( v, vo ) | ||
| + | if d < TOLERANCE: | ||
| + | # retro seeking: v may have to be merged with a previous one! | ||
| + | index = i | ||
| + | for m in VMERGES: | ||
| + | mlist = VMERGES[ m ] | ||
| + | mcontinue = True | ||
| + | for mc in mlist: | ||
| + | if mc == v: | ||
| + | index = m | ||
| + | mcontinue = False | ||
| + | #print( "retro-seek is successful", i, m ) | ||
| + | break | ||
| + | if not mcontinue: | ||
| + | break | ||
| + | |||
| + | if i not in VMERGES: | ||
| + | VMERGES[ index ] = [ v ] | ||
| + | VMERGES[ index ].append( vo ) | ||
| + | |||
| + | i += 1 | ||
| + | |||
| + | # rendering position of merge | ||
| + | for k in VMERGES: | ||
| + | mlist = VMERGES[ k ] | ||
| + | pos = Vector( (0,0,0) ) | ||
| + | for mc in mlist: | ||
| + | pos.x += mc.co[0] | ||
| + | pos.y += mc.co[1] | ||
| + | pos.z += mc.co[2] | ||
| + | pos.x /= len( mlist ) | ||
| + | pos.y /= len( mlist ) | ||
| + | pos.z /= len( mlist ) | ||
| + | #print( len(VMERGEPOS), ">>", len(mlist), ">>", pos ) | ||
| + | VMERGEPOS.append( pos ) | ||
| + | |||
| + | print( "VMERGEPOS:", len( VMERGEPOS ) ) | ||
bpy.ops.object.mode_set(mode="EDIT") | bpy.ops.object.mode_set(mode="EDIT") | ||
| Line 188: | Line 232: | ||
bpy.ops.object.mode_set(mode="OBJECT") | bpy.ops.object.mode_set(mode="OBJECT") | ||
| − | + | mcount = 0 | |
| − | + | for p in VMERGEPOS: | |
| − | + | vall = obj.data.vertices | |
| − | print( | + | velected = 0 |
| + | for v in vall: | ||
| + | d = getDistance2Vector( v, p ) | ||
| + | if d < TOLERANCE: | ||
| + | v.select = True | ||
| + | velected += 1 | ||
| + | if velected != 0: | ||
| + | bpy.ops.object.mode_set(mode="EDIT") | ||
| + | bpy.ops.mesh.merge(type='CENTER') | ||
| + | bpy.ops.mesh.select_all(action="DESELECT") | ||
| + | bpy.ops.object.mode_set(mode="OBJECT") | ||
| + | print( "merge done at", p.x, p.y, p.z, "vertex:", velected, "count:", mcount, "/", len(VMERGEPOS) ) | ||
| + | MERGED_COUNT += velected | ||
| + | mcount += 1 | ||
print( "total:", MERGED_COUNT, "vertices have been merged" ) | print( "total:", MERGED_COUNT, "vertices have been merged" ) | ||
[https://github.com/Blender-Brussels/bpy-bge-library/blob/master/users/frankiezafe/tanukis/GlueVertices.py script on github] | [https://github.com/Blender-Brussels/bpy-bge-library/blob/master/users/frankiezafe/tanukis/GlueVertices.py script on github] | ||
Revision as of 20:42, 8 April 2016
Python scripts vault used during the project.
Contents
BoneMatrixCopy
import bpy, math from mathutils import Vector, Matrix # configuration ############ ARMATURE_NAME = 'makehuman' BONE_NAME = 'RightArm' # getting the right bone, no safety net... scn = bpy.context.scene armature = scn.objects[ ARMATURE_NAME ].data bone = armature.bones[ BONE_NAME ] # orientation of the bone is represented as a 4x4 matrix # see https://www.blender.org/api/blender_python_api_2_59_0/bpy.types.Bone.html#bpy.types.Bone.matrix_local bone_mat = bone.matrix_local # getting the active object target = scn.objects.active # copy of the matrix ############ target.matrix_local = bone_mat target.rotation_mode = 'QUATERNION' target.rotation_mode = 'XYZ' print( 'done, matrix of bone', armature.name, ':', bone.name, 'copied on', target.name )
BonesAndVertexgroupsBulkRenaming
import bpy # right and left markers NEEDLE = "R_" REPLACE = "L_" # name of the armature and the related mesh ARMATURE_NAME = 'armature_skeleton' MESH_NAME = 'skeleton' scn = bpy.context.scene armature = scn.objects[ ARMATURE_NAME ].data mesh = scn.objects[ MESH_NAME ] # renaming all bones print( "armature:", ARMATURE_NAME, armature ) for b in armature.bones: b.name = b.name.replace( NEEDLE, REPLACE ) print( b.name ) # renaming all vertex groups print( "mesh:", MESH_NAME, mesh ) for vg in mesh.vertex_groups: vg.name = vg.name.replace( NEEDLE, REPLACE ) print( vg.name )
BonesVertexgroupsSync
import bpy
# name of the armature and the related mesh
ARMATURE_NAME = 'armature_skeleton'
MESH_NAME = 'skeleton'
REMOVE_VERTEXGROUPS = True
scn = bpy.context.scene
armature = scn.objects[ ARMATURE_NAME ].data
mesh = scn.objects[ MESH_NAME ]
print( mesh.vertex_groups )
# creation of missing vertex groups
for b in armature.bones:
found = False
for vg in mesh.vertex_groups:
if vg.name == b.name:
found = True
if found == False:
mesh.vertex_groups.new( b.name )
print( b.name, "vertex group created" )
# deletion of vertex groups
if REMOVE_VERTEXGROUPS == True:
for vg in mesh.vertex_groups:
found = False
for b in armature.bones:
if vg.name == b.name:
found = True
if found == False:
print( vg.name, "vertex group removed" )
mesh.vertex_groups.remove( vg )
BatchBonesModification
import bpy
# name of the armature
ARMATURE_NAME = 'armature_skeleton'
NAME_FILTER = 'spine'
def doContinue( name ):
global NAME_FILTER
if NAME_FILTER == :
return True
if name.find( NAME_FILTER ) != -1:
return True
return False
scn = bpy.context.scene
armature = scn.objects[ ARMATURE_NAME ]
# modification on bones
# modifiable params are listed in doc
# https://www.blender.org/api/blender_python_api_2_77_release/bpy.types.Bone.html#bpy.types.Bone
print( '**** bones:', len(armature.pose.bones) )
for b in armature.data.bones:
if not doContinue( b.name ):
continue
print( b.name )
b.use_inherit_rotation = True
b.use_inherit_scale = False
# modification on pose bones
# modifiable params are listed in doc
# https://www.blender.org/api/blender_python_api_2_77_release/bpy.types.PoseBone.html
print( '**** pose bones:', len(armature.pose.bones) )
for pb in armature.pose.bones:
if not doContinue( pb.name ):
continue
print( pb.name )
pb.lock_location = (False,False,False)
pb.lock_rotation = (False,False,False)
pb.lock_scale = (False,False,False)
GlueVertices
# based on https://www.blender.org/api/blender_python_api_current/bpy.types.MeshVertex.html?highlight=meshvertex # and http://blender.stackexchange.com/questions/7144/how-to-get-the-distance-between-two-objects-in-the-game-engine import bpy from bpy import context from math import sqrt from mathutils import Vector # BEFORE launching script, SELECT the vertices to test # config TOLERANCE = 0.00001 # globals MERGED_COUNT = 0 LAST_INDEX = 0 VSELECTED = [] VMERGES = {} VMERGEPOS = [] def getDistance( v1, v2 ): distance = sqrt( (v1.co[0] - v2.co[0])**2 + (v1.co[1] - v2.co[1])**2 + (v1.co[2] - v2.co[2])**2) #print(distance) return distance def getDistance2Vector( vertex, vector ): distance = sqrt( (vertex.co[0] - vector.x)**2 + (vertex.co[1] - vector.y)**2 + (vertex.co[2] - vector.z)**2) #print(distance) return distance obj = context.active_object print( "scanning", obj.data.vertices, "vertices" ) bpy.ops.object.mode_set(mode="OBJECT") vall = obj.data.vertices for v in vall: if v.select: VSELECTED.append( v ) print( "***********", len( VSELECTED ), "vertices to verify" ) # making merge groups vselnum = len( VSELECTED ) i = 0 for v in VSELECTED: #print( v.co, i ) for j in range( i + 1, vselnum ): if j >= vselnum: break vo = VSELECTED[ j ] d = getDistance( v, vo ) if d < TOLERANCE: # retro seeking: v may have to be merged with a previous one! index = i for m in VMERGES: mlist = VMERGES[ m ] mcontinue = True for mc in mlist: if mc == v: index = m mcontinue = False #print( "retro-seek is successful", i, m ) break if not mcontinue: break if i not in VMERGES: VMERGES[ index ] = [ v ] VMERGES[ index ].append( vo ) i += 1 # rendering position of merge for k in VMERGES: mlist = VMERGES[ k ] pos = Vector( (0,0,0) ) for mc in mlist: pos.x += mc.co[0] pos.y += mc.co[1] pos.z += mc.co[2] pos.x /= len( mlist ) pos.y /= len( mlist ) pos.z /= len( mlist ) #print( len(VMERGEPOS), ">>", len(mlist), ">>", pos ) VMERGEPOS.append( pos ) print( "VMERGEPOS:", len( VMERGEPOS ) ) bpy.ops.object.mode_set(mode="EDIT") bpy.ops.mesh.select_all(action="DESELECT") bpy.context.tool_settings.mesh_select_mode = (True , False , False) bpy.ops.object.mode_set(mode="OBJECT") mcount = 0 for p in VMERGEPOS: vall = obj.data.vertices velected = 0 for v in vall: d = getDistance2Vector( v, p ) if d < TOLERANCE: v.select = True velected += 1 if velected != 0: bpy.ops.object.mode_set(mode="EDIT") bpy.ops.mesh.merge(type='CENTER') bpy.ops.mesh.select_all(action="DESELECT") bpy.ops.object.mode_set(mode="OBJECT") print( "merge done at", p.x, p.y, p.z, "vertex:", velected, "count:", mcount, "/", len(VMERGEPOS) ) MERGED_COUNT += velected mcount += 1 print( "total:", MERGED_COUNT, "vertices have been merged" )