GoofosASEExporter

From The DarkMod Wiki
Jump to navigationJump to search

Blender ASE export script

This is a copy of the ASE export script for Blender written by Goofos on Doom3World.

#!BPY

"""
Name: 'ASCII Scene (.ase) v0.6.10'
Blender: 244
Group: 'Export'
Tooltip: 'ASCII Scene Export (*.ase)'
"""
__author__ = "Goofos"
__version__ = "0.6.10"
__url__ = ["http://www.doom3world.org","http://www.doom3world.org/phpbb2/viewtopic.php?f=50&t=9275&st=0&sk=t&sd=a"]
__bpydoc__ = """\
-- ASCII Scene Export (.ase) export script v0.6.10 for Blender 2.44 --<br>

Can export:<br>
-Mesh Objects<br>
-Materials and Textures (no Procedural but Image)<br>
   Note: Normalmaps will be exported as Bumpmaps (FixMe).
      Image path depends on how you have loaded it
      (absolute path's looks better :))
   Currently supported: Amb, Col, Csp, Hard, Alpha, Nor, Disp<br>
-Vertex Colors<br>
   Note: If the mesh has materials you must enable "Vcol Paint"
   in Material tab. Without Materials, make sure "VertCol"
   in Mesh tab is enabled. Seems like the ASE Format doesn't
   support multiple Vertex Color layers.<br>
-Face UV<br>
   Make sure "TexFace" in Mesh tab is enabled.
   Multi UV layers are now supported<br>
-Solid or Smooth Faces<br>
   ... smoothgroups currently only with a workaround. Solid
   faces will not have a smoothgroup, smooth faces will be by default in
   smoothgroup 1.<br>

-- Export Options Description --<br>
Apply Modifiers: Export the mesh with applied modifiers.
   Note: This uses the render settings of the modifiers.<br>
Materials: Export Materials if any.<br>
Face UV: Export TexFace UV if any. The current active UV Layer will be used
   as the first mapping channel.<br>
Vertex Colors: Export Vertex Colors if any (See note above). The
   current VC Layer will be used.<br>
Selection Only: Export only selected Objects or if nothing is selected
   all Objects.<br>
VertGr. as SmoothGr.: You can export SmoothGroups defined by
   VertexGroups. Simply create a VertGroup and name it "smooth." plus
   a group number, e.g. "smooth.2". Please note that you should not use
   more than 32 smoothgroups!
   Vertex Normals currently might not calculated right!!
   And there is a simple problem, if you add e.g. 3 faces of a cube
   to a smoothgroup, all 6 faces will be in the smoothgroup!! This is
   because the verts of the other 3 faces are in that group, too.
   You can see this if you select the vertexgroup.<br>
Center Objects: Move all objects to the World Grid Center.
"""
# goofos
#
# ***** BEGIN GPL LICENSE BLOCK *****
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
# ***** END GPL LICENCE BLOCK *****

import Blender, time, math, sys as osSys #os
from Blender import sys, Window, Draw, Scene, Mesh, Material, Texture, Image, Mathutils

#============================================
#           Write!
#============================================

def write(filename):
   start = time.clock()
   print_boxed('---------Start of Export------------')
   print 'Export Path: ' + filename

   global exp_list, Tab, idnt, imgTable, worldTable

   exp_list =[]
   Tab = "\t"
   idnt = 1
   matTable = {}
   worldTable = {'ambR': 0.0, 'ambG': 0.0, 'ambB': 0.0, 'horR': 0.0, 'horG': 0.0, 'horB': 0.0} #default
   total = {'Verts': 0, 'Tris': 0, 'Faces': 0}
   
   scn = Blender.Scene.GetCurrent()

   set_up(scn, exp_list, matTable, worldTable)
   if not exp_list:
      #if there is nothing to export, end here
      return

   file = open(filename, "w")
   write_header(file, filename, scn, worldTable)
   write_materials(file, exp_list, worldTable, matTable)
   write_mesh(file, scn, exp_list, matTable, total)
   file.close()
   
   Blender.Window.DrawProgressBar(0, "")    # clear progressbar
   end = time.clock()
   seconds = " in %.2f %s" % (end-start, "seconds")
   totals = "Verts: %i Tris: %i Faces: %i" % (total['Verts'], total['Tris'], total['Faces'])
   print_boxed(totals)
   name = filename.split('/')[-1].split('\\')[-1]
   message = "Successfully exported " + name + seconds
   #meshtools.print_boxed(message)
   print_boxed(message)


def print_boxed(text): #Copy/Paste from meshtools, only to remove the beep :)
   lines = text.splitlines()
   maxlinelen = max(map(len, lines))
   if osSys.platform[:3] == "win":
      print chr(218)+chr(196) + chr(196)*maxlinelen + chr(196)+chr(191)
      for line in lines:
         print chr(179) + ' ' + line.ljust(maxlinelen) + ' ' + chr(179)
      print chr(192)+chr(196) + chr(196)*maxlinelen + chr(196)+chr(217)
   else:
      print '+-' + '-'*maxlinelen + '-+'
      for line in lines: print '| ' + line.ljust(maxlinelen) + ' |'
      print '+-' + '-'*maxlinelen + '-+'
   #print '\a\r', # beep when done

#============================================
#           Setup
#============================================

def set_up(scn, exp_list, matTable, worldTable):
   print "Setup"
   #Get selected Objects or if none selected all Objects from the current Scene
   if scn.objects.selected and guiTable['SELO'] == 1:
      objects = scn.objects.selected
   elif scn.objects:
      objects = scn.objects
   else:
      print "No Objects"
      return

   set_lists(exp_list, objects, matTable, worldTable)


def set_lists(exp_list, objects, matTable, worldTable):
   global mat_cnt
   mat_cnt = 0
   mat_index = 0
   #exp_list = [container1 = [ [mesh], [material_ref] ],...]

   for current_obj in objects:
      container = []
      if current_obj.getType() == 'Mesh':
         container.append(current_obj)

         mat_type = 0 #1=Material, 2=UV Images
         mat_ref = []
         mesh = current_obj.data
         mats_me = mesh.materials
         mats_ob = current_obj.getMaterials(0)
         #Find used Materials by Meshes or Objects
         if guiTable['MTL'] == 1 and mats_me or mats_ob: #Materials
            if mats_me:
               me_mats = mats_me
            elif mats_ob:
               me_mats = mats_ob
            mat_ref = -1

            for i,m in matTable.iteritems():
               for mat in me_mats:
                  if mat in m:
                     for amat in me_mats:
                        if amat not in m:
                           m.append(amat)
                     mat_ref = i
                     break

            if mat_ref < 0:
               matTable[mat_index] = me_mats
               mat_ref = mat_index
               mat_cnt+=1
               mat_index+=1
         container.append(mat_ref)
         exp_list.append(container)

   #If there is a world shader get some values
   world = Blender.World.GetCurrent()
   if world != None:
      worldAmb = world.getAmb()
      worldHor = world.getHor()

      worldTable['ambR'] = worldAmb[0]
      worldTable['ambG'] = worldAmb[1]
      worldTable['ambB'] = worldAmb[2]

      worldTable['horR'] = worldHor[0]
      worldTable['horG'] = worldHor[1]
      worldTable['horB'] = worldHor[2]



#============================================
#           Header/Scene
#============================================

def write_header(file, filename, scn, worldTable):
   print "Write Header"

   context = scn.getRenderingContext()

   file.write("*3DSMAX_ASCIIEXPORT%s200\n" % (Tab))
   file.write("*COMMENT \"Exported from Blender %s - %s\"\n" % (Blender.Get('version'), time.asctime(time.localtime())))
   file.write("*SCENE {\n")
   #file.write("%s*SCENE_FILENAME \"%s\"\n" % (Tab, os.path.basename(Blender.Get('filename'))))
   name = Blender.Get('filename').split('/')[-1].split('\\')[-1] #Blender 2.44
   file.write("%s*SCENE_FILENAME \"%s\"\n" % (Tab, name))

   file.write("%s*SCENE_FIRSTFRAME %d\n" % (Tab,context.startFrame()))
   file.write("%s*SCENE_LASTFRAME %d\n" % (Tab,context.endFrame()))
   file.write("%s*SCENE_FRAMESPEED %d\n" % (Tab,context.framesPerSec()))
   file.write("%s*SCENE_TICKSPERFRAME 160\n" % (Tab)) #Blender has no Ticks?

   file.write("%s*SCENE_BACKGROUND_STATIC %.4f %.4f %.4f\n" % (Tab, worldTable['horR'], worldTable['horG'], worldTable['horB']))
   file.write("%s*SCENE_AMBIENT_STATIC %.4f %.4f %.4f\n" % (Tab, worldTable['ambR'], worldTable['ambG'], worldTable['ambB']))
   file.write("}\n")


#============================================
#           Materials
#============================================

def write_materials(file, exp_list, worldTable, matTable):
   print "Write Materials"

   file.write("*MATERIAL_LIST {\n")
   file.write("%s*MATERIAL_COUNT %s\n" % (Tab, mat_cnt))

   for i,m in matTable.iteritems():
      if len(m) == 1: # single mat
         mat_class = 'Standard'

         mats = m
         material = mats[0]
         mat_name = material.name

         file.write("%s*MATERIAL %d {\n" % ((Tab), i))

         idnt = 2
         mat_para(file, idnt, material, mat_name, mat_class, worldTable)
         mat_dummy(file, idnt)
         mat_map(file, idnt, mat_name)

         file.write("%s}\n" % (Tab))

      elif len(m) > 1: # multiple mat
         mat_class = 'Multi/Sub-Object'

         mats = m
         material = mats[0]
         mat_name = 'Multi # ' + material.name
         submat_no = len(mats)

         idnt = 2
         file.write("%s*MATERIAL %d {\n" % ((Tab), i))

         mat_para(file, idnt, material, mat_name, mat_class, worldTable)

         file.write("%s*NUMSUBMTLS %d\n" % ((Tab*idnt), submat_no))

         for submat_cnt,current_mat in enumerate(mats):
            material = current_mat
            mat_class = 'Standard'
            mat_name = material.name

            idnt = 2
            file.write("%s*SUBMATERIAL %d {\n" % ((Tab*idnt), submat_cnt))
            submat_cnt += 1

            idnt = 3
            mat_para(file, idnt, material, mat_name, mat_class, worldTable)
            mat_dummy(file, idnt)
            mat_map(file, idnt, mat_name)

            idnt = 2
            file.write("%s}\n" % (Tab*idnt))

         file.write("%s}\n" % (Tab))


   file.write("}\n")


def mat_para(file, idnt, material, mat_name, mat_class, worldTable):

   mat_amb = material.getAmb()
   mat_dif = material.getRGBCol()
   mat_specCol = material.getSpecCol()
   mat_spec = material.getSpec()
   mat_hard = material.getHardness()
   mat_alpha = 1.0000-material.getAlpha()

   file.write("%s*MATERIAL_NAME \"%s\"\n" % ((Tab*idnt), mat_name))
   file.write("%s*MATERIAL_CLASS \"%s\"\n" % ((Tab*idnt), mat_class))
   file.write("%s*MATERIAL_AMBIENT %.4f   %.4f   %.4f\n" % ((Tab*idnt), (worldTable['ambR']*mat_amb), (worldTable['ambG']*mat_amb), (worldTable['ambB']*mat_amb))) #-Usefull?
   file.write("%s*MATERIAL_DIFFUSE %.4f   %.4f   %.4f\n" % ((Tab*idnt), mat_dif[0], mat_dif[1], mat_dif[2]))
   file.write("%s*MATERIAL_SPECULAR %.4f   %.4f   %.4f\n" % ((Tab*idnt), mat_specCol[0], mat_specCol[1], mat_specCol[2]))
   file.write("%s*MATERIAL_SHINE %.4f\n" % ((Tab*idnt), mat_spec))
   file.write("%s*MATERIAL_SHINESTRENGTH %.4f\n" % ((Tab*idnt), (mat_hard/511.))) #-511 or 512?
   file.write("%s*MATERIAL_TRANSPARENCY %.4f\n" % ((Tab*idnt), mat_alpha))
   file.write("%s*MATERIAL_WIRESIZE 1.0000\n" % (Tab*idnt))


def mat_dummy(file, idnt):

   file.write("%s*MATERIAL_SHADING Blinn\n" % (Tab*idnt))
   file.write("%s*MATERIAL_XP_FALLOFF 0.0000\n" % (Tab*idnt))
   file.write("%s*MATERIAL_SELFILLUM 0.0000\n" % (Tab*idnt))
   file.write("%s*MATERIAL_FALLOFF In\n" % (Tab*idnt))
   file.write("%s*MATERIAL_XP_TYPE Filter\n" % (Tab*idnt))


