3D Software - Blender Import Obj Files

In order to help importing characters into Blender I have modified the obj import script that comes with Blender. I made the following changes:

The modified user interface is:

blender obj import

The modified script is here: import_obj_mod.py. (<-right click and save as file) if that does not work download as a text file and rename to .py: import_obj_mod.txt.

Here is an overview of code changes:

new procedures

new procedures to create vertex groups:

#####################################################
# creates array of vertex groups
#####################################################
def create_vg(verts_loc, faces):
     '''
     returns an array of vert_group
     each vert group has name and integer array.
     '''
   
     vert_groups= []
     thisGroup= []
     indexArray=[]
   
     oldname= -1 # initialize to a value that will never match the key
   
     for face in faces:
     name=face[4]
     if oldname == name: # append to current name.
     for f in face[0]: appendUnique(indexArray,f)
     # print '\nappending "%s"' % face[0]
     else: # start new name.
     if oldname!= -1:
     thisGroup= []
     thisGroup.append(enforceNameConventions(oldname))
     thisGroup.append(indexArray)
     vert_groups.append(thisGroup)
     #print '\nadding vertex group ',oldname,indexArray
     oldname= name
     indexArray=[]
     for f in face[0]: appendUnique(indexArray,f)
     thisGroup= []
     thisGroup.append(enforceNameConventions(name))
     thisGroup.append(indexArray)
     vert_groups.append(thisGroup)
     #print '\nadding vertex group "%s"' % name
     return vert_groups
################################################
     # enforce name conventions
     # in blender left and right armatures end with _L and _R
     ################################################
     def enforceNameConventions(name):
     newname=name
     if name.find('left') != -1:
     newname=name.replace('left','')+'_L'
     elif name.find('Left') != -1: newname=name.replace('Left','')+'_L'
     elif name.find('right') != -1: newname=name.replace('right','')+'_R'
     elif name.find('Right') != -1: newname=name.replace('Right','')+'_R'
     elif name.startswith('R'): newname=name.replace('R','',1)+'_R'
     elif name.startswith('r'): newname=name.replace('r','',1)+'_R'
     elif name.startswith('L'): newname=name.replace('L','',1)+'_L'
     elif name.startswith('l'): newname=name.replace('l','',1)+'_L'
     newname=newname.replace(' ','_')
     print '\nreplacing ',name,' with ',newname
     return newname
################################################
     # append if not already in array
     ################################################
     def appendUnique(array,newItem):
     for item in array:
     if item == newItem: return
     array.append(newItem)
     # print 'appendUnigue',newItem
     return

Modify create_mesh

We pass vert_groups to create_mesh

################################################
# create mesh
################################################
def create_mesh(scn, new_objects, has_ngons, CREATE_FGONS,
	    CREATE_EDGES, verts_loc, verts_tex, faces, unique_materials, u
        nique_material_images, unique_smooth_groups, 
        dataname, vert_groups):

and we use this to add the vertex groups to the mesh:

     
     ob= scn.objects.new(me)
     if vert_groups != None:
     for vert_group in vert_groups:
     #print '\nabout to add vertex group "%s"' % vert_group[0]
     #print '\nindexes "%s"' % vert_group[1]
     me.addVertGroup(vert_group[0])
     me.assignVertsToGroup(vert_group[0],vert_group[1],
        0.5,Mesh.AssignModes.REPLACE)
    new_objects.append(ob)

The vertex groups are created in the create_mesh

     # Create meshes from the data
     create_mesh(scn, new_objects, has_ngons, CREATE_FGONS, CREATE_EDGES,
    verts_loc_split, verts_tex, faces_split, unique_materials_split,
    unique_material_images, unique_smooth_groups, dataname, vert_groups)

The scaling is changed as follows:

     
     axis_min= [ 1000000000]*3
     axis_max= [-1000000000]*3
     
     if ENABLE_SCALE: 
     # Scale objects
     scale= SCALE_SIZE
     
     for ob in new_objects:
     ob.setSize(scale, scale, scale)
     
     if ENABLE_CLAMP:
     # Get all object bounds
     for ob in new_objects:
     for v in ob.getBoundBox():
     for axis, value in enumerate(v):
     if axis_min[axis] > value:	axis_min[axis]= value
     if axis_max[axis] < value:	axis_max[axis]= value
     
     # Scale objects
     max_axis= max(axis_max[0]-axis_min[0], axis_max[1]-axis_min[1],
           axis_max[2]-axis_min[2])
     scale= 1.0
     
     while CLAMP_SIZE < max_axis * scale:
     scale= scale/10.0
     
     for ob in new_objects:
     ob.setSize(scale, scale, scale)
   

Changes to load_obj_ui

