Jump to: navigation, search

Difference between revisions of "Pyhton Scripts"

(GlueVertices)
(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 ):
    """
 
    return: float. Distance of the two vertices
 
    """
 
 
     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 to console, DEBUG
+
     #print(distance)
 
     return distance
 
     return distance
 
   
 
   
  def doMerge( vs ):
+
  def getDistance2Vector( vertex, vector ):
     global TOLERANCE
+
     distance = sqrt( (vertex.co[0] - vector.x)**2 + (vertex.co[1] - vector.y)**2 + (vertex.co[2] - vector.z)**2)
    global MERGED_COUNT
+
    #print(distance)
    vnum = len( vs )
+
     return distance
    for i in range( 0, vnum ):
+
        v = vs[ i ]
+
        for j in range( i + 1, vnum ):
+
            vo = vs[ j ]
+
            if v is not vo:
+
                d = getDistance( v, vo )
+
                if d  < TOLERANCE:
+
                    v.select = True
+
                    vo.select = True
+
                    print( "merging vertices at", v.co, "and", vo.co )
+
                    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")
+
                    MERGED_COUNT += 1
+
                    return True
+
     return False
+
 
   
 
   
 
  obj = context.active_object
 
  obj = context.active_object
 
  print( "scanning", obj.data.vertices, "vertices" )
 
  print( "scanning", obj.data.vertices, "vertices" )
 
   
 
   
  vpot = obj.data.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")
 
   
 
   
  # seek vertices at the same position
+
  mcount = 0
   
+
  for p in VMERGEPOS:
while doMerge( vpot ):
+
    vall = obj.data.vertices
     print( MERGED_COUNT )
+
    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 21:42, 8 April 2016

Python scripts vault used during the project.

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 )

script on github

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 )

script on github

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 )

script on github

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)

script on github

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" )

script on github