def mat_map(file, idnt, mat_name):

   mapTable = {0:'*MAP_AMBIENT',1:'*MAP_DIFFUSE',2:'*MAP_SPECULAR',3:'*MAP_SHINE',4:'*MAP_SHINESTRENGTH',5:'*MAP_SELFILLUM',6:'*MAP_OPACITY',7:'*MAP_FILTERCOLOR',8:'*MAP_BUMP',9:'*MAP_REFLECT',10:'*MAP_REFRACT',11:'*MAP_REFRACT'}
   tex_list = [[],[],[],[],[],[],[],[],[],[],[],[]]

   mat = Material.Get(mat_name)
   MTexes = mat.getTextures()

   for current_MTex in MTexes:
      if current_MTex is not None:
         # MAP_SUBNO 0 = *MAP_AMBIENT
         if current_MTex.mapto & Texture.MapTo.AMB:
            map_getTex(current_MTex, 0, (current_MTex.dvar*current_MTex.varfac), tex_list)
         # MAP_SUBNO 1 = *MAP_DIFFUSE = COL = 1
         elif current_MTex.mapto & Texture.MapTo.COL:
            map_getTex(current_MTex, 1, current_MTex.colfac, tex_list)
         # MAP_SUBNO 2 = *MAP_SPECULAR (Color)= CSP or SPEC? = 4
         elif current_MTex.mapto & Texture.MapTo.CSP:
            map_getTex(current_MTex, 2, current_MTex.colfac, tex_list)
         # MAP_SUBNO 3 = *MAP_SHINE (Spec Level) = SPEC or CSP? = 32
         elif current_MTex.mapto & Texture.MapTo.SPEC:
            map_getTex(current_MTex, 3, (current_MTex.dvar*current_MTex.varfac), tex_list)
         # MAP_SUBNO 4 = *MAP_SHINESTRENGTH (Gloss) = HARD = 256
         elif current_MTex.mapto & Texture.MapTo.HARD:
            map_getTex(current_MTex, 4, (current_MTex.dvar*current_MTex.varfac), tex_list)
         # MAP_SUBNO 5 = *MAP_SELFILLUM
         # MAP_SUBNO 6 = *MAP_OPACITY = ALPHA = 128
         elif current_MTex.mapto & Texture.MapTo.ALPHA:
            map_getTex(current_MTex, 6, (current_MTex.dvar*current_MTex.varfac), tex_list)
         # MAP_SUBNO 7 = *MAP_FILTERCOLOR
         # MAP_SUBNO 8 = *MAP_BUMP = NOR = 2
         elif current_MTex.mapto & Texture.MapTo.NOR:
            map_getTex(current_MTex, 8, (current_MTex.norfac/25), tex_list)
         # MAP_SUBNO 9 = *MAP_REFLECT
         elif current_MTex.mapto & Texture.MapTo.REF:
            map_getTex(current_MTex, 9, (current_MTex.norfac/25), tex_list)
         # MAP_SUBNO 10 = *MAP_REFRACT (refraction)
         # MAP_SUBNO 11 = *MAP_REFRACT (displacement)
         elif current_MTex.mapto & Texture.MapTo.DISP:
            map_getTex(current_MTex, 11, (current_MTex.norfac/25), tex_list)

   # Write maps
   for current_LI in tex_list:
      subNo = tex_list.index(current_LI)
      for current_MTex in current_LI:
         tex = current_MTex[0].tex
         if tex.type == Texture.Types.IMAGE:
            map_image(file, idnt, current_MTex, subNo, tex, mapTable[subNo])


def map_getTex(MTex, map_subNo, map_amount, texes):
   # container = [[[MTex], [map_amount]], ...]
   container = []
   container.append(MTex)
   container.append(map_amount)
   texes[map_subNo].append(container)

         
def map_image(file, idnt, MTexCon, subNo, tex, mapType):

   img = tex.getImage()
   #path = sys.expandpath(img.getFilename()).replace('/', '\\')
   path = img.filename #or img.getFilename()
   tex_class = 'Bitmap'
   tex_mapType = 'Screen'
   tex_filter = 'Pyramidal'

   file.write("%s%s {\n" % ((Tab*idnt), mapType))

   idnt += 1
   file.write("%s*MAP_NAME \"%s\"\n" % ((Tab*idnt), tex.getName()))
   file.write("%s*MAP_CLASS \"%s\"\n" % ((Tab*idnt), tex_class))
   file.write("%s*MAP_SUBNO %s\n" % ((Tab*idnt), subNo))
   file.write("%s*MAP_AMOUNT %.4f\n" % ((Tab*idnt), MTexCon[1]))
   file.write("%s*BITMAP \"%s\"\n" % ((Tab*idnt), path))
   file.write("%s*MAP_TYPE %s\n" % ((Tab*idnt), tex_mapType))

   # hope this part is right!
   u_tiling = tex.repeat[0]*tex.crop[2]
   v_tiling = tex.repeat[1]*tex.crop[3]
   file.write("%s*UVW_U_OFFSET %.4f\n" % ((Tab*idnt), tex.crop[0]))
   file.write("%s*UVW_V_OFFSET %.4f\n" % ((Tab*idnt), tex.crop[1]))
   file.write("%s*UVW_U_TILING %.4f\n" % ((Tab*idnt), u_tiling))
   file.write("%s*UVW_V_TILING %.4f\n" % ((Tab*idnt), v_tiling))

   map_uvw(file, idnt) #hardcoded

   file.write("%s*BITMAP_FILTER %s\n" % ((Tab*idnt), tex_filter))

   idnt -= 1
   file.write("%s}\n" % (Tab*idnt))


def mat_uv(file, idnt, uv_image, uv_name, mat_class, worldTable):
   fake_val0 = '0.0000'
   fake_val1 = '0.1000'
   fake_val2 = '0.5882'
   fake_val3 = '0.9000'
   fake_val4 = '1.0000'

   file.write("%s*MATERIAL_NAME \"%s\"\n" % ((Tab*idnt), uv_name))
   file.write("%s*MATERIAL_CLASS \"%s\"\n" % ((Tab*idnt), mat_class))
   file.write("%s*MATERIAL_AMBIENT %.4f   %.4f   %.4f\n" % ((Tab*idnt), worldTable['ambR'], worldTable['ambG'], worldTable['ambB'])) #------------Usefull?
   file.write("%s*MATERIAL_DIFFUSE %s   %s   %s\n" % ((Tab*idnt), fake_val2, fake_val2, fake_val2))
   file.write("%s*MATERIAL_SPECULAR %s   %s   %s\n" % ((Tab*idnt), fake_val3, fake_val3, fake_val3))
   file.write("%s*MATERIAL_SHINE %s\n" % ((Tab*idnt), fake_val1))
   file.write("%s*MATERIAL_SHINESTRENGTH %s\n" % ((Tab*idnt), fake_val0))
   file.write("%s*MATERIAL_TRANSPARENCY %s\n" % ((Tab*idnt), fake_val0))
   file.write("%s*MATERIAL_WIRESIZE %s\n" % ((Tab*idnt), fake_val4))


