Введение в написание скриптов на Питоне для Блендера 2.5x. Примеры кода - страница 36
Больше конструкций, например, для настройки материала или групп граней, имеются в полноценном экспортёре-импортёре OBJ-формата.
Есть две вещи, которые надо принять во внимание. Во-первых, большинство приложений (насколько мне известно, все, кроме Блендера) используют соглашение, что ось >Y
указывает вверх, в то время как Блендер использует ось >Z
для направления вверх. Во-вторых, Майя начинает подсчет вершин с >1
, тогда как Блендер начинает отсчет от >0
. Это означает, что углы граней на самом деле расположены в вершинах >v>1-1, v>2-1, ... v>n-1
в 3D-пространстве и в >vt>1-1, vt>2-1, ... vt>n-1
в пространстве текстур.
Простой экспортёр-импортёр OBJ-файлов — это пакет Питона, который состоит из трех файлов: два файла, которые фактически выполняют работу экспорта/импорта, и >__init__.py
, который делает каталог пакетом.
Простой экспорт OBJ-файлов
Этот скрипт экспортирует выбранный меш как OBJ-файл.
>#----------------------------------------------------------
># File export_simple_obj.py
># Простой OBJ-экспортёр, который записывает только вершины, грани и текстурные вершины
>#----------------------------------------------------------
>import bpy, os
>def export_simple_obj(filepath, ob, rot90, scale):
> name = os.path.basename(filepath)
> realpath = os.path.realpath(os.path.expanduser(filepath))
> fp = open(realpath, 'w')
> print('Exporting %s' % realpath)
> if not ob or ob.type != 'MESH':
> raise NameError('Cannot export: active object %s is not a mesh.' % ob)
> me = ob.data
> for v in me.vertices:
> x = scale*v.co
> if rot90:
> fp.write("v %.5f %.5f %.5f\n" % (x[0], x[2], -x[1]))
> else:
> fp.write("v %.5f %.5f %.5f\n" % (x[0], x[1], x[2]))
> if len(me.uv_textures) > 0:
> uvtex = me.uv_textures[0]
> for f in me.faces:
> data = uvtex.data[f.index]
> fp.write("vt %.5f %.5f\n" % (data.uv1[0], data.uv1[1]))
> fp.write("vt %.5f %.5f\n" % (data.uv2[0], data.uv2[1]))
> fp.write("vt %.5f %.5f\n" % (data.uv3[0], data.uv3[1]))
> if len(f.vertices) == 4:
> fp.write("vt %.5f %.5f\n" % (data.uv4[0], data.uv4[1]))
> vt = 1
> for f in me.faces:
> vs = f.vertices
> fp.write("f %d/%d %d/%d %d/%d" % (vs[0]+1, vt, vs[1]+1, vt+1, vs[2]+1, vt+2))
> vt += 3
> if len(f.vertices) == 4:
> fp.write(" %d/%d\n" % (vs[3]+1, vt))
> vt += 1
> else:
> fp.write("\n")
> else:
> for f in me.faces:
> vs = f.vertices
> fp.write("f %d %d %d" % (vs[0]+1, vs[1]+1, vs[2]+1))
> if len(f.vertices) == 4:
> fp.write(" %d\n" % (vs[3]+1))
> else:
> fp.write("\n")
> print('%s successfully exported' % realpath)
> fp.close()
> return
Простой импорт OBJ-файлов
Этот скрипт импорта — компаньон предыдущего. Он, конечно, также может использоваться для импорта OBJ-файлов из других приложений.
>#----------------------------------------------------------
># File import_simple_obj.py
># Простой OBJ-импортёр, который читает только вершины, грани и текстурные вершины
>#----------------------------------------------------------
>import bpy, os
>def import_simple_obj(filepath, rot90, scale):
> name = os.path.basename(filepath)
> realpath = os.path.realpath(os.path.expanduser(filepath))
> fp = open(realpath, 'rU')
># Universal read
> print('Importing %s' % realpath)
> verts = []
> faces = []
> texverts = []
> texfaces = []
> for line in fp:
> words = line.split()
> if len(words) == 0:
> pass
> elif words[0] == 'v':
> (x,y,z) = (float(words[1]), float(words[2]), float(words[3]))
> if rot90:
> verts.append( (scale*x, -scale*z, scale*y) )
> else:
> verts.append( (scale*x, scale*y, scale*z) )
> elif words[0] == 'vt':
> texverts.append( (float(words[1]), float(words[2])) )
> elif words[0] == 'f':
> (f,tf) = parseFace(words)
> faces.append(f)
> if tf: