Can't get plugin to work

A friendly guy sent me a Python script (see code below) which is supposed export meshes to glVertex3f(x,y,z); lines.
But I can’t get the script to work, I am new to blender, and have never touched python.
To run the script i opened a new text-window (Shift-F11), and opened the script by selecting “Open new”, i then tried running the script with Alt+P, but nothing happened. The output to console was:


  File "<string>", line 103
    file.write("  glEnd();

")
       ^
SyntaxError: invalid syntax

I’m running Gentoo GNU/LInux 1.4rc1 (2.4.19), and the precompiled blender 2.25 (tried 2.23 as well).
My python version is:
Python 2.2.1 (#1, Oct 3 2002, 23:04:23)
[GCC 3.2] on linux2

But it seems like blender is using version 2.0(?), the script
import sys
sys.version

gives the output:

2.0 (#1, Mar 5 2001, 15:53:21)
[GCC 2.95.2 19991024 (release)]

Really hope someone is able to help… :-?

The script’s source:


import math
import Blender210
import GUI

# GL Export v1.0 by
# Rogerio Mazakina
# [email protected]
# http://dway.cjb.net
# Please do not edit this header

# press Alt+P to exec
# then choose the name of the file
# that will be exported
# See readme.txt for more information

def getNormal(A,B,C):
    M_ax = M_ay = M_az = 0
    M_bx = M_by = M_bz = 0
    M_nx = M_ny = M_nz = 0
    M_Len = 0

    M_ax = B[0] - A[0]
    M_ay = B[1] - A[1]
    M_az = B[2] - A[2]

    M_bx = C[0] - A[0]
    M_by = C[1] - A[1]
    M_bz = C[2] - A[2]

    M_nx = (M_ay * M_bz) - (M_by * M_az)
    M_ny = (M_az * M_bx) - (M_bz * M_ax)
    M_nz = (M_ax * M_by) - (M_bx * M_ay)
# get length of normal
    M_Len = (M_nx * M_nx) + (M_ny * M_ny) + (M_nz * M_nz)

    if M_Len < 0:
        M_Len = math.sqrt(-M_Len)
        M_Len = -M_len
    elif M_Len > 0: M_Len = math.sqrt(M_Len)
# normalize the normal
    if M_Len != 0:
        M_nx = M_nx/M_Len
        M_ny = M_ny/M_Len
        M_nz = M_nz/M_Len

    M_normal=[]
    M_normal.append(M_nx)
    M_normal.append(M_ny)
    M_normal.append(M_nz)
    return M_normal
# END OF FUNCTION getNormal(A,B,C)

print "####################################"
print "        GL file Export Script"

def GLexport(filename):
  model = ""
  filename = filename+".c"
  file = open(filename,"w")
  scene = Blender210.getCurrentScene()

  for names in scene.objects:
      obj = Blender210.getObject(names)
      if obj.type == "Mesh":
          mesh = Blender210.getMesh(obj.data)
          model = obj.data
          break

  print " Exporting %s now." %model

  file.write("void model()
{
")
  file.write("// Object name: %s
" %model)
  file.write("// File Exported by GLexport Script.
")
  FaceIndex = 0
  for face in mesh.faces:
      if face[3] == 0: file.write("  glBegin(GL_TRIANGLES);
")
      else:            file.write("  glBegin(GL_QUADS);
")

      if face[4] == 0:
          nx,ny,nz = getNormal(mesh.vertices[face[0]],
                               mesh.vertices[face[1]],
                               mesh.vertices[face[2]])
          file.write("    glNormal3f(%3.6f, %3.6f, %3.6f);
" % (nx,ny,nz))

      vCount = 0
      for vCount in range(4):
          if vCount == 3 and face[vCount] == 0:   break

          if face[4] == 1: # if the face is Smooth
              file.write("    glNormal3f(%3.6f, %3.6f, %3.6f);
" %
                        (mesh.normals[face[vCount]][0],
                         mesh.normals[face[vCount]][1],
                         mesh.normals[face[vCount]][2] ));
          if mesh.texture: # if the mesh have texture (only UV coords)
              file.write("    glTexCoord2f(%3.6f,%3.6f);" %
                        (mesh.texcoords[FaceIndex][vCount][0],
                         mesh.texcoords[FaceIndex][vCount][1] ))
          file.write("    glVertex3f(%3.6f, %3.6f, %3.6f);
" %
                    (mesh.vertices[face[vCount]][0],
                     mesh.vertices[face[vCount]][1],
                     mesh.vertices[face[vCount]][2],)
      #} END FOR
      file.write("  glEnd();

")
      FaceIndex = FaceIndex+1
  #} END FOR FACES
  file.write("}
")
  file.close()
  print " ..."
  print " Export done!"
print "-------  END GL EXPORT.PY  ----------"

def callback():
  GLexport(fs.filename)

fs = GUI.FileSelector()
fs.activate(callback)

Replace (line 98 or so)


          file.write("    glVertex3f(%3.6f, %3.6f, %3.6f);
" %
                    (mesh.vertices[face[vCount]][0],
                     mesh.vertices[face[vCount]][1],
                     mesh.vertices[face[vCount]][2],)

with


          file.write("    glVertex3f(%3.6f, %3.6f, %3.6f);
" %
                    (mesh.vertices[face[vCount]][0],
                     mesh.vertices[face[vCount]][1],
                     mesh.vertices[face[vCount]][2]))

That should do the trick.

That is not an error, it is because python is embedded in Blender (it’s running a ‘builtin’ interpreter), which is python version 2.0.

Making progress here… :slight_smile:

The script now runs successfully in 2.23, but it doesn’t write any coordinates to the file. If i create a circle in blender an runs the script, the output-file looks like this:

void model()
{
// Object name: Circle
// File Exported by GLexport Script.
}

You probably still were in edit mode after adding the circle? Might have something to do with the Blender210 module.

On another note, a blender circle by default has no faces, so although the script does output something, it is actually not correct. The script assumes triangles or quads, while for the circle it is edges only which could be done with GL_LINES in OpenGL. GL_POINTS can be used for single vertices.

Hmmm… The script works correctly with a plane, if I leave edit mode.
But drawing with quads and triangles is quite limiting :wink:
What would be the best way to export a blender scene so I could load it in an OpenGL app? Could a script like this work?

For now, I only need the vertices in the scene, is there an easy way to just write out the coordinates of all the vertices to a file?

I really have to learn Python scripting :wink:

Of course it can work, but you will have to do the rest of the work, creating a rendering context and such, this script only exports the geometry, but it isn’t very sophisticated as it only deals with triangles or quads. Besides that, there are more optimal ways to code your meshes for OpenGL, such as using display lists.
Waffler just released some unfinished code that might be a good basis to create a script like that, see Exporter for C++ OpenGL below.

For now, I only need the vertices in the scene, is there an easy way to just write out the coordinates of all the vertices to a file?

I really have to learn Python scripting :wink:

That depends on how you want to read it in, you can write it out as binary numbers, or you could just use ascii, which makes it readable too.
Here is a very simple example of how to write all vertices of a mesh to a file:


import Blender

# The filename used to save the file
# Don't forget that you either use DOUBLE backslashes when using
# windows style file/directory names, or use a single forward slash
output_filename = 'c:\\mymeshes\\filename_here'
# alternatively: output_filename = 'c:/mymeshes/filename_here'

# get the selected objects
obs = Blender.Object.GetSelected()

# if nothing is selected, stop with an error
if len(obs)==0:
	raise "No objects selected!"

# Get the meshdata from the first selected object.
# You could of course create a loop here to write out
# all selected mesh objects.
me = obs[0].data

# write out the vertices,
# it just writes a vertex on every line as x, y, z

# first open the file for writing
file = open(output_filename, 'w')

for v in me.verts:
	file.write("%f, %f, %f
" % tuple(v.co))

# that's it, close the file
file.close()

print "Done!"