def map_uv(file, idnt, uv_image, uv_name):
   map_type = '*MAP_DIFFUSE'
   map_subNo = '1'
   tex_class = 'Bitmap'
   tex_mapType = 'Screen'
   tex_filter = 'Pyramidal'

   fake_val0 = '0.0000'
   fake_val1 = '0.1000'
   fake_val2 = '0.5882'
   fake_val3 = '0.9000'
   fake_val4 = '1.0000'

   #replace "/" with "\" in image path
   uv_filename = uv_image.getFilename().replace('/', '\\')

   file.write("%s%s {\n" % ((Tab*idnt), map_type))

   idnt += 1
   file.write("%s*MAP_NAME \"%s\"\n" % ((Tab*idnt), uv_name))
   file.write("%s*MAP_CLASS \"%s\"\n" % ((Tab*idnt), tex_class))
   file.write("%s*MAP_SUBNO %s\n" % ((Tab*idnt), map_subNo))
   file.write("%s*MAP_AMOUNT %s\n" % ((Tab*idnt), fake_val4))
   file.write("%s*BITMAP \"%s\"\n" % ((Tab*idnt), uv_filename))
   file.write("%s*MAP_TYPE %s\n" % ((Tab*idnt), tex_mapType))
   file.write("%s*UVW_U_OFFSET %s\n" % ((Tab*idnt), fake_val0))
   file.write("%s*UVW_V_OFFSET %s\n" % ((Tab*idnt), fake_val0))
   file.write("%s*UVW_U_TILING %s\n" % ((Tab*idnt), fake_val4))
   file.write("%s*UVW_V_TILING %s\n" % ((Tab*idnt), fake_val4))

   map_uvw(file, idnt) #hardcoded

   file.write("%s*BITMAP_FILTER %s\n" % ((Tab*idnt), tex_filter))

   idnt -= 1
   file.write("%s}\n" % (Tab*idnt))


def map_uvw(file, idnt):

   fake_val0 = '0.0000'
   fake_val1 = '1.0000'

   file.write("%s*UVW_ANGLE %s\n" % ((Tab*idnt), fake_val0))
   file.write("%s*UVW_BLUR %s\n" % ((Tab*idnt), fake_val1))
   file.write("%s*UVW_BLUR_OFFSET %s\n" % ((Tab*idnt), fake_val0))
   file.write("%s*UVW_NOUSE_AMT %s\n" % ((Tab*idnt), fake_val1))
   file.write("%s*UVW_NOISE_SIZE %s\n" % ((Tab*idnt), fake_val1))
   file.write("%s*UVW_NOISE_LEVEL 1\n" % (Tab*idnt))
   file.write("%s*UVW_NOISE_PHASE %s\n" % ((Tab*idnt), fake_val0))


#============================================
#           Mesh
#============================================


def write_mesh(file, scn, exp_list, matTable, total):
   print "Write Geometric"

   for current_container in exp_list:

      TransTable = {'SizeX': 1, 'SizeY': 1, 'SizeZ': 1}
      nameMe = {'objName': 'obj', 'meName': 'me'}
      sGroups = {}
      hasTable = {'hasMat': 0, 'hasSG': 0, 'hasUV': 0, 'hasVC': 0, 'matRef': 0}
      count = {'face': 0, 'vert': 0, 'UVs': 0, 'cVert': 0}

      obj = current_container[0]
      #mat_ref = current_container[1]
      data = obj.getData(0,1)
      nameMe['objName'] = obj.name
      nameMe['meName'] = data.name

      mats_me = [mat for mat in data.materials if mat] #fix for 2.44, get rid of NoneType Objects in me.materials
      mats_ob = obj.getMaterials(0)
      materials = False

      if mats_me:
         materials = mats_me
      elif mats_ob:
         materials = mats_ob

      if guiTable['MTL'] and materials:
         hasTable['hasMat'] = 1
         hasTable['matRef'] = current_container[1]

      if obj.getParent():
         nameMe['parent'] = obj.getParent().name
      
      me = Mesh.New()      # Create a new mesh

      if guiTable['MOD']:   # Use modified mesh
         me.getFromObject(obj.name, 0) # Get the object's mesh data, cage 0 = apply mod
      else:
         me.getFromObject(obj.name, 1)

      me.transform(obj.matrix)   # ASE stores transformed mesh data
      if guiTable['RECENTER']:   # Recentre Objects to 0,0,0 feature
         rec_matrix = Mathutils.TranslationMatrix(obj.matrix.translationPart().negate())
         me.transform(rec_matrix)

      tempObj = Blender.Object.New('Mesh', 'ASE_export_temp_obj')
      tempObj.setMatrix(obj.matrix)
      tempObj.link(me)

      if guiTable['VG2SG']:
         VGNames = data.getVertGroupNames()
         for vg in VGNames:
            me.addVertGroup(vg)
            gverts = data.getVertsFromGroup(vg, 1)
            gverts_copy = []
            for gv in gverts:
               gverts_copy.append(gv[0])
            me.assignVertsToGroup(vg, gverts_copy, 1, 1)

      obj = tempObj
      faces = me.faces
      verts = me.verts

      count['vert'] = len(verts)
      total['Verts'] += count['vert']

      if count['vert'] == 0:
         print 'Error: ' + nameMe['meName'] + 'has 0 Verts'
         continue

      vGroups = me.getVertGroupNames()
      if guiTable['VG2SG'] and len(vGroups) > 0:
         for current_VG in vGroups:
            if current_VG.lower().count("smooth."):
               hasTable['hasSG'] = 1
               smooth_num = int(current_VG.lower().replace("smooth.", ""))
               gverts = me.getVertsFromGroup(current_VG)
               for vi in gverts:
                  if not sGroups.has_key(vi):
                     sGroups[vi] = [smooth_num]
                  else:
                     sGroups[vi].append(smooth_num)

      if guiTable['UV']:
         if me.faceUV == True or me.faceUV == 1:
            hasTable['hasUV'] = 1

      if guiTable['VC']:
         if me.vertexColors:
            hasTable['hasVC'] = 1
         elif hasTable['hasMat']: # Blender material
            for current_mat in materials:
               if current_mat.getMode() & Material.Modes['VCOL_PAINT']:
                  hasTable['hasVC'] = 1
                  break

      for current_face in faces:
         if len(current_face.verts) is 3:
            count['face'] += 1
            total['Tris'] += 1
            total['Faces'] += 1
         elif len(current_face.verts) is 4:
            count['face'] += 2
            total['Tris'] += 2
            total['Faces'] += 1

      #Open Geomobject
      file.write("*GEOMOBJECT {\n")
      file.write("%s*NODE_NAME \"%s\"\n" % (Tab, nameMe['objName']))

      if nameMe.has_key('parent'):
         file.write("%s*NODE_PARENT \"%s\"\n" % (Tab, nameMe['parent']))

      idnt = 1
      mesh_matrix(file, idnt, obj, nameMe, TransTable)

      #Open Mesh
      file.write("%s*MESH {\n" % (Tab))

      idnt = 2
      file.write("%s*TIMEVALUE 0\n" % (Tab*idnt))
      file.write("%s*MESH_NUMVERTEX %i\n" % ((Tab*idnt), count['vert']))
      file.write("%s*MESH_NUMFACES %i\n" % ((Tab*idnt), count['face']))

      idnt = 2
      mesh_vertexList(file, idnt, verts, count)
      idnt = 2
      mesh_faceList(file, idnt, me, materials, sGroups, faces, matTable, hasTable, count)


      if hasTable['hasUV'] == 1:
         UVTable = {}

         active_map_channel = me.activeUVLayer
         map_channels = me.getUVLayerNames()

         idnt = 2
         mesh_tVertList(file, idnt, faces, UVTable, count)
         #idnt = 2
         mesh_tFaceList(file, idnt, faces, UVTable, count)
         UVTable = {}
         
         if len(map_channels) > 1:
            chan_index = 2
            for map_chan in map_channels:
               if map_chan != active_map_channel:
                  me.activeUVLayer = map_chan

                  idnt = 2
                  file.write("%s*MESH_MAPPINGCHANNEL %i {\n" % ((Tab*idnt), chan_index))
                  idnt = 3
                  mesh_tVertList(file, idnt, faces, UVTable, count)
                  mesh_tFaceList(file, idnt, faces, UVTable, count)
                  UVTable = {}
                  chan_index += 1
                  idnt = 2
                  file.write("%s}\n" % (Tab*idnt))

         me.activeUVLayer = active_map_channel

      else:
      # dirty fix
         file.write("%s*MESH_NUMTVERTEX %i\n" % ((Tab*idnt), count['UVs']))

      if hasTable['hasVC'] == 1:
         cVertTable = {}

         idnt = 2
         mesh_cVertList(file, idnt, faces, cVertTable, count)
         #idnt = 2
         mesh_cFaceList(file, idnt, faces, cVertTable, count)
      else:
      # dirty fix
         file.write("%s*MESH_NUMCVERTEX %i\n" % ((Tab*idnt), count['cVert']))


      idnt = 2
      mesh_normals(file, idnt, faces, verts, count)

      # Close *MESH
      idnt = 1
      file.write("%s}\n" % (Tab*idnt))

      idnt = 1
      mesh_footer(file, idnt, hasTable)

      # Close *GEOMOBJECT
      file.write("}\n")
      
      #free some memory
      me.materials = [None]
      me.faces.delete(1,[(f.index) for f in me.faces])
      me.verts.delete(me.verts)
      obj.fakeUser = False
      me.fakeUser = False
      scn.objects.unlink(obj)