The user interface changes are made to load_obj_ui as follows:

     CREATE_SMOOTH_GROUPS= Draw.Create(0)
     CREATE_FGONS= Draw.Create(1)
     CREATE_EDGES= Draw.Create(1)
     SPLIT_OBJECTS= Draw.Create(0)
     SPLIT_GROUPS= Draw.Create(0)
     SPLIT_VERTS= Draw.Create(1)
     SPLIT_MATERIALS= Draw.Create(0)
     MORPH_TARGET= Draw.Create(0)
     IMAGE_SEARCH= Draw.Create(1)
     ENFORCE_CONVENTIONS= Draw.Create(0)
     ENABLE_SCALE= Draw.Create(0)
     SCALE_SIZE= Draw.Create(5.0)
     ENABLE_CLAMP= Draw.Create(0)
     CLAMP_SIZE= Draw.Create(10.0) 
     
     # Get USER Options
     pup_block= [\
     'Import...',\
     ('Create FGons', CREATE_FGONS, 'Import faces with more then 4 verts as fgons.'),\
     ('Lines', CREATE_EDGES, 'Import lines and faces with 2 verts as edges'),\
     'Separate objects from obj...',\
     ('Object', SPLIT_OBJECTS, 'Import OBJ Objects into Blender Objects'),\
     ('Group', SPLIT_GROUPS, 'Import OBJ Groups into Blender Objects'),\
     ('Vert', SPLIT_VERTS, 'Import OBJ Groups into vertex groups'),\
     ('Material', SPLIT_MATERIALS, 'Import each material into a seperate mesh
             (Avoids > 16 per mesh error)'),\
     'Options...',\
     ('Morph Target', MORPH_TARGET, 'Keep vert and face order, disables some other options.'),\
     ('Image Search', IMAGE_SEARCH, 'Search subdirs for any assosiated images
               (Warning, may be slow)'),\
     ('Enforce names', ENFORCE_CONVENTIONS, 'enforce naming conventions
            like _L and _R for left and right'),\
     ('Smooth Groups', CREATE_SMOOTH_GROUPS, 'Surround smooth groups by sharp edges'),\
     ' ',\
     ' ',\
     ' ',\
     'Scaling...',\
     ('Enable Scale', ENABLE_SCALE, 'enable a fixed scale factor'),\
     ('Scale Size:', SCALE_SIZE, 0.0, 1000.0, 'scale factor'),\
     ('Enable Clamp', ENABLE_CLAMP, 'enable clamp factor'),\
     ('Clamp Scale:', CLAMP_SIZE, 0.0, 1000.0, 'Clamp the size to
              this maximum - divide by 10 until it is'),\
     ]
     
     if not Draw.PupBlock('Import OBJ...', pup_block):
     return
     
     if MORPH_TARGET.val:
     SPLIT_OBJECTS.val = False
     SPLIT_GROUPS.val = False
     SPLIT_VERTS.val = False
     SPLIT_MATERIALS.val = False
     
     Window.WaitCursor(1)
     
     if BATCH_LOAD: # load the dir
     try:
     files= [ f for f in os.listdir(filepath) if f.lower().endswith('.obj') ]
     except:
     Window.WaitCursor(0)
     Draw.PupMenu('Error%t|Could not open path ' + filepath)
     return
     
     if not files:
     Window.WaitCursor(0)
     Draw.PupMenu('Error%t|No files at path ' + filepath)
     return
     
     for f in files:
     scn= bpy.data.scenes.new( stripExt(f) )
     scn.makeCurrent()
     
     load_obj(sys.join(filepath, f),\
     CLAMP_SIZE.val,\
     CREATE_FGONS.val,\
     CREATE_SMOOTH_GROUPS.val,\
     CREATE_EDGES.val,\
     SPLIT_OBJECTS.val,\
     SPLIT_GROUPS.val,\
     SPLIT_VERTS.val,\
     SPLIT_MATERIALS.val,\
     IMAGE_SEARCH.val,\
     ENFORCE_CONVENTIONS.val,\
     ENABLE_SCALE.val,\
     SCALE_SIZE.val,\
     ENABLE_CLAMP.val,\
     )
     
     else: # Normal load
     load_obj(filepath,\
     CLAMP_SIZE.val,\
     CREATE_FGONS.val,\
     CREATE_SMOOTH_GROUPS.val,\
     CREATE_EDGES.val,\
     SPLIT_OBJECTS.val,\
     SPLIT_GROUPS.val,\
     SPLIT_VERTS.val,\
     SPLIT_MATERIALS.val,\
     IMAGE_SEARCH.val,\
     ENFORCE_CONVENTIONS.val,\
     ENABLE_SCALE.val,\
     SCALE_SIZE.val,\
     ENABLE_CLAMP.val,\
     )
     
     Window.WaitCursor(0)
   

metadata block
see also:
Correspondence about this page

Book Shop - Further reading.

Where I can, I have put links to Amazon for books that are relevant to the subject, click on the appropriate country flag to get more details of the book or to buy it from them.

cover Introducing Character Animation with Blender. This is a detailed and well written book, however 3D character animation is a big subject and blender has a very steep learning curve. Those new to Blender will probably need other sources of information to get you started. Also this book can't teach you the anatomy and artistic side of the subject.

Commercial Software Shop

Where I can, I have put links to Amazon for commercial software, not directly related to this site, but related to the subject being discussed, click on the appropriate country flag to get more details of the software or to buy it from them.

cover Poser 7 - Allows you to animate the provided human / animal models

This site may have errors. Don't use for critical systems.

Copyright (c) 1998-2014 Martin John Baker - All rights reserved - privacy policy.