Saturday, September 7, 2019

some intro blender python scripting tips

Hi,
i'm still very new to blender scripting but thought some of these tips might be helpful.

if coming from maya, bpy is kindof like maya's cmds.
also instead of like maya's cmds.Function(params) to do things.
blender scripts uses things like bpy.data, bpy.context, bpy.ops ... there are also lots of use of python dictionaries.
i found it very helpful to google things like 'blender bpy import obj' to find function examples to import objs.

here are some helpful tips when starting blender scripting related to setting up ui etc:
in terminal ‘blender’ , so can see what we print
ctrl+spacebar — to auto complete in python console
command+left/right - to go to beginning/end of line in console
console > bpy.app.debug = True > n panel >mesh display > checkbox indices - display mesh vertex index
-no parenthesis
- use of ‘.’
can learn function by manually making a cube and reading command from ‘info’ panel.
can find more info on parameters by search google ex: ‘blender primitive_cube_add’
command+click command c — to copy info editor line (command + click) to deselect
shift+tab - to remove added tab in console
arrows top left corner> show text editor, click view duplicate view to new window.
arrows top left corner> show python console
ui related info > ex: type bpy.props.FloatProperty then ctrl+spacebar to read args
so far i tried the layout setup with ‘info’ panel open on left, ‘text editor’ panel on upper right, ‘python console’ on upper left.

 
the couple of examples here could possibly relate to facial or prop rigging.
The first example relates to constructing shapekey (blendshapes) given multiple meshes.
the second couple examples relate to importing a blender file or obj mesh. this could be useful in an auto rigging script.

#introShapeKeyPipe.py
#snippets for creating shapekeys/blendshapes given meshes in scene
"""
#run in blender python editor
import sys

#change path to directory where script is saved
sys.path.append('/Users/Nathaniel/Documents/src_blender/python/snippets/pipeTools')

#python file named introShapeKeyPipe.py 
import introShapeKeyPipe as mod
import imp
imp.reload(mod)

mod.makeShapeKeyFromMultipleMeshes()
"""

#manually
#-select base mesh
#-in data menu, click +
#-select all shapes then last base mesh
#-down arrow join as shapes

import bpy

def makeShapeKeyFromMultipleMeshes():
    
    #Change these:
    baseMesh = 'nozo_default'
    shapes = ['nozo_side','nozo_up']

    #check all meshes exist in scene
    checkList = shapes
    checkList.append(baseMesh)
    if any(  [x for x in checkList if bpy.data.objects.get(x) is None ]  ):
        print('could not find all meshes to work on in scene')
        return
        
    #make base shape key
    #active object base mesh
    bpy.context.scene.objects.active= bpy.data.objects[baseMesh]
    bpy.data.objects[baseMesh].select = True
    bpy.ops.object.shape_key_add(from_mix=False)
    
    #select all shapes
    for shap in shapes:
        bpy.data.objects[shap].select = True
        
    #add shapes to base mesh shape key
    bpy.ops.object.join_shapes()

    #deselect all shapes
    for shap in shapes:
        bpy.data.objects[shap].select = False    

#inspired by:
#https://blender.stackexchange.com/questions/38618/selecting-an-object-via-scripting
#https://blenderartists.org/t/how-to-test-if-an-object-exists/566990


and some importing related examples:

#snippets for importing .blend file / .obj file
"""need imp to reload script
import sys
sys.path.append('/Users/Nathaniel/Documents/src_blender/python/snippets/pipeTools')

import importGeo as mod
import imp
imp.reload(mod)
#mod.importBlend()
mod.importObj()
"""

import bpy
import os

def importBlend():
    #CHANGE .blend file name here
    fileName = '/Users/Nathaniel/Documents/src_blender/python/snippets/pipeTools/nozo_geo.blend'
    
    #append objects
    with bpy.data.libraries.load(fileName) as (data_from, data_to):
        data_to.objects = [n for n in data_from.objects]
    
    #link objects to scene
    scene = bpy.context.scene
    for obj in data_to.objects:
        if obj is not None:
            print('linking object %s' %(obj.name))
            scene.objects.link(obj)

def importObj():
   
    #CHANGE obj directory here    
    shapeDir = '/Users/Nathaniel/Documents/src_blender/python/snippets/pipeTools'
    #CHANGE obj file names here
    fileNames = ['nozo_default.obj','nozo_up.obj','nozo_side.obj']
    toNames = ['nozo_default','nozo_up','nozo_side']
    
    #todo check all file paths exist
    
    xpos = 0
    for f,toName in zip(fileNames,toNames):
        fileName = os.path.join(shapeDir,f) #todo check obj file path exists
        importedObj = bpy.ops.import_scene.obj(filepath = fileName)
        obj = bpy.context.selected_objects[0]
        obj.location = (xpos,0,0)
        obj.name = toName
        obj.data.name = toName
        xpos += 5
    

#bpy.context.scene.objects[0].name
#'nozo_geo'

#inspired by:
#https://blender.stackexchange.com/questions/75746/import-multiple-objects-using-python
#https://blender.stackexchange.com/questions/72928/blender-2-78-obj-import-via-script


 hope you find these examples helpful for beginning to learn blender python scripting.

and some doodles:






i was really inspired by story work of:
Didier Ah-Koon
didierahkoon dot blogspot dot com
and
Jeff Call
jeffisnotartsyfartsy dot blogspot dot com
jeffisnotart dot blogspot dot com


Happy Sketching!
Nate