def mesh_matrix(file, idnt, obj, nameMe, TransTable):

   #i should check why i have to get and invert the matrix
   #exactly in that sequence.

   row = obj.getMatrix('localspace').invert()
   #row = obj.getInverseMatrix()

   if guiTable['RECENTER']:
      location = 0.0,0.0,0.0
      row[3][0] = row[3][1] = row[3][2] = 0.0
   else:
      location = obj.getLocation()

   quat = row.invert().toQuat()
   #quat = obj.getMatrix('localspace').toQuat()
   rota = quat.axis
   #angle = quat.angle * (math.pi/180) #Blender: degrees -> ASE: radians
   angle = math.radians(quat.angle)

   Blender.Window.DrawProgressBar(0.0, "Writing Transform Node")

   file.write("%s*NODE_TM {\n" % (Tab*idnt))

   idnt += 1
   file.write("%s*NODE_NAME \"%s\"\n" % ((Tab*idnt), nameMe['meName']))
   # Inherit from what?..
   file.write("%s*INHERIT_POS 0 0 0\n" % (Tab*idnt))
   file.write("%s*INHERIT_ROT 0 0 0\n" % (Tab*idnt))
   file.write("%s*INHERIT_SCL 0 0 0\n" % (Tab*idnt))

   file.write("%s*TM_ROW0 %.4f %.4f %.4f\n" % ((Tab*idnt), row[0][0], row[0][1], row[0][2]))
   file.write("%s*TM_ROW1 %.4f %.4f %.4f\n" % ((Tab*idnt), row[1][0], row[1][1], row[1][2]))
   file.write("%s*TM_ROW2 %.4f %.4f %.4f\n" % ((Tab*idnt), row[2][0], row[2][1], row[2][2]))
   file.write("%s*TM_ROW3 %.4f %.4f %.4f\n" % ((Tab*idnt), row[3][0], row[3][1], row[3][2]))

   file.write("%s*TM_POS %.4f %.4f %.4f\n" % ((Tab*idnt), location[0], location[1], location[2]))

   file.write("%s*TM_ROTAXIS %.4f %.4f %.4f\n" % ((Tab*idnt), rota.x, rota.y, rota.z))
   file.write("%s*TM_ROTANGLE %.4f\n" % ((Tab*idnt), angle))

   file.write("%s*TM_SCALE %.4f %.4f %.4f\n" % ((Tab*idnt), TransTable['SizeX'], TransTable['SizeY'], TransTable['SizeZ']))
   #file.write("%s*TM_SCALEAXIS 0.0000 0.0000 0.0000\n" % (Tab*idnt))
   # Looks more logic, because blender use the rotaxis for rot and scale:
   file.write("%s*TM_SCALEAXIS %.4f %.4f %.4f\n" % ((Tab*idnt), rota.x, rota.y, rota.z))
   file.write("%s*TM_SCALEAXISANG %.4f\n" % ((Tab*idnt), angle))

   idnt -= 1
   file.write("%s}\n" % (Tab*idnt))


def mesh_vertexList(file, idnt, verts, count):

   file.write("%s*MESH_VERTEX_LIST {\n" % (Tab*idnt))

   idnt += 1

   Blender.Window.DrawProgressBar(0.0, "Writing vertices")

   for current_vert in verts:

      vIndex = current_vert.index

      if (vIndex % 1000) == 0:
                   Blender.Window.DrawProgressBar((vIndex+1.0) / count['vert'], "Writing vertices")

      file.write("%s*MESH_VERTEX %d\t%.4f\t%.4f\t%.4f\n" % ((Tab*idnt), vIndex, current_vert.co[0], current_vert.co[1], current_vert.co[2]))

   idnt -= 1
   file.write("%s}\n" % (Tab*idnt))


