OBJ Import and vertex groups

edit: the fix is further down
(I have an ugly hack to do this manually with IDLE.
the interesting part would be the next post)

problem: OBJ import loses set membership list. (for vertex groups)

the task:
assign the set membership of verts (maya) to blender vertex groups.
-take a piece of MEL code that selects a set of vertices and convert it to a piece of blender python that can be run from the text editor in Blender, so the resultant selected verts can be assigned to a vertex group - optionally, automate the assignment to vertex group(s).
OBJ vertex numbering begins at 1.
maya and blender both begin at 0.

Here’s what you get in maya when you select a set, then when you drag select the membership :
select -r -ne L_elbowSet ; // this is the set
select -r rabbit.vtx[9] rabbit.vtx[10] rabbit.vtx[11] rabbit.vtx[12] rabbit.vtx[21] rabbit.vtx[22] rabbit.vtx[23] rabbit.vtx[24] rabbit.vtx[33] rabbit.vtx[34] rabbit.vtx[36] rabbit.vtx[67] rabbit.vtx[68] rabbit.vtx[69] rabbit.vtx[80] rabbit.vtx[81] rabbit.vtx[82] rabbit.vtx[86] rabbit.vtx[87] rabbit.vtx[90] rabbit.vtx[91] rabbit.vtx[92] ;

  • a utility to take the above list of verts and put it in a form blender will be able to use to select the verts. Preferably reads a file and saves to a new file, and runs from IDLE.
  • a script to run from inside blender to select a list of verts (so I can manually create a vertex group and assign the selection to it)
    optional script to create the vertex group based on the set name; add the selected verts to the group.

in blender, I need:
? will the verts be same numbered ? // we can hope.
to work the mesh … (find how it is refered in blender)
probably have to be in edit mode
create vertex groups for the mesh
name ‘L_elbowSet’ // could be set1, etc… for all I care. They will get renamed again before I am done.
add each vert to the selection // the important part
assign the selection to the vertex group

what would be the script to select a vert based on it’s index?
add (or append) a vert to a selection?

pseudo code:

need clever name for script v1.0

extract list of values from MEL data, save to file

import Blender
replace = Blender.Mesh.AssignModes.REPLACE
mesh = rabbit.getData(mesh=True)
mesh.addVertGroup(‘renameMe’)

read the data and put it into a list

vertList = [] # list of integers

mesh.assignVertsToGroup(‘renameMe’, vertList, 1.0, replace)

Of course the better option would be to redo the OBJ importer, of which there are legends but scant signs of a fixed version.

looking at import_obj.py
…create_mesh…
line 545


# Create the vertex groups. No need to have the flag passed here since we test for the 
# content of the vertex_groups. If the user selects to NOT have vertex groups saved then
# the following test will never run
for group_name, group_indicies in vertex_groups.iteritems():
 me.addVertGroup(group_name)
 me.assignVertsToGroup(group_name, group_indicies,1.00, Mesh.AssignModes.REPLACE)

Unfortunately, the only group that will get verts assigned is the last one in the OBJ file-
the mesh name in my case.
…load_obj…
line 727


if line.startswith('v '):
 line_split= line.split()
 # rotate X90: (x,-z,y)
 verts_loc.append( (float_func(line_split[1]), -float_func(line_split[3]), float_func(line_split[2])) )

ok it has a vert. it will either do this again for the next line, close the file, or some of the following:
line 741


elif line.startswith('f') or context_multi_line == 'f':


I am assuming context_multi_line is supposed to track blocks of lines beginning with ‘f’
line 761


if strip_slash(line_split):
 context_multi_line = 'f'
else:
 context_multi_line = ''

my assumption is probably incorrect.
line 770


# Add the vertex to the current group
# *warning*, this wont work for files that have groups defined around verts
if POLYGROUPS and context_vgroup:
 vertex_groups[context_vgroup].append(vert_loc_index)

This code piece is outside of the part that looks for groups on the OBJ file.
line 848


elif line.startswith('g'):
 if SPLIT_GROUPS:
  context_object= line_value(line.split())
  # print 'context_object', context_object
  # unique_obects[context_object]= None
 elif POLYGROUPS:
  context_vgroup = line_value(line.split())
  if context_vgroup and context_vgroup != '(null)':
   vertex_groups.setdefault(context_vgroup, [])
  else:
   context_vgroup = None # dont assign a vgroup

This seems to save the name of a group.
Perhaps the setdefault makes the group the default vert group, then the next group to appear becomes the default -
which could explain why only the last group in the OBJ file is getting all the vertices.

mesh (with sets) exported from maya as OBJ
set names are not too complicated - spaces and other crap may mess this up.
for my OBJ files, or if your OBJ files is in format:
g groupname(a)
v vertdata
v vert data
g groupname(b)
v
v
g another group name ( could be repeats)
etc…
the following should import the OBJ with the OBJ’s groups converted into vertex groups
note:
Keep vert order
Poly groups
image search (optional)
on, all others OFF

copy import_obj.py
change filename to import_DOG_obj.py

modify lines where create_mesh is defined and called to include filepath
335 and 956(if new code allready pasted 988)
def create_mesh(filepath, # etc

line 4: to distinguish from import_obj
Name: ‘DOG Wavefront (.obj)…’

code to look for at lines 545-550


 # Create the vertex groups. No need to have the flag passed here since we test for the 
 # content of the vertex_groups. If the user selects to NOT have vertex groups saved then
 # the following test will never run
 for group_name, group_indicies in vertex_groups.iteritems():
  me.addVertGroup(group_name)
  me.assignVertsToGroup(group_name, group_indicies,1.00, Mesh.AssignModes.REPLACE)

add at line 551, after the existing code for vertex groups


 # DOG  vertex groups
 if POLYGROUPS :
  # go through the file from the start
  file= open(filepath, 'rU') # from line 723
  groupname = ''
  # start index counter at 0
  vindex = 0
  for line in file: #.xreadlines(): # get the next line
    line = line.lstrip() # rare cases there is white space at the start of the line
    if line.startswith('g'): # is the line a group?
     # find out the group name, make it the current group
 
     groupline = line.split()
     groupname = groupline[1]
    elif line.startswith('v '): # is the line a vertice?
     # check for a current group
     if groupname : # probably need error check for screwy names, names with spaces etc.
      # add the index to the current group
      vList =[] # avoid a type error
      vList.append(vindex)
      # print '
', groupname, ' ', vList, '
'
      me.assignVertsToGroup(groupname, vList, 1.00, Mesh.AssignModes.ADD)
     # increment the index
     vindex += 1
 
    # would be nice to check for obvious end of possible vertex groups
    # if the line is anything else
     # do nothing
 
  file.close()

save in scripts directory