KeyError: bpy_prop_collection[key]: key "Cylinder"

Scripting in Blender with Python, and working on the API

Moderators: jesterKing, stiv

Seibold
Posts: 2
Joined: Sat Feb 09, 2013 12:09 pm

KeyError: bpy_prop_collection[key]: key "Cylinder"

Postby Seibold » Thu Apr 18, 2013 8:31 pm

hey :)

I try to export the vertices, normals and uv. I do not know whats going wrong with my export script. Sometimes it works well but now i get the error:
KeyError: bpy_prop_collection[key]: key "Cylinder" not found
?
how can i fix the problem?

This is my simple code


the error is here: me = bpy.data.meshes[bpy.context.active_object.name]

Code: Select all

import bpy

def writeString(file, string):
   file.write(bytes(string, 'UTF-8'))
   
filepath = 'D:\JackyFlasche.h'

file = open(filepath, "wb")

if bpy.app.version[0] < 2 or bpy.app.version[1] < 62:
        raise Exception("only for Blender 2.62 and above")
   
bpy.ops.object.mode_set(mode='OBJECT') # Can't access cprdinate date in edit mode currently
me = bpy.data.meshes[bpy.context.active_object.name]

count = 0
for f in me.polygons:
   for i in f.loop_indices:
      for j,ul in enumerate(me.uv_layers):
         count = count + 1
            
writeString(file, '\n#define kObjectNumberOfVertices %d\n' % ( count ))
writeString(file, '\n')
writeString(file, '@implmentation %s\n' % ( bpy.context.active_object.name ))
writeString(file, '\n')
writeString(file, '-(id)init{\n')
writeString(file, '\tstatic TexturedVertexData3D ObjectVertexData[] = {\n')

for f in me.polygons:
   for i in f.loop_indices:
      l = me.loops[i]
      vert = me.vertices[l.vertex_index]
      # print(v.co.x, v.co.y, v.co.z)
      for j,ul in enumerate(me.uv_layers):
         writeString(file, '\t\t{/*v:*/{%F, %F, %F}, ' % (vert.co.x, vert.co.y, vert.co.z) )
         writeString(file, '/*n:*/{%F, %F, %F}, ' % (vert.normal.x, vert.normal.y, vert.normal.z))
         writeString(file, '/*t:*/{%F, %F}' % (ul.data[l.index].uv.x, ul.data[l.index].uv.y ) )
         writeString(file, '},\n')
writeString(file, '\t};\n')
writeString(file, '};\n')
   
file.flush()
file.close()

CoDEmanX
Posts: 894
Joined: Sun Apr 05, 2009 7:42 pm
Location: Germany

Postby CoDEmanX » Fri Apr 19, 2013 12:53 am

Okay, here comes your code review ;)

this is a really bad idea:

Code: Select all

me = bpy.data.meshes[bpy.context.active_object.name]

1. The script makes the assumption, that there's always a Mesh with a certain name
2. It looks for a Mesh with the same name as the active object (which is a completely different ID datablock type)
3. The active object is the object the user (de-)selected last, so it depends on the current context

if you want to export only the active object of type mesh, do:

Code: Select all

ob = bpy.context.object
if ob is None or ob.type == 'MESH':
    print("Need an active Mesh object!")
else:
    me = ob.data


Or if you want to export a mesh object with a certain name:

Code: Select all

ob = bpy.data.objects.get("Cylinder")
if ob is not None and ob.type == 'MESH':
    print("Object %s - Mesh %s" % (ob.name, ob.data.name))



You can do simpler:

Code: Select all

if bpy.app.version[0] < 2 or bpy.app.version[1] < 62:
        raise Exception("only for Blender 2.62 and above")

if bpy.app.version < (2,62): ...



Not sure what you count here:

Code: Select all

count = 0
for f in me.polygons:
   for i in f.loop_indices:
      for j,ul in enumerate(me.uv_layers):
         count = count + 1


It should be fine to use either of these:

Code: Select all

len(me.loops)
len(me.uv_layers.active.data)



No need to enumerate if you don't use "j" anywhere...

Code: Select all

      for j,ul in enumerate(me.uv_layers):  ...

# rather:
for ul in me.uv_layers: ...



It's a little easier to use slide syntax to avoid ...x, ...y, ...z:

Code: Select all

         writeString(file, '\t\t{/*v:*/{%F, %F, %F}, ' % (vert.co.x, vert.co.y, vert.co.z) )
         writeString(file, '/*n:*/{%F, %F, %F}, ' % (vert.normal.x, vert.normal.y, vert.normal.z))
         writeString(file, '/*t:*/{%F, %F}' % (ul.data[l.index].uv.x, ul.data[l.index].uv.y ) )

         writeString(file, '\t\t{/*v:*/{%F, %F, %F}, ' % vert.co[:])
         writeString(file, '/*n:*/{%F, %F, %F}, ' % vert.normal[:])
         writeString(file, '/*t:*/{%F, %F}' % ul.data[l.index].uv[:])

# Special case: Vector objects define __repr__() and __str__(), printing their components
#print(v.co)



I bet python flushes automatically if you close file:

Code: Select all

file.flush() # superfluous
file.close()
I'm sitting, waiting, wishing, building Blender in superstition...


Return to “Python”

Who is online

Users browsing this forum: No registered users and 1 guest