def mesh_faceList(file, idnt, me, materials, sGroups, faces, matTable, hasTable, count):

   file.write("%s*MESH_FACE_LIST {\n" % (Tab*idnt))
   idnt += 1
   faceNo = 0

   Blender.Window.DrawProgressBar(0.0, "Writing faces")
   if hasTable['hasMat'] and matTable:
      mats = matTable[hasTable['matRef']]

   fgon_eds = [(ed.key) for ed in me.edges if ed.flag & Mesh.EdgeFlags.FGON]
   for current_face in faces:

      face_verts = current_face.verts
      smooth = '*MESH_SMOOTHING'
      matID = '*MESH_MTLID 0'

      if (faceNo % 500) == 0:
         Blender.Window.DrawProgressBar((faceNo+1.0) / count['face'], "Writing faces")

      if hasTable['hasMat']: # Blender mats
         #print current_face.mat
         mtlid = mats.index(materials[current_face.mat])
         matID = '*MESH_MTLID %i' % (mtlid)

      if len(face_verts) is 3:
         vert0 = face_verts[0].index
         vert1 = face_verts[1].index
         vert2 = face_verts[2].index

         #Find hidden (fgon) edges
         edge_keys = current_face.edge_keys
         eds_fgon = [1,1,1]
         for i,ed_key in enumerate(edge_keys):
            if ed_key in fgon_eds:
               eds_fgon[i] = 0

         #Find Smoothgroups for this face:
         if guiTable['VG2SG'] and hasTable['hasSG'] and current_face.smooth:
            if sGroups.has_key(vert0) and sGroups.has_key(vert1) and sGroups.has_key(vert2):
               sg = []
               gis = [sGroups[vert0],sGroups[vert1],sGroups[vert2]]
               for gil in gis:
                  for gi in gil:
                     sg.append(gi)
               sg = set(sg)
               for gi in sg:
                  smooth += ' %s,' % gi
               smooth = smooth[:-1]

         elif current_face.smooth:
            smooth += ' 1'

         file.write("%s*MESH_FACE %i:    A: %i B: %i C: %i AB:    %i BC:    %i CA:    %i\t %s \t%s\n" % ((Tab*idnt), faceNo, vert0, vert1, vert2, eds_fgon[0], eds_fgon[1], eds_fgon[2], smooth, matID))
         faceNo+=1

      elif len(face_verts) is 4:
         vert0 = face_verts[0].index
         vert1 = face_verts[1].index
         vert2 = face_verts[2].index
         vert3 = face_verts[3].index

         #Find hidden (fgon) edges
         edge_keys = current_face.edge_keys
         eds_fgon = [1,1,1,1]
         for i,ed_key in enumerate(edge_keys):
            if ed_key in fgon_eds:
               eds_fgon[i] = 0

         #Find Smooth for this face:
         if guiTable['VG2SG'] and hasTable['hasSG'] and current_face.smooth:
            if sGroups.has_key(vert0) and sGroups.has_key(vert1) and sGroups.has_key(vert2) and sGroups.has_key(vert3):
               ## I hate VG2SG ;> not sure which way is correct
               #sg0,sg1,sg2,sg3 = sGroups[vert0],sGroups[vert1],sGroups[vert2],sGroups[vert3]
               #if sg0 == sg1 == sg2 == sg3:
               #   sg = sg0
               #else:
               #   lens = [len(sg0),len(sg1),len(sg2),len(sg3)]
               #   lens_sort = lens
               #   lens_sort.sort()
               #   lowest = lens_sort[0]
               #   for l,s in zip(lens,[sg0,sg1,sg2,sg2]):
               #      if l == lowest:
               #         sg = s
               #         break

               sg = []
               gis = [sGroups[vert0],sGroups[vert1],sGroups[vert2],sGroups[vert3]]
               for gil in gis:
                  for gi in gil:
                     sg.append(gi)
               sg = set(sg)
               for gi in sg:
                  smooth += ' %s,' % gi
               smooth = smooth[:-1]
            else:
               smooth += ' 1'

         elif current_face.smooth:
            smooth += ' 1'

         file.write("%s*MESH_FACE %i:    A: %i B: %i C: %i AB:    %i BC:    %i CA:    0\t %s \t%s\n" % ((Tab*idnt), faceNo, vert0, vert1, vert2, eds_fgon[0], eds_fgon[1], smooth, matID))
         faceNo+=1
         file.write("%s*MESH_FACE %i:    A: %i B: %i C: %i AB:    %i BC:    %i CA:    0\t %s \t%s\n" % ((Tab*idnt), faceNo, vert0, vert2, vert3, eds_fgon[1], eds_fgon[2], smooth, matID))
         faceNo+=1

   idnt -= 1
   file.write("%s}\n" % (Tab*idnt))

def mesh_tVertList(file, idnt, faces, UVTable, count):

   Blender.Window.DrawProgressBar(0.0, "Setup UV index")

   for current_face in faces:
      faceuv = current_face.uv
      for current_uv in faceuv:
         uv = (current_uv.x, current_uv.y)
         if not UVTable.has_key(uv):
            UVTable[uv] = 0
            count['UVs'] += 1

   #count['UVs'] = len(UVTable)
   file.write("%s*MESH_NUMTVERTEX %d\n" % ((Tab*idnt), count['UVs']))
   file.write("%s*MESH_TVERTLIST {\n" % (Tab*idnt))

   idnt += 1
   Blender.Window.DrawProgressBar(0.0, "Writing UV index")

   for index,current_UV in enumerate(UVTable.iterkeys()):
      if (index % 1000) == 0:
         Blender.Window.DrawProgressBar((index+1.0) / count['face'], "Writing UV index")

      file.write("%s*MESH_TVERT %i\t%.4f\t%.4f\t0.0000\n" % ((Tab*idnt), index, current_UV[0], current_UV[1]))
      UVTable[current_UV] = index

   idnt -= 1
   file.write("%s}\n" % (Tab*idnt))


def mesh_tFaceList(file, idnt, faces, UVTable, count):

   tfaceNo = 0

   Blender.Window.DrawProgressBar(0.0, "Writing Face UV")

   file.write("%s*MESH_NUMTVFACES %i\n" % ((Tab*idnt), count['face']))
   file.write("%s*MESH_TFACELIST {\n" % (Tab*idnt))

   idnt += 1

   for current_face in faces:

      faceUV = current_face.uv

      if (tfaceNo % 1000) == 0:
         Blender.Window.DrawProgressBar((tfaceNo+1.0) / count['face'], "Writing Face UV")

      if len(faceUV) is 3: #tri
         UV0 = UVTable[(faceUV[0].x, faceUV[0].y)]
         UV1 = UVTable[(faceUV[1].x, faceUV[1].y)]
         UV2 = UVTable[(faceUV[2].x, faceUV[2].y)]
         file.write("%s*MESH_TFACE %i\t%i\t%i\t%d\n" % ((Tab*idnt), tfaceNo, UV0, UV1, UV2))
         tfaceNo+=1

      elif len(faceUV) is 4: #quad
         UV0 = UVTable[(faceUV[0].x, faceUV[0].y)]
         UV1 = UVTable[(faceUV[1].x, faceUV[1].y)]
         UV2 = UVTable[(faceUV[2].x, faceUV[2].y)]
         UV3 = UVTable[(faceUV[3].x, faceUV[3].y)]
         file.write("%s*MESH_TFACE %i\t%i\t%i\t%i\n" % ((Tab*idnt), tfaceNo, UV0, UV1, UV2))
         tfaceNo+=1
         file.write("%s*MESH_TFACE %i\t%i\t%i\t%i\n" % ((Tab*idnt), tfaceNo, UV0, UV2, UV3))
         tfaceNo+=1

   idnt -= 1
   file.write("%s}\n" % (Tab*idnt))


def mesh_cVertList(file, idnt, faces, cVertTable, count):

   Blender.Window.DrawProgressBar(0.0, "Setup VCol index")

   for current_face in faces:
      facecol = current_face.col
      for current_col in facecol:
         col = (current_col.r, current_col.g, current_col.b)
         if not cVertTable.has_key(col):
            cVertTable[col] = 0
            count['cVert'] += 1

   file.write("%s*MESH_NUMCVERTEX %i\n" % ((Tab*idnt), count['cVert']))
   file.write("%s*MESH_CVERTLIST {\n" % (Tab*idnt))

   idnt += 1

   Blender.Window.DrawProgressBar(0.0, "Writing VCol index")

   for index,current_cvert in enumerate(cVertTable.iterkeys()):
      if (index % 1000) == 0:
         Blender.Window.DrawProgressBar((index+1.0) / count['face'], "Writing VCol index")

      file.write("%s*MESH_VERTCOL %i\t%.4f\t%.4f\t%.4f\n" % ((Tab*idnt), index, (current_cvert[0]/256.), (current_cvert[1]/256.), (current_cvert[2]/256.)))
      cVertTable[current_cvert] = index

   idnt -= 1
   file.write("%s}\n" % (Tab*idnt))


def mesh_cFaceList(file, idnt, faces, cVertTable, count):

   cFaceNo = 0

   Blender.Window.DrawProgressBar(0.0, "Writing Face Colors")

   file.write("%s*MESH_NUMCFACES %i\n" % ((Tab*idnt), count['face']))
   file.write("%s*MESH_CFACELIST {\n" % (Tab*idnt))

   idnt += 1
   for current_face in faces:

      if (cFaceNo % 500) == 0:
         Blender.Window.DrawProgressBar((cFaceNo+1.0) / count['face'], "Writing Face Colors")

      if len(current_face.verts) is 3: #tri
         color0 = cVertTable[(current_face.col[0].r, current_face.col[0].g, current_face.col[0].b)]
         color1 = cVertTable[(current_face.col[1].r, current_face.col[1].g, current_face.col[1].b)]
         color2 = cVertTable[(current_face.col[2].r, current_face.col[2].g, current_face.col[2].b)]

         file.write("%s*MESH_CFACE %i\t%i\t%i\t%i\n" % ((Tab*idnt), cFaceNo, color0, color1, color2))
         cFaceNo+= 1

      elif len(current_face.verts) is 4: #quad
         color0 = cVertTable[(current_face.col[0].r, current_face.col[0].g, current_face.col[0].b)]
         color1 = cVertTable[(current_face.col[1].r, current_face.col[1].g, current_face.col[1].b)]
         color2 = cVertTable[(current_face.col[2].r, current_face.col[2].g, current_face.col[2].b)]
         color3 = cVertTable[(current_face.col[3].r, current_face.col[3].g, current_face.col[3].b)]

         file.write("%s*MESH_CFACE %i\t%i\t%i\t%i\n" % ((Tab*idnt), cFaceNo, color0, color1, color2))
         cFaceNo+= 1
         file.write("%s*MESH_CFACE %i\t%i\t%i\t%i\n" % ((Tab*idnt), cFaceNo, color0, color2, color3))
         cFaceNo+= 1

   idnt -= 1
   file.write("%s}\n" % (Tab*idnt))


def mesh_normals(file, idnt, faces, verts, count):
   # To export quads it is needed to calculate all face and vertex normals new!
   vec_null = Blender.Mathutils.Vector(0.0, 0.0, 0.0)
   v_normals = dict([(v.index, vec_null) for v in verts])
   f_normals = dict([(f.index, vec_null) for f in faces])
   f_normals_quad = {}

   file.write("%s*MESH_NORMALS {\n" % (Tab*idnt))

   Blender.Window.DrawProgressBar(0.0, "Setup Normals")

   #-- Calculate new face and vertex normals

   for i,f in enumerate(faces):
      f_dic = f_normals[i]
      f_vec = f_dic[0]

      f_verts = f.verts

      if len(f_verts) is 3: #tri
         v0,v1,v2 = f_verts[:]
         v0_i,v1_i,v2_i = f_verts[0].index, f_verts[1].index, f_verts[2].index
         f_no = Blender.Mathutils.TriangleNormal(v0.co, v1.co, v2.co)
         f_normals[f.index] = f_no
         if f.smooth:
            v_normals[v0_i] = v_normals[v0_i] + f_no
            v_normals[v1_i] = v_normals[v1_i] + f_no
            v_normals[v2_i] = v_normals[v2_i] + f_no

      if len(f_verts) is 4: #quad
         v0,v1,v2,v3 = f_verts[:]
         v0_i,v1_i,v2_i,v3_i = f_verts[0].index, f_verts[1].index, f_verts[2].index,f_verts[3].index
         f_no0 = Blender.Mathutils.TriangleNormal(v0.co, v1.co, v2.co)
         f_no1 = Blender.Mathutils.TriangleNormal(v2.co, v3.co, v0.co)
         f_normals[f.index] = f_no0
         f_normals_quad[f.index] = f_no1
         if f.smooth:
            v_normals[v0_i] = v_normals[v0_i] + f_no0
            v_normals[v1_i] = v_normals[v1_i] + f_no0
            v_normals[v2_i] = v_normals[v2_i] + f_no0
            
            v_normals[v0_i] = v_normals[v2_i] + f_no1
            v_normals[v2_i] = v_normals[v3_i] + f_no1
            v_normals[v3_i] = v_normals[v0_i] + f_no1


   #-- Normalize vectors
   #for i,vec in v_normals.iteritems():
   for vec in v_normals.itervalues():
      vec.normalize()

   #-- Finally write normals
   normNo = 0
   idnt += 2

   Blender.Window.DrawProgressBar(0.0, "Writing Normals")

   for f in faces:

      if (normNo % 500) == 0:
         Blender.Window.DrawProgressBar((normNo+1.0) / count['face'], "Writing Normals")

      f_verts = f.verts
      smooth = f.smooth

      if len(f_verts) is 3: #tri
         v0_i = f_verts[0].index
         v1_i = f_verts[1].index
         v2_i = f_verts[2].index

         idnt -= 1
         f_no = f_normals[f.index]
         file.write("%s*MESH_FACENORMAL %i\t%.4f\t%.4f\t%.4f\n" % ((Tab*idnt), normNo, f_no.x, f_no.y, f_no.z))
         normNo += 1

         idnt += 1
         mesh_vertNorm(file, idnt, v0_i, v1_i, v2_i, v_normals, smooth, f_no)

      #elif len(f_verts) is 4: #quad
      if len(f_verts) is 4: #quad
         v0_i = f_verts[0].index
         v1_i = f_verts[1].index
         v2_i = f_verts[2].index
         v3_i = f_verts[3].index

         idnt -= 1
         f_no = f_normals[f.index]
         file.write("%s*MESH_FACENORMAL %i\t%.4f\t%.4f\t%.4f\n" % ((Tab*idnt), normNo, f_no0.x, f_no0.y, f_no0.z))
         normNo += 1

         idnt += 1
         mesh_vertNorm(file, idnt, v0_i, v1_i, v2_i, v_normals, smooth, f_no0)

         idnt -= 1
         f_no = f_normals_quad[f.index]
         file.write("%s*MESH_FACENORMAL %i\t%.4f\t%.4f\t%.4f\n" % ((Tab*idnt), normNo, f_no1.x, f_no1.y, f_no1.z))
         normNo += 1

         idnt += 1
         mesh_vertNorm(file, idnt, v0_i, v2_i, v3_i, v_normals, smooth, f_no1)


   idnt -= 2
   file.write("%s}\n" % (Tab*idnt))
   
def mesh_vertNorm(file, idnt, v0_i, v1_i, v2_i, v_normals, smooth, f_no):
   if smooth:
      v_no0 = v_normals[v0_i]
      v_no1 = v_normals[v1_i]
      v_no2 = v_normals[v2_i]
   else: #If solid use the face normal
      v_no0 = v_no1 = v_no2 = f_no

   file.write("%s*MESH_VERTEXNORMAL %i\t%.4f\t%.4f\t%.4f\n" % ((Tab*idnt), v0_i, v_no0.x, v_no0.y, v_no0.z))
   file.write("%s*MESH_VERTEXNORMAL %i\t%.4f\t%.4f\t%.4f\n" % ((Tab*idnt), v1_i, v_no1.x, v_no1.y, v_no1.z))
   file.write("%s*MESH_VERTEXNORMAL %i\t%.4f\t%.4f\t%.4f\n" % ((Tab*idnt), v2_i, v_no2.x, v_no2.y, v_no2.z))


def mesh_footer(file, idnt, hasTable):

   file.write("%s*PROP_MOTIONBLUR 0\n" % (Tab*idnt))
   file.write("%s*PROP_CASTSHADOW 1\n" % (Tab*idnt))
   file.write("%s*PROP_RECVSHADOW 1\n" % (Tab*idnt))

   if hasTable['hasMat'] != 0:
      file.write("%s*MATERIAL_REF %i\n" % ((Tab*idnt), hasTable['matRef']))

   #-------------------------End?----------------------


def write_ui(filename):

   global guiTable, EXPORT_MOD, EXPORT_MTL, EXPORT_UV, EXPORT_VC, EXPORT_SELO, EXPORT_UVI, EXPORT_VG2SG
   guiTable = {'MOD': 1, 'MTL': 1, 'UV': 1, 'VC': 1, 'SELO': 1, 'UVI': 0, 'VG2SG': 1, 'RECENTER':0}

   EXPORT_MOD = Draw.Create(guiTable['MOD'])
   EXPORT_MTL = Draw.Create(guiTable['MTL'])
   EXPORT_UV = Draw.Create(guiTable['UV'])
   EXPORT_VC = Draw.Create(guiTable['VC'])
   EXPORT_SELO = Draw.Create(guiTable['SELO'])
   EXPORT_VG2SG = Draw.Create(guiTable['VG2SG'])
   EXPORT_REC = Draw.Create(guiTable['RECENTER'])

   # Get USER Options
   pup_block = [('Mesh Options...'),('Apply Modifiers', EXPORT_MOD, 'Use modified mesh data from each object.'),('Materials', EXPORT_MTL, 'Export Materials.'),('Face UV', EXPORT_UV, 'Export texface UV coords.'),('Vertex Colors', EXPORT_VC, 'Export vertex colors'),('Context...'),('Selection Only', EXPORT_SELO, 'Only export objects in visible selection, else export all mesh object.'),('Bonus...'),('VertGr. as SmoothGr.', EXPORT_VG2SG, 'Make SmoothGroups by VertGroups. See doc.'), ('Center Objects', EXPORT_REC, 'Center ALL objects to World-Grid-Origin-Center-Point-(0,0,0). ;)')]

   if not Draw.PupBlock('Export...', pup_block):
      return

   Window.WaitCursor(1)

   guiTable['MOD'] = EXPORT_MOD.val
   guiTable['MTL'] = EXPORT_MTL.val
   guiTable['UV'] = EXPORT_UV.val
   guiTable['VC'] = EXPORT_VC.val
   guiTable['SELO'] = EXPORT_SELO.val
   guiTable['VG2SG'] = EXPORT_VG2SG.val
   guiTable['RECENTER'] = EXPORT_REC.val

   if not filename.lower().endswith('.ase'):
      filename += '.ase'

   write(filename)

   Window.WaitCursor(0)


if __name__ == '__main__':
   Window.FileSelector(write_ui, 'Export ASCII Scene', sys.makename(ext='.ase'))