Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2006-07-28 12:17:04 +0400
committerCampbell Barton <ideasman42@gmail.com>2006-07-28 12:17:04 +0400
commita7a328523597d1160a546a6e9826c86e213e8ce8 (patch)
treebe9c99f0a3020a1ada79ca70a0079aa595063b22 /release/scripts/flt_import.py
parentcac265f7b6905d195d3a80597c2dc6bf849c1dc7 (diff)
Much needed update to flt_import.py
* NMesh to Mesh * Optimized vertex importing * Import NGons properly and make them blender FGons * lots of other small updates image_bake_from_uvs - ignore meshes without faceUV's
Diffstat (limited to 'release/scripts/flt_import.py')
-rwxr-xr-xrelease/scripts/flt_import.py3316
1 files changed, 1652 insertions, 1664 deletions
diff --git a/release/scripts/flt_import.py b/release/scripts/flt_import.py
index 47a738973a6..b4aa9d04676 100755
--- a/release/scripts/flt_import.py
+++ b/release/scripts/flt_import.py
@@ -24,7 +24,7 @@ Group: 'Import'
Tip: 'Import OpenFlight (.flt)'
"""
-__author__ = "Greg MacDonald"
+__author__ = "Greg MacDonald, Campbell Barton"
__version__ = "1.2 10/20/05"
__url__ = ("blender", "elysiun", "Author's homepage, http://sourceforge.net/projects/blight/")
__bpydoc__ = """\
@@ -36,11 +36,11 @@ Run from "File->Import" menu.
Options are available from Blender's "Scripts Config Editor," accessible through
the "Scripts->System" menu from the scripts window.
-All options are toggle switches that let the user choose what is imported. Most
+All global_prefs are toggle switches that let the user choose what is imported. Most
are straight-forward, but one option could be a source of confusion. The
"Diffuse Color From Face" option when set pulls the diffuse color from the face
colors. Otherwise the diffuse color comes from the material. What may be
-confusing is that this options only works if the "Diffuse Color" option is set.
+confusing is that this global_prefs only works if the "Diffuse Color" option is set.
New Features:<br>
* Importer is 14 times faster.<br>
@@ -65,7 +65,7 @@ Things To Be Aware Of:<br>
materials per object.<br>
* For triangulated faces, normals must be recomputed outward manually by typing
CTRL+N in edit mode.<br>
-* You can change options only after an initial import.<br>
+* You can change global_prefs only after an initial import.<br>
* External references are imported as geometry and will be exported that way.<br>
* A work around for not using the Triangle python module is to simply to
triangulate in Creator before importing. This is only necessary if your
@@ -85,1719 +85,1707 @@ What's Not Handled:<br>
import Blender
import os
+import BPyMesh
+reload(BPyMesh)
+import BPyImage
+reload(BPyImage)
-from flt_filewalker import FltIn, FileFinder
+#from flt_filewalker import FltIn, FileFinder
+import flt_filewalker
+reload(flt_filewalker)
def col_to_gray(c):
- return 0.3*c[0] + 0.59*c[1] + 0.11*c[2]
-
-class ImporterOptions:
- def __init__(self):
- self.defaults = { 'Texture': True,
- 'Diffuse Color': True,
- 'Specular Color': False,
- 'Emissive Intensity': False,
- 'Alpha': True,
- 'Ambient Intensity': False,
- 'Shininess': True,
- 'Diffuse Color From Face': True}
-
- d = Blender.Registry.GetKey('flt_import', True)
-
- if d == None or d.keys() != self.defaults.keys():
- d = self.defaults
- Blender.Registry.SetKey('flt_import', d, True)
-
- self.verbose = 1
- self.get_texture = d['Texture']
- self.get_diffuse = d['Diffuse Color']
- self.get_specular = d['Specular Color']
- self.get_emissive = d['Emissive Intensity']
- self.get_alpha = d['Alpha']
- self.get_ambient = d['Ambient Intensity']
- self.get_shininess = d['Shininess']
- self.color_from_face = d['Diffuse Color From Face']
-
-options = ImporterOptions()
-
-# Contributed by Campbell Barton:
-# http://en.wikibooks.org/wiki/Blending_Into_Python:_Cookbook#Expanded_Scanfill_function
+ return 0.3*c[0] + 0.59*c[1] + 0.11*c[2]
+
+
+global_prefs = dict()
+global_prefs['verbose']= 1
+global_prefs['get_texture'] = True
+global_prefs['get_diffuse'] = True
+global_prefs['get_specular'] = False
+global_prefs['get_emissive'] = False
+global_prefs['get_alpha'] = True
+global_prefs['get_ambient'] = False
+global_prefs['get_shininess'] = True
+global_prefs['color_from_face'] = True
+global_prefs['fltfile']= ''
msg_once = False
-def scanFillPoints(pointList):
- global msg_once
-
- screen_info = Blender.Window.GetScreenInfo(Blender.Window.Types.VIEW3D)
- if screen_info == []:
- if not msg_once:
- msg = 'Error: A 3D View window must be open while the script is running for triangulation to occur.'
- Blender.Draw.PupMenu(msg)
- print msg
- print
- msg_once = True
- return None
-
- Blender.Window.EditMode(0)
-
- nme = Blender.NMesh.GetRaw('.scanfill')
- if nme:
- nme.verts = []
- nme.edges = []
- nme. faces = []
- else:
- nme = Blender.NMesh.New('.scanfill')
-
- for p in pointList:
- v = Blender.NMesh.Vert( p[0], p[1], p[2] )
- nme.verts.append(v)
- v.sel = 1
-
- if len(nme.verts) >= 2:
- nme.addEdge(nme.verts[-2], nme.verts[-1])
-
- nme.addEdge(nme.verts[0], nme.verts[-1])
-
- nme.update()
-
- scn = Blender.Scene.GetCurrent()
-
- actOb = scn.getActiveObject()
- if actOb:
- actSel = actOb.sel
- else:
- actSel = 0
-
- try:
- ob = Blender.Object.Get('.scanfill')
- except ValueError:
- ob = Blender.Object.New('Mesh')
- ob.setName('.scanfill')
- ob.link(nme)
-
- scn.link(ob)
- scn.layers = range(1,20)
- ob.sel = 1
- Blender.Window.EditMode(1)
-
- winid = screen_info[0]['id']
- Blender.Window.SetKeyQualifiers(Blender.Window.Qual.SHIFT)
- Blender.Window.QAdd(winid, Blender.Draw.FKEY,1)
- Blender.Window.QHandle(winid)
- Blender.Window.SetKeyQualifiers(0)
-
- Blender.Window.EditMode(0)
- scn.unlink(ob)
-
- # Select the old active object.
- if actOb:
- actOb.sel = actSel
-
- # Return the scanfilled faces.
- return ob.getData()
class MaterialDesc:
- # Was going to use int(f*1000.0) instead of round(f,3), but for some reason
- # round produces better results, as in less dups.
- def make_key(self):
- key = []
- if options.get_texture:
- if self.tex0:
- key.append(self.tex0.getName())
- else:
- key.append(None)
-
- if options.get_alpha:
- key.append(round(self.alpha, 3))
- else:
- key.append(None)
-
- if options.get_shininess:
- key.append(round(self.shininess, 3))
- else:
- key.append(None)
-
- if options.get_emissive:
- key.append(round(self.emissive, 3))
- else:
- key.append(None)
-
- if options.get_ambient:
- key.append(round(self.ambient, 3))
- else:
- key.append(None)
-
- if options.get_specular:
- for n in self.specular:
- key.append(round(n, 3))
- else:
- key.extend([None, None, None])
-
- if options.get_diffuse:
- for n in self.diffuse:
- key.append(round(n, 3))
- else:
- key.extend([None, None, None])
-
+ # Was going to use int(f*1000.0) instead of round(f,3), but for some reason
+ # round produces better results, as in less dups.
+ def make_key(self):
+ key = list()
+ if global_prefs['get_texture']:
+ if self.tex0:
+ key.append(self.tex0.getName())
+ else:
+ key.append(None)
+
+ if global_prefs['get_alpha']:
+ key.append(round(self.alpha, 3))
+ else:
+ key.append(None)
+
+ if global_prefs['get_shininess']:
+ key.append(round(self.shininess, 3))
+ else:
+ key.append(None)
+
+ if global_prefs['get_emissive']:
+ key.append(round(self.emissive, 3))
+ else:
+ key.append(None)
+
+ if global_prefs['get_ambient']:
+ key.append(round(self.ambient, 3))
+ else:
+ key.append(None)
+
+ if global_prefs['get_specular']:
+ for n in self.specular:
+ key.append(round(n, 3))
+ else:
+ key.extend([None, None, None])
+
+ if global_prefs['get_diffuse']:
+ for n in self.diffuse:
+ key.append(round(n, 3))
+ else:
+ key.extend([None, None, None])
+
# key.extend(self.face_props.values())
-
- return tuple(key)
-
- def __init__(self):
- self.name = 'Material'
- # Colors, List of 3 floats.
- self.diffuse = [1.0, 1.0, 1.0]
- self.specular = [1.0, 1.0, 1.0]
-
- # Scalars
- self.ambient = 0.0 # [0.0, 1.0]
- self.emissive = 0.0 # [0.0, 1.0]
- self.shininess = 0.5 # Range is [0.0, 2.0]
- self.alpha = 1.0 # Range is [0.0, 1.0]
-
- self.tex0 = None
-
- # OpenFlight Face attributes
- self.face_props = dict.fromkeys(['comment', 'ir color', 'priority',
- 'draw type', 'texture white', 'template billboard',
- 'smc', 'fid', 'ir material', 'lod generation control',
- 'flags', 'light mode'])
+
+ return tuple(key)
+
+ def __init__(self):
+ self.name = 'Material'
+ # Colors, List of 3 floats.
+ self.diffuse = [1.0, 1.0, 1.0]
+ self.specular = [1.0, 1.0, 1.0]
+
+ # Scalars
+ self.ambient = 0.0 # [0.0, 1.0]
+ self.emissive = 0.0 # [0.0, 1.0]
+ self.shininess = 0.5 # Range is [0.0, 2.0]
+ self.alpha = 1.0 # Range is [0.0, 1.0]
+
+ self.tex0 = None
+
+ # OpenFlight Face attributes
+ self.face_props = dict.fromkeys(['comment', 'ir color', 'priority',
+ 'draw type', 'texture white', 'template billboard',
+ 'smc', 'fid', 'ir material', 'lod generation control',
+ 'flags', 'light mode'])
class VertexDesc:
- def make_key(self):
- return (round(self.x,3), round(self.y, 3), round(self.z, 3))
-
- def __init__(self):
- self.x = 0.0
- self.y = 0.0
- self.z = 0.0
- self.nx = 0.0
- self.ny = 1.0
- self.nz = 0.0
- self.u = 0.0
- self.v = 0.0
- self.r = 1.0
- self.g = 1.0
- self.b = 1.0
- self.a = 1.0
+ def make_key(self):
+ return int(self.x*1000), int(self.y*1000), int(self.z*1000)
+
+ def __init__(self):
+ self.x = 0.0
+ self.y = 0.0
+ self.z = 0.0
+ self.nx = 0.0
+ self.ny = 1.0
+ self.nz = 0.0
+ self.u = 0.0
+ self.v = 0.0
+ self.r = 1.0
+ self.g = 1.0
+ self.b = 1.0
+ self.a = 1.0
class LightPointAppDesc:
- def make_key(self):
- d = dict(self.props)
- del d['id']
- del d['type']
-
- if d['directionality'] != 0: # not omni
- d['nx'] = 0.0
- d['ny'] = 0.0
- d['nz'] = 0.0
-
- return tuple(d.values())
-
- def __init__(self):
- self.props = dict()
- self.props.update({'type': 'LPA'})
- self.props.update({'id': 'ap'})
- # Attribs not found in inline lightpoint.
- self.props.update({'visibility range': 0.0})
- self.props.update({'fade range ratio': 0.0})
- self.props.update({'fade in duration': 0.0})
- self.props.update({'fade out duration': 0.0})
- self.props.update({'LOD range ratio': 0.0})
- self.props.update({'LOD scale': 0.0})
+ def make_key(self):
+ d = dict(self.props)
+ del d['id']
+ del d['type']
+
+ if d['directionality'] != 0: # not omni
+ d['nx'] = 0.0
+ d['ny'] = 0.0
+ d['nz'] = 0.0
+
+ return tuple(d.values())
+
+ def __init__(self):
+ self.props = dict()
+ self.props.update({'type': 'LPA'})
+ self.props.update({'id': 'ap'})
+ # Attribs not found in inline lightpoint.
+ self.props.update({'visibility range': 0.0})
+ self.props.update({'fade range ratio': 0.0})
+ self.props.update({'fade in duration': 0.0})
+ self.props.update({'fade out duration': 0.0})
+ self.props.update({'LOD range ratio': 0.0})
+ self.props.update({'LOD scale': 0.0})
class GlobalResourceRepository:
- def request_lightpoint_app(self, desc):
- match = self.light_point_app.get(desc.make_key())
-
- if match:
- return match.getName()
- else:
- # Create empty and fill with properties.
- name = desc.props['type'] + ': ' + desc.props['id']
- object = Blender.Object.New('Empty', name)
-
- scene.link(object)
-
- # Attach properties
- for name, value in desc.props.items():
- object.addProperty(name, value)
-
- self.light_point_app.update({desc.make_key(): object})
-
- return object.getName()
-
- def request_vert(self, desc):
- match = self.vert_dict.get(desc.make_key())
-
- if match:
- return match
- else:
- vert = Blender.NMesh.Vert(desc.x, desc.y, desc.z)
-
- vert.no[0] = desc.nx
- vert.no[1] = desc.ny
- vert.no[2] = desc.nz
-
- self.vert_dict.update({desc.make_key(): vert})
- return vert
-
- def request_mat(self, mat_desc):
- match = self.mat_dict.get(mat_desc.make_key())
- if match: return match
-
- mat = Blender.Material.New(mat_desc.name)
-
- if mat_desc.tex0 != None:
- mat.setTexture(0, mat_desc.tex0, Blender.Texture.TexCo.UV)
-
- mat.setAlpha(mat_desc.alpha)
- mat.setSpec(mat_desc.shininess)
- mat.setHardness(255)
- mat.setEmit(mat_desc.emissive)
- mat.setAmb(mat_desc.ambient)
- mat.setSpecCol(mat_desc.specular)
- mat.setRGBCol(mat_desc.diffuse)
-
- # Create a text object to store openflight face attribs until
- # user properties can be set on materials.
+ def request_lightpoint_app(self, desc):
+ match = self.light_point_app.get(desc.make_key())
+
+ if match:
+ return match.getName()
+ else:
+ # Create empty and fill with properties.
+ name = desc.props['type'] + ': ' + desc.props['id']
+ object = Blender.Object.New('Empty', name)
+ scene.link(object)
+ object.Layers= current_layer
+ object.sel= 1
+
+ # Attach properties
+ for name, value in desc.props.iteritems():
+ object.addProperty(name, value)
+
+ self.light_point_app.update({desc.make_key(): object})
+
+ return object.getName()
+
+ def request_vert(self, desc):
+ match = self.vert_dict.get(desc.make_key())
+
+ if match:
+ return match
+ else:
+ vert = Blender.Mathutils.Vector(desc.x, desc.y, desc.z)
+ ''' # No point in assigning teh normal
+ vert.no[0] = desc.nx
+ vert.no[1] = desc.ny
+ vert.no[2] = desc.nz
+ '''
+ self.vert_dict.update({desc.make_key(): vert})
+ return vert
+
+ def request_mat(self, mat_desc):
+ match = self.mat_dict.get(mat_desc.make_key())
+ if match: return match
+
+ mat = Blender.Material.New(mat_desc.name)
+
+ if mat_desc.tex0 != None:
+ mat.setTexture(0, mat_desc.tex0, Blender.Texture.TexCo.UV)
+
+ mat.setAlpha(mat_desc.alpha)
+ mat.setSpec(mat_desc.shininess)
+ mat.setHardness(255)
+ mat.setEmit(mat_desc.emissive)
+ mat.setAmb(mat_desc.ambient)
+ mat.setSpecCol(mat_desc.specular)
+ mat.setRGBCol(mat_desc.diffuse)
+
+ # Create a text object to store openflight face attribs until
+ # user properties can be set on materials.
# t = Blender.Text.New('FACE: ' + mat.getName())
#
# for name, value in mat_desc.face_props.items():
# t.write(name + '\n' + str(value) + '\n\n')
-
- self.mat_dict.update({mat_desc.make_key(): mat})
-
- return mat
-
- def request_image(self, filename_with_path):
- if not options.get_texture: return None
-
- img = self.img_dict.get(filename_with_path)
- if img: return img
-
- img = Blender.Image.Load(filename_with_path)
- self.img_dict.update({filename_with_path: img})
- return img
-
- def request_texture(self, image):
- if not options.get_texture:
- return None
-
- tex = self.tex_dict.get(image.filename)
- if tex: return tex
-
- tex = Blender.Texture.New(Blender.sys.basename(image.filename))
- tex.setImage(image)
- tex.setType('Image')
- self.tex_dict.update({image.filename: tex})
- return tex
-
- def __init__(self):
- # material
- self.mat_dict = dict()
- mat_lst = Blender.Material.Get()
- for mat in mat_lst:
- mat_desc = MaterialDesc()
- mapto_lst = mat.getTextures()
- if mapto_lst[0]:
- mat_desc.tex0 = mapto_lst[0].tex
- else:
- mat_desc.tex0 = None
- mat_desc.alpha = mat.getAlpha()
- mat_desc.shininess = mat.getSpec()
- mat_desc.emissive = mat.getEmit()
- mat_desc.ambient = mat.getAmb()
- mat_desc.specular = mat.getSpecCol()
- mat_desc.diffuse = mat.getRGBCol()
-
- self.mat_dict.update({mat_desc.make_key(): mat})
-
- # texture
- self.tex_dict = dict()
- tex_lst = Blender.Texture.Get()
-
- for tex in tex_lst:
- img = tex.getImage()
- # Only interested in textures with images.
- if img:
- self.tex_dict.update({img.filename: tex})
-
- # image
- img_lst = Blender.Image.Get()
- self.img_dict = dict()
- for img in img_lst:
- self.img_dict.update({img.filename: img})
-
- # vertex
- self.vert_dict = dict()
-
- # light point
- self.light_point_app = dict()
-
+
+ self.mat_dict.update({mat_desc.make_key(): mat})
+
+ return mat
+
+ def request_image(self, filename_with_path):
+ if not global_prefs['get_texture']: return None
+ return BPyImage.comprehensiveImageLoad(filename_with_path, global_prefs['fltfile']) # Use join in case of spaces
+
+ def request_texture(self, image):
+ if not global_prefs['get_texture']:
+ return None
+
+ tex = self.tex_dict.get(image.filename)
+ if tex: return tex
+
+ tex = Blender.Texture.New(Blender.sys.basename(image.filename))
+ tex.setImage(image)
+ tex.setType('Image')
+ self.tex_dict.update({image.filename: tex})
+ return tex
+
+ def __init__(self):
+ # material
+ self.mat_dict = dict()
+ mat_lst = Blender.Material.Get()
+ for mat in mat_lst:
+ mat_desc = MaterialDesc()
+ mapto_lst = mat.getTextures()
+ if mapto_lst[0]:
+ mat_desc.tex0 = mapto_lst[0].tex
+ else:
+ mat_desc.tex0 = None
+ mat_desc.alpha = mat.getAlpha()
+ mat_desc.shininess = mat.getSpec()
+ mat_desc.emissive = mat.getEmit()
+ mat_desc.ambient = mat.getAmb()
+ mat_desc.specular = mat.getSpecCol()
+ mat_desc.diffuse = mat.getRGBCol()
+
+ self.mat_dict.update({mat_desc.make_key(): mat})
+
+ # texture
+ self.tex_dict = dict()
+ tex_lst = Blender.Texture.Get()
+
+ for tex in tex_lst:
+ img = tex.getImage()
+ # Only interested in textures with images.
+ if img:
+ self.tex_dict.update({img.filename: tex})
+
+ # vertex
+ self.vert_dict = dict()
+
+ # light point
+ self.light_point_app = dict()
+
# Globals
GRR = GlobalResourceRepository()
-FF = FileFinder()
-current_layer = 0x1
-scene = Blender.Scene.getCurrent()
+FF = flt_filewalker.FileFinder()
+scene = Blender.Scene.GetCurrent() # just hope they dont chenge scenes once the file selector pops up.
+current_layer = 0x01
+
# Opcodes that indicate its time to return control to parent.
throw_back_opcodes = [2, 73, 4, 11, 96, 14, 91, 98, 63]
do_not_report_opcodes = [76, 78, 79, 80, 81, 82, 94, 83, 33, 112, 100, 101, 102, 97, 31, 103, 104, 117, 118, 120, 121, 124, 125]
opcode_name = { 0: 'db',
- 1: 'head',
- 2: 'grp',
- 4: 'obj',
- 5: 'face',
- 10: 'push',
- 11: 'pop',
- 14: 'dof',
- 19: 'push sub',
- 20: 'pop sub',
- 21: 'push ext',
- 22: 'pop ext',
- 23: 'cont',
- 31: 'comment',
- 32: 'color pal',
- 33: 'long id',
- 49: 'matrix',
- 50: 'vector',
- 52: 'multi-tex',
- 53: 'uv lst',
- 55: 'bsp',
- 60: 'rep',
- 61: 'inst ref',
- 62: 'inst def',
- 63: 'ext ref',
- 64: 'tex pal',
- 67: 'vert pal',
- 68: 'vert w col',
- 69: 'vert w col & norm',
- 70: 'vert w col, norm & uv',
- 71: 'vert w col & uv',
- 72: 'vert lst',
- 73: 'lod',
- 74: 'bndin box',
- 76: 'rot edge',
- 78: 'trans',
- 79: 'scl',
- 80: 'rot pnt',
- 81: 'rot and/or scale pnt',
- 82: 'put',
- 83: 'eyepoint & trackplane pal',
- 84: 'mesh',
- 85: 'local vert pool',
- 86: 'mesh prim',
- 87: 'road seg',
- 88: 'road zone',
- 89: 'morph vert lst',
- 90: 'link pal',
- 91: 'snd',
- 92: 'rd path',
- 93: 'snd pal',
- 94: 'gen matrix',
- 95: 'txt',
- 96: 'sw',
- 97: 'line styl pal',
- 98: 'clip reg',
- 100: 'ext',
- 101: 'light src',
- 102: 'light src pal',
- 103: 'reserved',
- 104: 'reserved',
- 105: 'bndin sph',
- 106: 'bndin cyl',
- 107: 'bndin hull',
- 108: 'bndin vol cntr',
- 109: 'bndin vol orient',
- 110: 'rsrvd',
- 111: 'light pnt',
- 112: 'tex map pal',
- 113: 'mat pal',
- 114: 'name tab',
- 115: 'cat',
- 116: 'cat dat',
- 117: 'rsrvd',
- 118: 'rsrvd',
- 119: 'bounding hist',
- 120: 'rsrvd',
- 121: 'rsrvd',
- 122: 'push attrib',
- 123: 'pop attrib',
- 124: 'rsrvd',
- 125: 'rsrvd',
- 126: 'curv',
- 127: 'road const',
- 128: 'light pnt appear pal',
- 129: 'light pnt anim pal',
- 130: 'indexed lp',
- 131: 'lp sys',
- 132: 'indx str',
- 133: 'shdr pal'}
+ 1: 'head',
+ 2: 'grp',
+ 4: 'obj',
+ 5: 'face',
+ 10: 'push',
+ 11: 'pop',
+ 14: 'dof',
+ 19: 'push sub',
+ 20: 'pop sub',
+ 21: 'push ext',
+ 22: 'pop ext',
+ 23: 'cont',
+ 31: 'comment',
+ 32: 'color pal',
+ 33: 'long id',
+ 49: 'matrix',
+ 50: 'vector',
+ 52: 'multi-tex',
+ 53: 'uv lst',
+ 55: 'bsp',
+ 60: 'rep',
+ 61: 'inst ref',
+ 62: 'inst def',
+ 63: 'ext ref',
+ 64: 'tex pal',
+ 67: 'vert pal',
+ 68: 'vert w col',
+ 69: 'vert w col & norm',
+ 70: 'vert w col, norm & uv',
+ 71: 'vert w col & uv',
+ 72: 'vert lst',
+ 73: 'lod',
+ 74: 'bndin box',
+ 76: 'rot edge',
+ 78: 'trans',
+ 79: 'scl',
+ 80: 'rot pnt',
+ 81: 'rot and/or scale pnt',
+ 82: 'put',
+ 83: 'eyepoint & trackplane pal',
+ 84: 'mesh',
+ 85: 'local vert pool',
+ 86: 'mesh prim',
+ 87: 'road seg',
+ 88: 'road zone',
+ 89: 'morph vert lst',
+ 90: 'link pal',
+ 91: 'snd',
+ 92: 'rd path',
+ 93: 'snd pal',
+ 94: 'gen matrix',
+ 95: 'txt',
+ 96: 'sw',
+ 97: 'line styl pal',
+ 98: 'clip reg',
+ 100: 'ext',
+ 101: 'light src',
+ 102: 'light src pal',
+ 103: 'reserved',
+ 104: 'reserved',
+ 105: 'bndin sph',
+ 106: 'bndin cyl',
+ 107: 'bndin hull',
+ 108: 'bndin vol cntr',
+ 109: 'bndin vol orient',
+ 110: 'rsrvd',
+ 111: 'light pnt',
+ 112: 'tex map pal',
+ 113: 'mat pal',
+ 114: 'name tab',
+ 115: 'cat',
+ 116: 'cat dat',
+ 117: 'rsrvd',
+ 118: 'rsrvd',
+ 119: 'bounding hist',
+ 120: 'rsrvd',
+ 121: 'rsrvd',
+ 122: 'push attrib',
+ 123: 'pop attrib',
+ 124: 'rsrvd',
+ 125: 'rsrvd',
+ 126: 'curv',
+ 127: 'road const',
+ 128: 'light pnt appear pal',
+ 129: 'light pnt anim pal',
+ 130: 'indexed lp',
+ 131: 'lp sys',
+ 132: 'indx str',
+ 133: 'shdr pal'}
class Handler:
- def in_throw_back_lst(self, opcode):
- return opcode in self.throw_back_lst
-
- def handle(self, opcode):
- return self.handler[opcode]()
-
- def handles(self, opcode):
- return opcode in self.handler.keys()
-
- def throws_back_all_unhandled(self):
- return self.throw_back_unhandled
-
- def set_throw_back_lst(self, a):
- self.throw_back_lst = a
-
- def set_throw_back_all_unhandled(self):
- self.throw_back_unhandled = True
-
- def set_only_throw_back_specified(self):
- self.throw_back_unhandled = False
-
- def set_handler(self, d):
- self.handler = d
-
- def __init__(self):
- # Dictionary of opcodes to handler methods.
- self.handler = dict()
- # Send all opcodes not handled to the parent node.
- self.throw_back_unhandled = False
- # If throw_back_unhandled is False then only throw back
- # if the opcodes in throw_back are encountered.
- self.throw_back_lst = []
-
+ def in_throw_back_lst(self, opcode):
+ return opcode in self.throw_back_lst
+
+ def handle(self, opcode):
+ return self.handler[opcode]()
+
+ def handles(self, opcode):
+ return opcode in self.handler.iterkeys()
+
+ def throws_back_all_unhandled(self):
+ return self.throw_back_unhandled
+
+ def set_throw_back_lst(self, a):
+ self.throw_back_lst = a
+
+ def set_throw_back_all_unhandled(self):
+ self.throw_back_unhandled = True
+
+ def set_only_throw_back_specified(self):
+ self.throw_back_unhandled = False
+
+ def set_handler(self, d):
+ self.handler = d
+
+ def __init__(self):
+ # Dictionary of opcodes to handler methods.
+ self.handler = dict()
+ # Send all opcodes not handled to the parent node.
+ self.throw_back_unhandled = False
+ # If throw_back_unhandled is False then only throw back
+ # if the opcodes in throw_back are encountered.
+ self.throw_back_lst = list()
+
class Node:
- def blender_import(self):
- if self.opcode in opcode_name and options.verbose >= 2:
- for i in range(self.get_level()):
- print ' ',
- print opcode_name[self.opcode],
- print '-', self.props['id'],
- print '-', self.props['comment'],
-
- print
-
- for child in self.children:
- child.blender_import()
-
- # Import comment.
+ def blender_import(self):
+ if self.opcode in opcode_name and global_prefs['verbose'] >= 2:
+ for i in xrange(self.get_level()):
+ print ' ',
+ print opcode_name[self.opcode],
+ print '-', self.props['id'],
+ print '-', self.props['comment'],
+
+ print
+
+ for child in self.children:
+ child.blender_import()
+
+ # Import comment.
# if self.props['comment'] != '':
# name = 'COMMENT: ' + self.props['id']
# t = Blender.Text.New(name)
# t.write(self.props['comment'])
# self.props['comment'] = name
-
- # Always ignore extensions and anything in between them.
- def parse_push_extension(self):
- self.saved_handler = self.active_handler
- self.active_handler = self.extension_handler
- return True
-
- def parse_pop_extension(self):
- self.active_handler = self.saved_handler
- return True
-
- def parse_push(self):
- self.header.fw.up_level()
- # Ignore unknown children.
- self.ignore_unhandled = True
- # Don't do child records that might overwrite parent info. ex: longid
- self.active_handler = self.child_handler
- return True
-
- def parse_pop(self):
- self.header.fw.down_level()
-
- if self.header.fw.get_level() == self.level:
- return False
-
- return True
-
- def parse(self):
- while self.header.fw.begin_record():
- opcode = self.header.fw.get_opcode()
-
- # Print out info on opcode and tree level.
- if options.verbose >= 3:
- p = ''
- for i in range(self.header.fw.get_level()):
- p = p + ' '
- if opcode in opcode_name:
- p = p + opcode_name[opcode]
- else:
- if options.verbose >= 1:
- print 'undocumented opcode', opcode
- continue
-
- if self.global_handler.handles(opcode):
- if options.verbose >= 3:
- print p + ' handled globally'
- if self.global_handler.handle(opcode) == False:
- break
-
- elif self.active_handler.handles(opcode):
- if options.verbose >= 4:
- print p + ' handled'
- if self.active_handler.handle(opcode) == False:
- break
-
- else:
- if self.active_handler.throws_back_all_unhandled():
- if options.verbose >= 3:
- print p + ' handled elsewhere'
- self.header.fw.repeat_record()
- break
-
- elif self.active_handler.in_throw_back_lst(opcode):
- if options.verbose >= 3:
- print p + ' handled elsewhere'
- self.header.fw.repeat_record()
- break
-
- else:
- if options.verbose >= 3:
- print p + ' ignored'
- elif options.verbose >= 1 and not opcode in do_not_report_opcodes and opcode in opcode_name:
- print opcode_name[opcode], 'not handled'
-
- def get_level(self):
- return self.level
-
- def parse_long_id(self):
- self.props['id'] = self.header.fw.read_string(self.header.fw.get_length()-4)
- return True
-
- def parse_comment(self):
- self.props['comment'] = self.header.fw.read_string(self.header.fw.get_length()-4)
- return True
-
- def __init__(self, parent, header):
- self.root_handler = Handler()
- self.child_handler = Handler()
- self.extension_handler = Handler()
- self.global_handler = Handler()
-
- self.global_handler.set_handler({21: self.parse_push_extension})
- self.active_handler = self.root_handler
-
- # used by parse_*_extension
- self.extension_handler.set_handler({22: self.parse_pop_extension})
- self.saved_handler = None
-
- self.header = header
- self.children = []
-
- self.parent = parent
-
- if parent:
- parent.children.append(self)
-
- self.level = self.header.fw.get_level()
- self.opcode = self.header.fw.get_opcode()
-
- self.props = {'id': 'unnamed', 'comment': '', 'type': 'untyped'}
+
+ # Always ignore extensions and anything in between them.
+ def parse_push_extension(self):
+ self.saved_handler = self.active_handler
+ self.active_handler = self.extension_handler
+ return True
+
+ def parse_pop_extension(self):
+ self.active_handler = self.saved_handler
+ return True
+
+ def parse_push(self):
+ self.header.fw.up_level()
+ # Ignore unknown children.
+ self.ignore_unhandled = True
+ # Don't do child records that might overwrite parent info. ex: longid
+ self.active_handler = self.child_handler
+ return True
+
+ def parse_pop(self):
+ self.header.fw.down_level()
+
+ if self.header.fw.get_level() == self.level:
+ return False
+
+ return True
+
+ def parse(self):
+ while self.header.fw.begin_record():
+ opcode = self.header.fw.get_opcode()
+
+ # Print out info on opcode and tree level.
+ if global_prefs['verbose'] >= 3:
+ p = ''
+ for i in xrange(self.header.fw.get_level()):
+ p = p + ' '
+ if opcode in opcode_name:
+ p = p + opcode_name[opcode]
+ else:
+ if global_prefs['verbose'] >= 1:
+ print 'undocumented opcode', opcode
+ continue
+
+ if self.global_handler.handles(opcode):
+ if global_prefs['verbose'] >= 3:
+ print p + ' handled globally'
+ if self.global_handler.handle(opcode) == False:
+ break
+
+ elif self.active_handler.handles(opcode):
+ if global_prefs['verbose'] >= 4:
+ print p + ' handled'
+ if self.active_handler.handle(opcode) == False:
+ break
+
+ else:
+ if self.active_handler.throws_back_all_unhandled():
+ if global_prefs['verbose'] >= 3:
+ print p + ' handled elsewhere'
+ self.header.fw.repeat_record()
+ break
+
+ elif self.active_handler.in_throw_back_lst(opcode):
+ if global_prefs['verbose'] >= 3:
+ print p + ' handled elsewhere'
+ self.header.fw.repeat_record()
+ break
+
+ else:
+ if global_prefs['verbose'] >= 3:
+ print p + ' ignored'
+ elif global_prefs['verbose'] >= 1 and not opcode in do_not_report_opcodes and opcode in opcode_name:
+ print opcode_name[opcode], 'not handled'
+
+ def get_level(self):
+ return self.level
+
+ def parse_long_id(self):
+ self.props['id'] = self.header.fw.read_string(self.header.fw.get_length()-4)
+ return True
+
+ def parse_comment(self):
+ self.props['comment'] = self.header.fw.read_string(self.header.fw.get_length()-4)
+ return True
+
+ def __init__(self, parent, header):
+ self.root_handler = Handler()
+ self.child_handler = Handler()
+ self.extension_handler = Handler()
+ self.global_handler = Handler()
+
+ self.global_handler.set_handler({21: self.parse_push_extension})
+ self.active_handler = self.root_handler
+
+ # used by parse_*_extension
+ self.extension_handler.set_handler({22: self.parse_pop_extension})
+ self.saved_handler = None
+
+ self.header = header
+ self.children = list()
+
+ self.parent = parent
+
+ if parent:
+ parent.children.append(self)
+
+ self.level = self.header.fw.get_level()
+ self.opcode = self.header.fw.get_opcode()
+
+ self.props = {'id': 'unnamed', 'comment': '', 'type': 'untyped'}
class VertexPalette(Node):
- def blender_import(self):
- for vert_desc in self.vert_desc_lst:
- vert = GRR.request_vert(vert_desc)
- self.blender_verts.append(vert)
-
- def parse_vertex_common(self):
- # Add this vertex to an offset to index dictionary.
- self.index_lst.append( (self.offset, self.next_index) )
- self.next_index += 1
- # Get ready for next record.
- self.offset += self.header.fw.get_length()
-
- v = VertexDesc()
-
- self.header.fw.read_ahead(2)
- v.flags = self.header.fw.read_short()
-
- v.x = self.header.fw.read_double()
- v.y = self.header.fw.read_double()
- v.z = self.header.fw.read_double()
-
- return v
-
- def parse_vertex_post_common(self, v):
- if not v.flags & 0x2000: # 0x2000 = no color
- if v.flags & 0x1000: # 0x1000 = packed color
- v.a = self.header.fw.read_uchar()
- v.b = self.header.fw.read_uchar()
- v.g = self.header.fw.read_uchar()
- v.r = self.header.fw.read_uchar()
- else:
- self.header.fw.read_ahead(4)
-
- color_index = self.header.fw.read_uint()
- color = self.header.get_color(color_index)
- v.r = color[0]
- v.g = color[1]
- v.b = color[2]
- v.a = color[3]
-
- self.vert_desc_lst.append(v)
-
- return True
-
- def parse_vertex_c(self):
- v = self.parse_vertex_common()
-
- self.parse_vertex_post_common(v)
-
- return True
-
- def parse_vertex_cn(self):
- v = self.parse_vertex_common()
-
- v.nx = self.header.fw.read_float()
- v.ny = self.header.fw.read_float()
- v.nz = self.header.fw.read_float()
-
- self.parse_vertex_post_common(v)
-
- return True
-
- def parse_vertex_cuv(self):
- v = self.parse_vertex_common()
-
- v.u = self.header.fw.read_float()
- v.v = self.header.fw.read_float()
-
- self.parse_vertex_post_common(v)
-
- return True
-
- def parse_vertex_cnuv(self):
- v = self.parse_vertex_common()
-
- v.nx = self.header.fw.read_float()
- v.ny = self.header.fw.read_float()
- v.nz = self.header.fw.read_float()
-
- v.u = self.header.fw.read_float()
- v.v = self.header.fw.read_float()
-
- self.parse_vertex_post_common(v)
-
- return True
-
- def parse(self):
- Node.parse(self)
-
- self.index = dict(self.index_lst)
- del self.index_lst
-
- def __init__(self, parent):
- Node.__init__(self, parent, parent.header)
- self.root_handler.set_handler({68: self.parse_vertex_c,
- 69: self.parse_vertex_cn,
- 70: self.parse_vertex_cnuv,
- 71: self.parse_vertex_cuv})
- self.root_handler.set_throw_back_all_unhandled()
-
- self.vert_desc_lst = []
- self.blender_verts = []
- self.offset = 8
- # Used to create a map from byte offset to vertex index.
- self.index = dict()
- self.index_lst = []
- self.next_index = 0
+ def blender_import(self):
+ for vert_desc in self.vert_desc_lst:
+ vert = GRR.request_vert(vert_desc)
+ self.blender_verts.append(vert)
+
+ def parse_vertex_common(self):
+ # Add this vertex to an offset to index dictionary.
+ self.index_lst.append( (self.offset, self.next_index) )
+ self.next_index += 1
+ # Get ready for next record.
+ self.offset += self.header.fw.get_length()
+
+ v = VertexDesc()
+
+ self.header.fw.read_ahead(2)
+ v.flags = self.header.fw.read_short()
+
+ v.x = self.header.fw.read_double()
+ v.y = self.header.fw.read_double()
+ v.z = self.header.fw.read_double()
+
+ return v
+
+ def parse_vertex_post_common(self, v):
+ if not v.flags & 0x2000: # 0x2000 = no color
+ if v.flags & 0x1000: # 0x1000 = packed color
+ v.a = self.header.fw.read_uchar()
+ v.b = self.header.fw.read_uchar()
+ v.g = self.header.fw.read_uchar()
+ v.r = self.header.fw.read_uchar()
+ else:
+ self.header.fw.read_ahead(4)
+
+ color_index = self.header.fw.read_uint()
+ color = self.header.get_color(color_index)
+ v.r = color[0]
+ v.g = color[1]
+ v.b = color[2]
+ v.a = color[3]
+
+ self.vert_desc_lst.append(v)
+
+ return True
+
+ def parse_vertex_c(self):
+ v = self.parse_vertex_common()
+
+ self.parse_vertex_post_common(v)
+
+ return True
+
+ def parse_vertex_cn(self):
+ v = self.parse_vertex_common()
+
+ v.nx = self.header.fw.read_float()
+ v.ny = self.header.fw.read_float()
+ v.nz = self.header.fw.read_float()
+
+ self.parse_vertex_post_common(v)
+
+ return True
+
+ def parse_vertex_cuv(self):
+ v = self.parse_vertex_common()
+
+ v.u = self.header.fw.read_float()
+ v.v = self.header.fw.read_float()
+
+ self.parse_vertex_post_common(v)
+
+ return True
+
+ def parse_vertex_cnuv(self):
+ v = self.parse_vertex_common()
+
+ v.nx = self.header.fw.read_float()
+ v.ny = self.header.fw.read_float()
+ v.nz = self.header.fw.read_float()
+
+ v.u = self.header.fw.read_float()
+ v.v = self.header.fw.read_float()
+
+ self.parse_vertex_post_common(v)
+
+ return True
+
+ def parse(self):
+ Node.parse(self)
+
+ self.index = dict(self.index_lst)
+ del self.index_lst
+
+ def __init__(self, parent):
+ Node.__init__(self, parent, parent.header)
+ self.root_handler.set_handler({68: self.parse_vertex_c,
+ 69: self.parse_vertex_cn,
+ 70: self.parse_vertex_cnuv,
+ 71: self.parse_vertex_cuv})
+ self.root_handler.set_throw_back_all_unhandled()
+
+ self.vert_desc_lst = list()
+ self.blender_verts = list()
+ self.offset = 8
+ # Used to create a map from byte offset to vertex index.
+ self.index = dict()
+ self.index_lst = list()
+ self.next_index = 0
class InterNode(Node):
- def blender_import(self):
+ def blender_import(self):
# name = self.props['type'] + ': ' + self.props['id']
- name = self.props['id']
- if self.isMesh:
- self.object = Blender.Object.New('Mesh', name)
- self.mesh = self.object.getData()
- else:
- self.object = Blender.Object.New('Empty', name)
-
- if self.parent:
- self.parent.object.makeParent([self.object])
-
- scene.link(self.object)
-
- self.object.Layer = current_layer
-
- Node.blender_import(self)
-
- if self.isMesh:
- self.mesh.update(recalc_normals=1)
-
- if self.matrix:
- self.object.setMatrix(self.matrix)
-
- # Attach properties
- #for name, value in self.props.items():
- # self.object.addProperty(name, value)
-
- def parse_face(self):
- child = Face(self)
- child.parse()
- return True
-
- def parse_group(self):
- child = Group(self)
- child.parse()
- return True
-
- def move_to_next_layer(self):
- global current_layer
- current_layer = current_layer << 1
- if current_layer > 0x80000:
- current_layer = 1
-
- def parse_lod(self):
- child = LOD(self)
- child.parse()
- return True
-
- def parse_unhandled(self):
- child = Unhandled(self)
- child.parse()
- return True
-
- def parse_object(self):
- child = Object(self)
- child.parse()
- return True
-
- def parse_xref(self):
- child = XRef(self)
- child.parse()
- return True
-
- def parse_indexed_light_point(self):
- child = IndexedLightPoint(self)
- child.parse()
- return True
-
- def parse_inline_light_point(self):
- child = InlineLightPoint(self)
- child.parse()
- return True
-
- def parse_matrix(self):
- m = []
- for i in range(4):
- m.append([])
- for j in range(4):
- f = self.header.fw.read_float()
- m[i].append(f)
- self.matrix = Blender.Mathutils.Matrix(m[0], m[1], m[2], m[3])
-
- def __init__(self):
- self.object = None
- self.mesh = None
- self.isMesh = False
- self.matrix = None
-
+ name = self.props['id']
+ if self.isMesh:
+ self.object = Blender.Object.New('Mesh', name)
+ #self.mesh = self.object.getData()
+ self.mesh = Blender.Mesh.New()
+ self.mesh.verts.extend( Blender.Mathutils.Vector() ) # DUMMYVERT
+ self.object.link(self.mesh)
+ else:
+ self.object = Blender.Object.New('Empty', name)
+
+ if self.parent:
+ self.parent.object.makeParent([self.object])
+
+ scene.link(self.object)
+ self.object.Layer = current_layer
+ self.object.sel = 1
+
+
+ Node.blender_import(self)
+
+ if self.isMesh:
+ #self.mesh.update(recalc_normals=1)
+ self.mesh.update()
+
+ if self.matrix:
+ self.object.setMatrix(self.matrix)
+
+ # Attach properties
+ #for name, value in self.props.items():
+ # self.object.addProperty(name, value)
+
+ def parse_face(self):
+ child = Face(self)
+ child.parse()
+ return True
+
+ def parse_group(self):
+ child = Group(self)
+ child.parse()
+ return True
+
+ def move_to_next_layer(self):
+ global current_layer
+ current_layer = current_layer << 1
+ if current_layer > 0x80000:
+ current_layer = 1
+
+ def parse_lod(self):
+ child = LOD(self)
+ child.parse()
+ return True
+
+ def parse_unhandled(self):
+ child = Unhandled(self)
+ child.parse()
+ return True
+
+ def parse_object(self):
+ child = Object(self)
+ child.parse()
+ return True
+
+ def parse_xref(self):
+ child = XRef(self)
+ child.parse()
+ return True
+
+ def parse_indexed_light_point(self):
+ child = IndexedLightPoint(self)
+ child.parse()
+ return True
+
+ def parse_inline_light_point(self):
+ child = InlineLightPoint(self)
+ child.parse()
+ return True
+
+ def parse_matrix(self):
+ m = list()
+ for i in xrange(4):
+ m.append([])
+ for j in xrange(4):
+ f = self.header.fw.read_float()
+ m[i].append(f)
+ self.matrix = Blender.Mathutils.Matrix(m[0], m[1], m[2], m[3])
+
+ def __init__(self):
+ self.object = None
+ self.mesh = None
+ self.isMesh = False
+ self.matrix = None
+
class Face(Node):
- def blender_import_face(self, indices, material_index, image):
- mesh = self.parent.mesh
- face = Blender.NMesh.Face()
-
- # Add vertices to face.
- for i in indices:
- # Add uv info to face.
- vert_desc = self.header.vert_pal.vert_desc_lst[i]
- if vert_desc.u != None and vert_desc.v != None:
- mesh.hasFaceUV(True)
- face.uv.append((vert_desc.u, vert_desc.v))
-
- # Add vert to face.
- vert = self.header.vert_pal.blender_verts[i]
- face.v.append(vert)
-
- # Add vert to mesh.
- if not vert in mesh.verts:
- mesh.verts.append(vert)
-
- if image:
- face.image = image
- face.materialIndex = material_index
- face.smooth = True
-
- mesh.addFace(face)
-
- def parse_comment(self):
- self.comment = self.header.fw.read_string(self.header.fw.get_length()-4)
- return True
-
- # returns a tuple (material, image) where material is the blender material and
- # image is the blender image or None.
- def create_blender_material(self):
- # Create face material.
- mat_desc = MaterialDesc()
-
- if self.mat_index != -1:
- if not self.mat_index in self.header.mat_desc_pal:
- if options.verbose >= 1:
- print 'Warning: Material index', self.mat_index, 'not in material palette.'
- else:
- mat_pal_desc = self.header.mat_desc_pal[self.mat_index]
- mat_desc.alpha = mat_pal_desc.alpha * self.alpha # combine face and mat alphas
- mat_desc.ambient = mat_pal_desc.ambient
- mat_desc.diffuse = mat_pal_desc.diffuse
- mat_desc.specular = mat_pal_desc.specular
- mat_desc.emissive = mat_pal_desc.emissive
- mat_desc.shininess = mat_pal_desc.shininess
- else:
- # if no material get alpha from just face.
- mat_desc.alpha = self.alpha
-
- # Color.
- if options.color_from_face:
- color = None
- if not self.props['flags'] & 0x40000000:
- if self.props['flags'] & 0x10000000: # packed color
- color = self.packed_color
- else:
- color = self.header.get_color(self.color_index)
-
- if color:
- r = float(color[0])/255.0
- g = float(color[1])/255.0
- b = float(color[2])/255.0
- mat_desc.diffuse = [r, g, b]
-
- # Texture
- image = None
- if self.tex_index != -1 and self.tex_index in self.header.bl_tex_pal:
- mat_desc.tex0 = self.header.bl_tex_pal[self.tex_index]
- if mat_desc.tex0:
- mat_desc.name = FF.strip_path(self.header.tex_pal[self.tex_index])
- image = mat_desc.tex0.image
-
- # OpenFlight Face Attributes
- mat_desc.face_props = self.props
-
- # Get material.
- mat = GRR.request_mat(mat_desc)
-
- # Add material to mesh.
- mesh = self.parent.mesh
- try:
- mesh.addMaterial(mat)
- except AttributeError:
- pass
- except RuntimeError:
- if options.verbose >= 1:
- print 'Warning: Too many materials per mesh object. Only a maximum of 16 ' + \
- 'allowed. Using 16th material instead.'
- mat = mesh.materials[-1]
-
- # Return where it is in the mesh for faces.
- material_index = mesh.materials.index(mat)
-
- return (material_index, image)
-
- def triangulate(self):
- point_lst = []
- for i in self.indices:
- vert_desc = self.header.vert_pal.vert_desc_lst[i]
- point_lst.append(self.header.vert_pal.blender_verts[i].co)
-
- mesh = scanFillPoints(point_lst)
- if not mesh:
- return []
-
- # mesh.verts and vert_lst should be in the same order unless blender rearranged them during triangulation, unlikely.
- tri_lst = []
- for f in mesh.faces:
- tri = []
- for vert in f.v:
- i = mesh.verts.index(vert)
- tri.append(self.indices[i])
- tri_lst.append(tri)
-
- return tri_lst
-
- def blender_import(self):
- vert_count = len(self.indices)
- if vert_count == 0:
- if options.verbose >= 2:
- print 'Warning: Ignoring face with no vertices.'
- return
-
- material = self.create_blender_material()
-
- if vert_count > 4:
- tri_lst = self.triangulate()
- else:
- tri_lst = [self.indices]
-
- for tri in tri_lst:
- self.blender_import_face(tri, material[0], material[1])
-
- # Store comment info in parent.
- if self.comment != '':
- if self.parent.props['comment'] != '':
- self.parent.props['comment'] += '\n\nFrom Face:\n' + self.comment
- else:
- self.parent.props['comment'] = self.comment
-
- def parse_vertex_list(self):
- length = self.header.fw.get_length()
- fw = self.header.fw
- vert_pal = self.header.vert_pal
-
- count = (length-4)/4
-
- for i in range(count):
- byte_offset = fw.read_int()
- if byte_offset in vert_pal.index:
- index = vert_pal.index[byte_offset]
- self.indices.append(index)
- elif options.verbose >= 1:
- print 'Warning: Unable to map byte offset %s' + \
- ' to vertex index.' % byte_offset
-
- return True
-
- def __init__(self, parent):
- Node.__init__(self, parent, parent.header)
- self.root_handler.set_handler({31: self.parse_comment,
- 10: self.parse_push})
- self.root_handler.set_throw_back_lst(throw_back_opcodes)
-
- self.child_handler.set_handler({72: self.parse_vertex_list,
- 10: self.parse_push,
- 11: self.parse_pop})
-
- if parent:
- parent.isMesh = True
-
- self.indices = []
-
- self.comment = ''
- self.props = dict.fromkeys(['ir color', 'priority',
- 'draw type', 'texture white', 'template billboard',
- 'smc', 'fid', 'ir material', 'lod generation control',
- 'flags', 'light mode'])
-
- self.header.fw.read_ahead(8) # face id
- # Load face.
- self.props['ir color'] = self.header.fw.read_int()
- self.props['priority'] = self.header.fw.read_short()
- self.props['draw type'] = self.header.fw.read_char()
- self.props['texture white'] = self.header.fw.read_char()
- self.header.fw.read_ahead(4) # color name indices
- self.header.fw.read_ahead(1) # reserved
- self.props['template billboard'] = self.header.fw.read_uchar()
- self.detail_tex_index = self.header.fw.read_short()
- self.tex_index = self.header.fw.read_short()
- self.mat_index = self.header.fw.read_short()
- self.props['smc'] = self.header.fw.read_short()
- self.props['fid'] = self.header.fw.read_short()
- self.props['ir material'] = self.header.fw.read_int()
- self.alpha = 1.0 - float(self.header.fw.read_ushort()) / 65535.0
- self.props['lod generation control'] = self.header.fw.read_uchar()
- self.header.fw.read_ahead(1) # line style index
- self.props['flags'] = self.header.fw.read_int()
- self.props['light mode'] = self.header.fw.read_uchar()
- self.header.fw.read_ahead(7)
- a = self.header.fw.read_uchar()
- b = self.header.fw.read_uchar()
- g = self.header.fw.read_uchar()
- r = self.header.fw.read_uchar()
- self.packed_color = [r, g, b, a]
- a = self.header.fw.read_uchar()
- b = self.header.fw.read_uchar()
- g = self.header.fw.read_uchar()
- r = self.header.fw.read_uchar()
- self.alt_packed_color = [r, g, b, a]
- self.tex_map_index = self.header.fw.read_short()
- self.header.fw.read_ahead(2)
- self.color_index = self.header.fw.read_uint()
- self.alt_color_index = self.header.fw.read_uint()
- #self.header.fw.read_ahead(2)
- #self.shader_index = self.header.fw.read_short()
+ def blender_import_face(self, material_index, image):
+ FGON= Blender.Mesh.EdgeFlags['FGON']
+
+ mesh = self.parent.mesh
+ mesh_vert_len_orig= len(mesh.verts)
+ mesh.verts.extend([ self.header.vert_pal.blender_verts[i] for i in self.indices])
+ face_len= len(self.indices)
+ mesh_face_indicies = range(mesh_vert_len_orig, mesh_vert_len_orig+face_len)
+
+ # First we need to triangulate NGONS
+ if face_len>4:
+ tri_indicies = [[i+mesh_vert_len_orig for i in t] for t in BPyMesh.ngon(mesh, mesh_face_indicies) ] # use range because the verts are in order.
+ else:
+ tri_indicies= [mesh_face_indicies] # can be a quad but thats ok
+
+ # Extend face or ngon
+ mesh.faces.extend(tri_indicies)
+ mesh.faceUV= True
+
+ # Now set UVs
+ for i in xrange(len(mesh.faces)-len(tri_indicies), len(mesh.faces)):
+ f= mesh.faces[i]
+ f_v= f.v
+ for j, uv in enumerate(f.uv):
+ vertex_index_flt= self.indices[f_v[j].index - mesh_vert_len_orig]
+
+ vert_desc = self.header.vert_pal.vert_desc_lst[vertex_index_flt]
+ uv.x, uv.y= vert_desc.u, vert_desc.v
+
+ # Only a bug in 2.42, fixed in cvs
+ for c in f.col:
+ c.r=c.g=c.b= 255
+
+ f.mat = material_index
+ if image:
+ f.image = image
+
+
+ # FGon
+ if face_len>4:
+ # Add edges we know are not fgon
+ end_index= len(mesh.verts)
+ start_index= end_index - len(self.indices)
+ edge_dict= dict([ ((i, i+1), None) for i in xrange(start_index, end_index-1)])
+ edge_dict[(start_index, end_index)]= None # wish this was a set
+
+ fgon_edges= {}
+ for tri in tri_indicies:
+ for i in (0,1,2):
+ i1= tri[i]
+ i2= tri[i-1]
+
+ # Sort
+ if i1>i2:
+ i1,i2= i2,i1
+
+ try:
+ edge_dict[i1,i2] # if this works its an edge vert
+ except:
+ fgon_edges[i1,i2]= None
+
+
+ # Now set fgon flags
+ for ed in mesh.edges:
+ i1= ed.v1.index
+ i2= ed.v2.index
+ if i1>i2:
+ i1,i2= i2,i1
+
+ try:
+ fgon_edges[i1, i2]
+ ed.flag |= FGON
+ del fgon_edges[i1, i2] # make later searches faster?
+
+ except:
+ pass
+
+ if not fgon_edges:
+ break
+
+
+ def parse_comment(self):
+ self.comment = self.header.fw.read_string(self.header.fw.get_length()-4)
+ return True
+
+ # returns a tuple (material, image) where material is the blender material and
+ # image is the blender image or None.
+ def create_blender_material(self):
+ # Create face material.
+ mat_desc = MaterialDesc()
+
+ if self.mat_index != -1:
+ if not self.mat_index in self.header.mat_desc_pal:
+ if global_prefs['verbose'] >= 1:
+ #print 'Warning: Material index', self.mat_index, 'not in material palette.'
+ pass
+ else:
+ mat_pal_desc = self.header.mat_desc_pal[self.mat_index]
+ mat_desc.alpha = mat_pal_desc.alpha * self.alpha # combine face and mat alphas
+ mat_desc.ambient = mat_pal_desc.ambient
+ mat_desc.diffuse = mat_pal_desc.diffuse
+ mat_desc.specular = mat_pal_desc.specular
+ mat_desc.emissive = mat_pal_desc.emissive
+ mat_desc.shininess = mat_pal_desc.shininess
+ else:
+ # if no material get alpha from just face.
+ mat_desc.alpha = self.alpha
+
+ # Color.
+ if global_prefs['color_from_face']:
+ color = None
+ if not self.props['flags'] & 0x40000000:
+ if self.props['flags'] & 0x10000000: # packed color
+ color = self.packed_color
+ else:
+ color = self.header.get_color(self.color_index)
+
+ if color:
+ r = float(color[0])/255.0
+ g = float(color[1])/255.0
+ b = float(color[2])/255.0
+ mat_desc.diffuse = [r, g, b]
+
+ # Texture
+ image = None
+ if self.tex_index != -1 and self.tex_index in self.header.bl_tex_pal:
+ mat_desc.tex0 = self.header.bl_tex_pal[self.tex_index]
+ if mat_desc.tex0:
+ mat_desc.name = FF.strip_path(self.header.tex_pal[self.tex_index])
+ image = mat_desc.tex0.image
+
+ # OpenFlight Face Attributes
+ mat_desc.face_props = self.props
+
+ # Get material.
+ mat = GRR.request_mat(mat_desc)
+
+ # Add material to mesh.
+ mesh = self.parent.mesh
+ try:
+ mesh.materials= mesh.materials+[mat] # not exactly optmil
+ #material_index = len(mesh.materials)-1 # ??? best to a proper check
+ except AttributeError:
+ pass
+ except TypeError:
+ if global_prefs['verbose'] >= 1:
+ print 'Warning: Too many materials per mesh object. Only a maximum of 16 ' + \
+ 'allowed. Using 16th material instead.'
+ mat = mesh.materials[-1]
+
+ # Return where it is in the mesh for faces.
+ #material_index = mesh.materials.index(mat)
+ for i,m in enumerate(mesh.materials):
+ if m.name==mat.name:
+ material_index= i
+ break
+
+ return (material_index, image)
+
+
+ def blender_import(self):
+ vert_count = len(self.indices)
+ if vert_count == 0:
+ if global_prefs['verbose'] >= 2:
+ print 'Warning: Ignoring face with no vertices.'
+ return
+
+ material = self.create_blender_material()
+ '''
+ if vert_count > 4:
+ tri_lst = self.triangulate()
+ else:
+ tri_lst = [self.indices]
+
+ for tri in tri_lst:
+ self.blender_import_face(tri, material[0], material[1])
+ '''
+ self.blender_import_face(material[0], material[1])
+
+ # Store comment info in parent.
+ if self.comment != '':
+ if self.parent.props['comment'] != '':
+ self.parent.props['comment'] += '\n\nFrom Face:\n' + self.comment
+ else:
+ self.parent.props['comment'] = self.comment
+
+ def parse_vertex_list(self):
+ length = self.header.fw.get_length()
+ fw = self.header.fw
+ vert_pal = self.header.vert_pal
+
+ count = (length-4)/4
+
+ for i in xrange(count):
+ byte_offset = fw.read_int()
+ if byte_offset in vert_pal.index:
+ index = vert_pal.index[byte_offset]
+ self.indices.append(index)
+ elif global_prefs['verbose'] >= 1:
+ print 'Warning: Unable to map byte offset %s' + \
+ ' to vertex index.' % byte_offset
+
+ return True
+
+ def __init__(self, parent):
+ Node.__init__(self, parent, parent.header)
+ self.root_handler.set_handler({31: self.parse_comment,
+ 10: self.parse_push})
+ self.root_handler.set_throw_back_lst(throw_back_opcodes)
+
+ self.child_handler.set_handler({72: self.parse_vertex_list,
+ 10: self.parse_push,
+ 11: self.parse_pop})
+
+ if parent:
+ parent.isMesh = True
+
+ self.indices = list()
+
+ self.comment = ''
+ self.props = dict.fromkeys(['ir color', 'priority',
+ 'draw type', 'texture white', 'template billboard',
+ 'smc', 'fid', 'ir material', 'lod generation control',
+ 'flags', 'light mode'])
+
+ self.header.fw.read_ahead(8) # face id
+ # Load face.
+ self.props['ir color'] = self.header.fw.read_int()
+ self.props['priority'] = self.header.fw.read_short()
+ self.props['draw type'] = self.header.fw.read_char()
+ self.props['texture white'] = self.header.fw.read_char()
+ self.header.fw.read_ahead(4) # color name indices
+ self.header.fw.read_ahead(1) # reserved
+ self.props['template billboard'] = self.header.fw.read_uchar()
+ self.detail_tex_index = self.header.fw.read_short()
+ self.tex_index = self.header.fw.read_short()
+ self.mat_index = self.header.fw.read_short()
+ self.props['smc'] = self.header.fw.read_short()
+ self.props['fid'] = self.header.fw.read_short()
+ self.props['ir material'] = self.header.fw.read_int()
+ self.alpha = 1.0 - float(self.header.fw.read_ushort()) / 65535.0
+ self.props['lod generation control'] = self.header.fw.read_uchar()
+ self.header.fw.read_ahead(1) # line style index
+ self.props['flags'] = self.header.fw.read_int()
+ self.props['light mode'] = self.header.fw.read_uchar()
+ self.header.fw.read_ahead(7)
+ a = self.header.fw.read_uchar()
+ b = self.header.fw.read_uchar()
+ g = self.header.fw.read_uchar()
+ r = self.header.fw.read_uchar()
+ self.packed_color = [r, g, b, a]
+ a = self.header.fw.read_uchar()
+ b = self.header.fw.read_uchar()
+ g = self.header.fw.read_uchar()
+ r = self.header.fw.read_uchar()
+ self.alt_packed_color = [r, g, b, a]
+ self.tex_map_index = self.header.fw.read_short()
+ self.header.fw.read_ahead(2)
+ self.color_index = self.header.fw.read_uint()
+ self.alt_color_index = self.header.fw.read_uint()
+ #self.header.fw.read_ahead(2)
+ #self.shader_index = self.header.fw.read_short()
class Object(InterNode):
- def __init__(self, parent):
- Node.__init__(self, parent, parent.header)
- InterNode.__init__(self)
-
- self.root_handler.set_handler({33: self.parse_long_id,
- 31: self.parse_comment,
- 10: self.parse_push,
- 49: self.parse_matrix})
- self.root_handler.set_throw_back_lst(throw_back_opcodes)
-
- self.child_handler.set_handler({5: self.parse_face,
- #130: self.parse_indexed_light_point,
- #111: self.parse_inline_light_point,
- 10: self.parse_push,
- 11: self.parse_pop})
-
- self.props['type'] = 'Object'
- self.props['id'] = self.header.fw.read_string(8)
+ def __init__(self, parent):
+ Node.__init__(self, parent, parent.header)
+ InterNode.__init__(self)
+
+ self.root_handler.set_handler({33: self.parse_long_id,
+ 31: self.parse_comment,
+ 10: self.parse_push,
+ 49: self.parse_matrix})
+ self.root_handler.set_throw_back_lst(throw_back_opcodes)
+
+ self.child_handler.set_handler({5: self.parse_face,
+ #130: self.parse_indexed_light_point,
+ #111: self.parse_inline_light_point,
+ 10: self.parse_push,
+ 11: self.parse_pop})
+
+ self.props['type'] = 'Object'
+ self.props['id'] = self.header.fw.read_string(8)
class Group(InterNode):
- def __init__(self, parent):
- Node.__init__(self, parent, parent.header)
- InterNode.__init__(self)
-
- self.root_handler.set_handler({33: self.parse_long_id,
- 31: self.parse_comment,
- 10: self.parse_push,
- 49: self.parse_matrix})
- self.root_handler.set_throw_back_lst(throw_back_opcodes)
-
- self.child_handler.set_handler({5: self.parse_face,
- #130: self.parse_indexed_light_point,
- #111: self.parse_inline_light_point,
- 2: self.parse_group,
- 73: self.parse_lod,
- 4: self.parse_object,
- 10: self.parse_push,
- 11: self.parse_pop,
- 96: self.parse_unhandled,
- 14: self.parse_unhandled,
- 91: self.parse_unhandled,
- 98: self.parse_unhandled,
- 63: self.parse_xref})
- self.props = dict.fromkeys(['type', 'id', 'comment', 'priority', 'flags', 'special1',
- 'special2', 'significance', 'layer code', 'loop count',
- 'loop duration', 'last frame duration'])
-
- self.props['type'] = 'Group'
- self.props['comment'] = ''
- self.props['id'] = self.header.fw.read_string(8)
- self.props['priority'] = self.header.fw.read_short()
- self.header.fw.read_ahead(2)
- self.props['flags'] = self.header.fw.read_int()
- self.props['special1'] = self.header.fw.read_short()
- self.props['special2'] = self.header.fw.read_short()
- self.props['significance'] = self.header.fw.read_short()
- self.props['layer code'] = self.header.fw.read_char()
- self.header.fw.read_ahead(5)
- self.props['loop count'] = self.header.fw.read_int()
- self.props['loop duration'] = self.header.fw.read_float()
- self.props['last frame duration'] = self.header.fw.read_float()
+ def __init__(self, parent):
+ Node.__init__(self, parent, parent.header)
+ InterNode.__init__(self)
+
+ self.root_handler.set_handler({33: self.parse_long_id,
+ 31: self.parse_comment,
+ 10: self.parse_push,
+ 49: self.parse_matrix})
+ self.root_handler.set_throw_back_lst(throw_back_opcodes)
+
+ self.child_handler.set_handler({5: self.parse_face,
+ #130: self.parse_indexed_light_point,
+ #111: self.parse_inline_light_point,
+ 2: self.parse_group,
+ 73: self.parse_lod,
+ 4: self.parse_object,
+ 10: self.parse_push,
+ 11: self.parse_pop,
+ 96: self.parse_unhandled,
+ 14: self.parse_unhandled,
+ 91: self.parse_unhandled,
+ 98: self.parse_unhandled,
+ 63: self.parse_xref})
+ self.props = dict.fromkeys(['type', 'id', 'comment', 'priority', 'flags', 'special1',
+ 'special2', 'significance', 'layer code', 'loop count',
+ 'loop duration', 'last frame duration'])
+
+ self.props['type'] = 'Group'
+ self.props['comment'] = ''
+ self.props['id'] = self.header.fw.read_string(8)
+ self.props['priority'] = self.header.fw.read_short()
+ self.header.fw.read_ahead(2)
+ self.props['flags'] = self.header.fw.read_int()
+ self.props['special1'] = self.header.fw.read_short()
+ self.props['special2'] = self.header.fw.read_short()
+ self.props['significance'] = self.header.fw.read_short()
+ self.props['layer code'] = self.header.fw.read_char()
+ self.header.fw.read_ahead(5)
+ self.props['loop count'] = self.header.fw.read_int()
+ self.props['loop duration'] = self.header.fw.read_float()
+ self.props['last frame duration'] = self.header.fw.read_float()
class XRef(InterNode):
- def parse(self):
- if self.xref:
- self.xref.parse()
- Node.parse(self)
-
- def __init__(self, parent):
- Node.__init__(self, parent, parent.header)
- InterNode.__init__(self)
-
- self.root_handler.set_handler({49: self.parse_matrix})
- self.root_handler.set_throw_back_lst(throw_back_opcodes)
-
- xref_filename = self.header.fw.read_string(200)
- filename = FF.find(xref_filename)
-
- self.props['type'] = 'XRef'
-
- if filename != None:
- self.xref = Database(filename, self)
- self.props['id'] = 'X: ' + Blender.sys.splitext(Blender.sys.basename(filename))[0]
- else:
- self.xref = None
- self.props['id'] = 'X: broken'
+ def parse(self):
+ if self.xref:
+ self.xref.parse()
+ Node.parse(self)
+
+ def __init__(self, parent):
+ Node.__init__(self, parent, parent.header)
+ InterNode.__init__(self)
+
+ self.root_handler.set_handler({49: self.parse_matrix})
+ self.root_handler.set_throw_back_lst(throw_back_opcodes)
+
+ xref_filename = self.header.fw.read_string(200)
+ filename = FF.find(xref_filename)
+
+ self.props['type'] = 'XRef'
+
+ if filename != None:
+ self.xref = Database(filename, self)
+ self.props['id'] = 'X: ' + Blender.sys.splitext(Blender.sys.basename(filename))[0]
+ else:
+ self.xref = None
+ self.props['id'] = 'X: broken'
class LOD(InterNode):
- def blender_import(self):
- self.move_to_next_layer()
- InterNode.blender_import(self)
-
- def __init__(self, parent):
- Node.__init__(self, parent, parent.header)
- InterNode.__init__(self)
-
- self.root_handler.set_handler({33: self.parse_long_id,
- 31: self.parse_comment,
- 10: self.parse_push,
- 49: self.parse_matrix})
- self.root_handler.set_throw_back_lst(throw_back_opcodes)
-
- self.child_handler.set_handler({2: self.parse_group,
- 73: self.parse_lod,
- 4: self.parse_object,
- 10: self.parse_push,
- 11: self.parse_pop,
- 96: self.parse_unhandled, # switch
- 14: self.parse_unhandled, # DOF
- 91: self.parse_unhandled, # sound
- 98: self.parse_unhandled, # clip
- 63: self.parse_xref})
-
- self.props['type'] = 'LOD'
- self.props['id'] = self.header.fw.read_string(8)
+ def blender_import(self):
+ self.move_to_next_layer()
+ InterNode.blender_import(self)
+
+ def __init__(self, parent):
+ Node.__init__(self, parent, parent.header)
+ InterNode.__init__(self)
+
+ self.root_handler.set_handler({33: self.parse_long_id,
+ 31: self.parse_comment,
+ 10: self.parse_push,
+ 49: self.parse_matrix})
+ self.root_handler.set_throw_back_lst(throw_back_opcodes)
+
+ self.child_handler.set_handler({2: self.parse_group,
+ 73: self.parse_lod,
+ 4: self.parse_object,
+ 10: self.parse_push,
+ 11: self.parse_pop,
+ 96: self.parse_unhandled, # switch
+ 14: self.parse_unhandled, # DOF
+ 91: self.parse_unhandled, # sound
+ 98: self.parse_unhandled, # clip
+ 63: self.parse_xref})
+
+ self.props['type'] = 'LOD'
+ self.props['id'] = self.header.fw.read_string(8)
class InlineLightPoint(InterNode):
- # return dictionary: lp_app name => index list
- def group_points(self, props):
-
- name_to_indices = {}
-
- for i in self.indices:
- vert_desc = self.header.vert_pal.vert_desc_lst[i]
- app_desc = LightPointAppDesc()
- app_desc.props.update(props)
- # add vertex normal and color
- app_desc.props.update({'nx': vert_desc.nx})
- app_desc.props.update({'ny': vert_desc.ny})
- app_desc.props.update({'nz': vert_desc.nz})
-
- app_desc.props.update({'r': vert_desc.r})
- app_desc.props.update({'g': vert_desc.g})
- app_desc.props.update({'b': vert_desc.b})
- app_desc.props.update({'a': vert_desc.a})
-
- app_name = GRR.request_lightpoint_app(app_desc)
-
- if name_to_indices.get(app_name):
- name_to_indices[app_name].append(i)
- else:
- name_to_indices.update({app_name: [i]})
-
- return name_to_indices
-
- def blender_import(self):
- name = self.props['type'] + ': ' + self.props['id']
-
- name_to_indices = self.group_points(self.app_props)
-
- for app_name, indices in name_to_indices.items():
- self.object = Blender.Object.New('Mesh', name)
- self.mesh = self.object.getData()
-
- if self.parent:
- self.parent.object.makeParent([self.object])
-
- for i in indices:
- vert = self.header.vert_pal.blender_verts[i]
- self.mesh.verts.append(vert)
-
- scene.link(self.object)
-
- self.object.Layer = current_layer
-
- if self.matrix:
- self.object.setMatrix(self.matrix)
-
- # Import comment.
- if self.props['comment'] != '':
- name = 'COMMENT: ' + self.props['id']
- t = Blender.Text.New(name)
- t.write(self.props['comment'])
- self.props['comment'] = name
-
- # Attach properties.
- self.props.update({'appearance': app_name})
- for name, value in self.props.items():
- self.object.addProperty(name, value)
-
- self.mesh.update()
-
- def parse_vertex_list(self):
- length = self.header.fw.get_length()
- fw = self.header.fw
- vert_pal = self.header.vert_pal
-
- count = (length-4)/4
-
- for i in range(count):
- byte_offset = fw.read_int()
- if byte_offset in vert_pal.index:
- index = vert_pal.index[byte_offset]
- self.indices.append(index)
- elif options.verbose >= 1:
- print 'Warning: Unable to map byte offset %s' + \
- ' to vertex index.' % byte_offset
-
- return True
-
- def __init__(self, parent):
- Node.__init__(self, parent, parent.header)
- InterNode.__init__(self)
- self.root_handler.set_handler({33: self.parse_long_id,
- 31: self.parse_comment,
- 10: self.parse_push,
- 49: self.parse_matrix})
- self.root_handler.set_throw_back_lst(throw_back_opcodes)
-
- self.child_handler.set_handler({72: self.parse_vertex_list,
- 10: self.parse_push,
- 11: self.parse_pop})
-
- self.indices = []
-
- self.props = dict.fromkeys(['id', 'type', 'comment', 'draw order', 'appearance'])
- self.app_props = dict()
-
- self.props['comment'] = ''
- self.props['type'] = 'Light Point'
- self.props['id'] = self.header.fw.read_string(8)
-
- self.app_props.update({'smc': self.header.fw.read_short()})
- self.app_props.update({'fid': self.header.fw.read_short()})
- self.app_props.update({'back color: a': self.header.fw.read_uchar()})
- self.app_props.update({'back color: b': self.header.fw.read_uchar()})
- self.app_props.update({'back color: g': self.header.fw.read_uchar()})
- self.app_props.update({'back color: r': self.header.fw.read_uchar()})
- self.app_props.update({'display mode': self.header.fw.read_int()})
- self.app_props.update({'intensity': self.header.fw.read_float()})
- self.app_props.update({'back intensity': self.header.fw.read_float()})
- self.app_props.update({'minimum defocus': self.header.fw.read_float()})
- self.app_props.update({'maximum defocus': self.header.fw.read_float()})
- self.app_props.update({'fading mode': self.header.fw.read_int()})
- self.app_props.update({'fog punch mode': self.header.fw.read_int()})
- self.app_props.update({'directional mode': self.header.fw.read_int()})
- self.app_props.update({'range mode': self.header.fw.read_int()})
- self.app_props.update({'min pixel size': self.header.fw.read_float()})
- self.app_props.update({'max pixel size': self.header.fw.read_float()})
- self.app_props.update({'actual size': self.header.fw.read_float()})
- self.app_props.update({'trans falloff pixel size': self.header.fw.read_float()})
- self.app_props.update({'trans falloff exponent': self.header.fw.read_float()})
- self.app_props.update({'trans falloff scalar': self.header.fw.read_float()})
- self.app_props.update({'trans falloff clamp': self.header.fw.read_float()})
- self.app_props.update({'fog scalar': self.header.fw.read_float()})
- self.app_props.update({'fog intensity': self.header.fw.read_float()})
- self.app_props.update({'size threshold': self.header.fw.read_float()})
- self.app_props.update({'directionality': self.header.fw.read_int()})
- self.app_props.update({'horizontal lobe angle': self.header.fw.read_float()})
- self.app_props.update({'vertical lobe angle': self.header.fw.read_float()})
- self.app_props.update({'lobe roll angle': self.header.fw.read_float()})
- self.app_props.update({'dir falloff exponent': self.header.fw.read_float()})
- self.app_props.update({'dir ambient intensity': self.header.fw.read_float()})
- self.header.fw.read_ahead(12) # Animation settings.
- self.app_props.update({'significance': self.header.fw.read_float()})
- self.props['draw order'] = self.header.fw.read_int()
- self.app_props.update({'flags': self.header.fw.read_int()})
- #self.fw.read_ahead(12) # More animation settings.
-
+ # return dictionary: lp_app name => index list
+ def group_points(self, props):
+
+ name_to_indices = {}
+
+ for i in self.indices:
+ vert_desc = self.header.vert_pal.vert_desc_lst[i]
+ app_desc = LightPointAppDesc()
+ app_desc.props.update(props)
+ # add vertex normal and color
+ app_desc.props.update({'nx': vert_desc.nx})
+ app_desc.props.update({'ny': vert_desc.ny})
+ app_desc.props.update({'nz': vert_desc.nz})
+
+ app_desc.props.update({'r': vert_desc.r})
+ app_desc.props.update({'g': vert_desc.g})
+ app_desc.props.update({'b': vert_desc.b})
+ app_desc.props.update({'a': vert_desc.a})
+
+ app_name = GRR.request_lightpoint_app(app_desc)
+
+ if name_to_indices.get(app_name):
+ name_to_indices[app_name].append(i)
+ else:
+ name_to_indices.update({app_name: [i]})
+
+ return name_to_indices
+
+ def blender_import(self):
+ name = '%s: %s' % (self.props['type'], self.props['id'])
+
+ name_to_indices = self.group_points(self.app_props)
+
+ for app_name, indices in name_to_indices.iteritems():
+ self.object = Blender.Object.New('Mesh', name)
+ #self.mesh = self.object.getData()
+ self.mesh= Blender.Mesh.New()
+ self.object.link(self.mesh)
+
+ if self.parent:
+ self.parent.object.makeParent([self.object])
+
+ for i in indices:
+ vert = self.header.vert_pal.blender_verts[i]
+ self.mesh.verts.append(vert)
+
+ scene.link(self.object)
+ self.object.Layer = current_layer
+ self.object.sel= 1
+
+ if self.matrix:
+ self.object.setMatrix(self.matrix)
+
+ # Import comment.
+ if self.props['comment'] != '':
+ name = 'COMMENT: ' + self.props['id']
+ t = Blender.Text.New(name)
+ t.write(self.props['comment'])
+ self.props['comment'] = name
+
+ # Attach properties.
+ self.props.update({'appearance': app_name})
+ for name, value in self.props.iteritems():
+ self.object.addProperty(name, value)
+
+ self.mesh.update()
+
+ def parse_vertex_list(self):
+ length = self.header.fw.get_length()
+ fw = self.header.fw
+ vert_pal = self.header.vert_pal
+
+ count = (length-4)/4
+
+ for i in xrange(count):
+ byte_offset = fw.read_int()
+ if byte_offset in vert_pal.index:
+ index = vert_pal.index[byte_offset]
+ self.indices.append(index)
+ elif global_prefs['verbose'] >= 1:
+ print 'Warning: Unable to map byte offset %s' + \
+ ' to vertex index.' % byte_offset
+
+ return True
+
+ def __init__(self, parent):
+ Node.__init__(self, parent, parent.header)
+ InterNode.__init__(self)
+ self.root_handler.set_handler({33: self.parse_long_id,
+ 31: self.parse_comment,
+ 10: self.parse_push,
+ 49: self.parse_matrix})
+ self.root_handler.set_throw_back_lst(throw_back_opcodes)
+
+ self.child_handler.set_handler({72: self.parse_vertex_list,
+ 10: self.parse_push,
+ 11: self.parse_pop})
+
+ self.indices = list()
+
+ self.props = dict.fromkeys(['id', 'type', 'comment', 'draw order', 'appearance'])
+ self.app_props = dict()
+
+ self.props['comment'] = ''
+ self.props['type'] = 'Light Point'
+ self.props['id'] = self.header.fw.read_string(8)
+
+ self.app_props.update({'smc': self.header.fw.read_short()})
+ self.app_props.update({'fid': self.header.fw.read_short()})
+ self.app_props.update({'back color: a': self.header.fw.read_uchar()})
+ self.app_props.update({'back color: b': self.header.fw.read_uchar()})
+ self.app_props.update({'back color: g': self.header.fw.read_uchar()})
+ self.app_props.update({'back color: r': self.header.fw.read_uchar()})
+ self.app_props.update({'display mode': self.header.fw.read_int()})
+ self.app_props.update({'intensity': self.header.fw.read_float()})
+ self.app_props.update({'back intensity': self.header.fw.read_float()})
+ self.app_props.update({'minimum defocus': self.header.fw.read_float()})
+ self.app_props.update({'maximum defocus': self.header.fw.read_float()})
+ self.app_props.update({'fading mode': self.header.fw.read_int()})
+ self.app_props.update({'fog punch mode': self.header.fw.read_int()})
+ self.app_props.update({'directional mode': self.header.fw.read_int()})
+ self.app_props.update({'range mode': self.header.fw.read_int()})
+ self.app_props.update({'min pixel size': self.header.fw.read_float()})
+ self.app_props.update({'max pixel size': self.header.fw.read_float()})
+ self.app_props.update({'actual size': self.header.fw.read_float()})
+ self.app_props.update({'trans falloff pixel size': self.header.fw.read_float()})
+ self.app_props.update({'trans falloff exponent': self.header.fw.read_float()})
+ self.app_props.update({'trans falloff scalar': self.header.fw.read_float()})
+ self.app_props.update({'trans falloff clamp': self.header.fw.read_float()})
+ self.app_props.update({'fog scalar': self.header.fw.read_float()})
+ self.app_props.update({'fog intensity': self.header.fw.read_float()})
+ self.app_props.update({'size threshold': self.header.fw.read_float()})
+ self.app_props.update({'directionality': self.header.fw.read_int()})
+ self.app_props.update({'horizontal lobe angle': self.header.fw.read_float()})
+ self.app_props.update({'vertical lobe angle': self.header.fw.read_float()})
+ self.app_props.update({'lobe roll angle': self.header.fw.read_float()})
+ self.app_props.update({'dir falloff exponent': self.header.fw.read_float()})
+ self.app_props.update({'dir ambient intensity': self.header.fw.read_float()})
+ self.header.fw.read_ahead(12) # Animation settings.
+ self.app_props.update({'significance': self.header.fw.read_float()})
+ self.props['draw order'] = self.header.fw.read_int()
+ self.app_props.update({'flags': self.header.fw.read_int()})
+ #self.fw.read_ahead(12) # More animation settings.
+
class IndexedLightPoint(InterNode):
- # return dictionary: lp_app name => index list
- def group_points(self, props):
-
- name_to_indices = {}
-
- for i in self.indices:
- vert_desc = self.header.vert_pal.vert_desc_lst[i]
- app_desc = LightPointAppDesc()
- app_desc.props.update(props)
- # add vertex normal and color
- app_desc.props.update({'nx': vert_desc.nx})
- app_desc.props.update({'ny': vert_desc.ny})
- app_desc.props.update({'nz': vert_desc.nz})
-
- app_desc.props.update({'r': vert_desc.r})
- app_desc.props.update({'g': vert_desc.g})
- app_desc.props.update({'b': vert_desc.b})
- app_desc.props.update({'a': vert_desc.a})
-
- app_name = GRR.request_lightpoint_app(app_desc)
-
- if name_to_indices.get(app_name):
- name_to_indices[app_name].append(i)
- else:
- name_to_indices.update({app_name: [i]})
-
- return name_to_indices
-
- def blender_import(self):
- name = self.props['type'] + ': ' + self.props['id']
-
- name_to_indices = self.group_points(self.header.lightpoint_appearance_pal[self.index])
-
- for app_name, indices in name_to_indices.items():
- self.object = Blender.Object.New('Mesh', name)
- self.mesh = self.object.getData()
-
- if self.parent:
- self.parent.object.makeParent([self.object])
-
- for i in indices:
- vert = self.header.vert_pal.blender_verts[i]
- self.mesh.verts.append(vert)
-
- scene.link(self.object)
-
- self.object.Layer = current_layer
-
- if self.matrix:
- self.object.setMatrix(self.matrix)
-
- # Import comment.
- if self.props['comment'] != '':
- name = 'COMMENT: ' + self.props['id']
- t = Blender.Text.New(name)
- t.write(self.props['comment'])
- self.props['comment'] = name
-
- # Attach properties.
- self.props.update({'appearance': app_name})
- for name, value in self.props.items():
- self.object.addProperty(name, value)
-
- self.mesh.update()
-
- def parse_vertex_list(self):
- length = self.header.fw.get_length()
- fw = self.header.fw
- vert_pal = self.header.vert_pal
-
- count = (length-4)/4
-
- for i in range(count):
- byte_offset = fw.read_int()
- if byte_offset in vert_pal.index:
- index = vert_pal.index[byte_offset]
- self.indices.append(index)
- elif options.verbose >= 1:
- print 'Warning: Unable to map byte offset %s' + \
- ' to vertex index.' % byte_offset
-
- return True
-
- def __init__(self, parent):
- Node.__init__(self, parent, parent.header)
- InterNode.__init__(self)
- self.root_handler.set_handler({33: self.parse_long_id,
- 31: self.parse_comment,
- 10: self.parse_push,
- 49: self.parse_matrix})
- self.root_handler.set_throw_back_lst(throw_back_opcodes)
-
- self.child_handler.set_handler({72: self.parse_vertex_list,
- 10: self.parse_push,
- 11: self.parse_pop})
-
- self.indices = []
-
- self.props = dict.fromkeys(['id', 'type', 'comment', 'draw order', 'appearance'])
- self.props['comment'] = ''
- self.props['type'] = 'Light Point'
- self.props['id'] = self.header.fw.read_string(8)
- self.index = self.header.fw.read_int()
- self.header.fw.read_ahead(4) # animation index
- self.props['draw order'] = self.header.fw.read_int()
+ # return dictionary: lp_app name => index list
+ def group_points(self, props):
+
+ name_to_indices = {}
+
+ for i in self.indices:
+ vert_desc = self.header.vert_pal.vert_desc_lst[i]
+ app_desc = LightPointAppDesc()
+ app_desc.props.update(props)
+ # add vertex normal and color
+ app_desc.props.update({'nx': vert_desc.nx})
+ app_desc.props.update({'ny': vert_desc.ny})
+ app_desc.props.update({'nz': vert_desc.nz})
+
+ app_desc.props.update({'r': vert_desc.r})
+ app_desc.props.update({'g': vert_desc.g})
+ app_desc.props.update({'b': vert_desc.b})
+ app_desc.props.update({'a': vert_desc.a})
+
+ app_name = GRR.request_lightpoint_app(app_desc)
+
+ if name_to_indices.get(app_name):
+ name_to_indices[app_name].append(i)
+ else:
+ name_to_indices.update({app_name: [i]})
+
+ return name_to_indices
+
+ def blender_import(self):
+ name = self.props['type'] + ': ' + self.props['id']
+
+ name_to_indices = self.group_points(self.header.lightpoint_appearance_pal[self.index])
+
+ for app_name, indices in name_to_indices.iteritems():
+ self.object = Blender.Object.New('Mesh', name)
+ #self.mesh = self.object.getData()
+ self.mesh= Blender.Mesh.New()
+ self.object.link(self.mesh)
+
+ if self.parent:
+ self.parent.object.makeParent([self.object])
+
+ for i in indices:
+ vert = self.header.vert_pal.blender_verts[i]
+ self.mesh.verts.append(vert)
+
+ scene.link(self.object)
+
+ self.object.Layer = current_layer
+
+ if self.matrix:
+ self.object.setMatrix(self.matrix)
+
+ # Import comment.
+ if self.props['comment'] != '':
+ name = 'COMMENT: ' + self.props['id']
+ t = Blender.Text.New(name)
+ t.write(self.props['comment'])
+ self.props['comment'] = name
+
+ # Attach properties.
+ self.props.update({'appearance': app_name})
+ for name, value in self.props.iteritems():
+ self.object.addProperty(name, value)
+
+ self.mesh.update()
+
+ def parse_vertex_list(self):
+ length = self.header.fw.get_length()
+ fw = self.header.fw
+ vert_pal = self.header.vert_pal
+
+ count = (length-4)/4
+
+ for i in xrange(count):
+ byte_offset = fw.read_int()
+ if byte_offset in vert_pal.index:
+ index = vert_pal.index[byte_offset]
+ self.indices.append(index)
+ elif global_prefs['verbose'] >= 1:
+ print 'Warning: Unable to map byte offset %s' + \
+ ' to vertex index.' % byte_offset
+
+ return True
+
+ def __init__(self, parent):
+ Node.__init__(self, parent, parent.header)
+ InterNode.__init__(self)
+ self.root_handler.set_handler({33: self.parse_long_id,
+ 31: self.parse_comment,
+ 10: self.parse_push,
+ 49: self.parse_matrix})
+ self.root_handler.set_throw_back_lst(throw_back_opcodes)
+
+ self.child_handler.set_handler({72: self.parse_vertex_list,
+ 10: self.parse_push,
+ 11: self.parse_pop})
+
+ self.indices = list()
+
+ self.props = dict.fromkeys(['id', 'type', 'comment', 'draw order', 'appearance'])
+ self.props['comment'] = ''
+ self.props['type'] = 'Light Point'
+ self.props['id'] = self.header.fw.read_string(8)
+ self.index = self.header.fw.read_int()
+ self.header.fw.read_ahead(4) # animation index
+ self.props['draw order'] = self.header.fw.read_int()
class Unhandled(InterNode):
- def __init__(self, parent):
- Node.__init__(self, parent, parent.header)
- InterNode.__init__(self)
-
- self.root_handler.set_handler({33: self.parse_long_id,
- 31: self.parse_comment,
- 10: self.parse_push,
- 49: self.parse_matrix})
- self.root_handler.set_throw_back_lst(throw_back_opcodes)
-
- self.child_handler.set_handler({2: self.parse_group,
- 73: self.parse_lod,
- 4: self.parse_object,
- 10: self.parse_push,
- 11: self.parse_pop,
- 96: self.parse_unhandled, # switch
- 14: self.parse_unhandled, # DOF
- 91: self.parse_unhandled, # sound
- 98: self.parse_unhandled, # clip
- 63: self.parse_xref})
-
- self.props['id'] = self.header.fw.read_string(8)
+ def __init__(self, parent):
+ Node.__init__(self, parent, parent.header)
+ InterNode.__init__(self)
+
+ self.root_handler.set_handler({33: self.parse_long_id,
+ 31: self.parse_comment,
+ 10: self.parse_push,
+ 49: self.parse_matrix})
+ self.root_handler.set_throw_back_lst(throw_back_opcodes)
+
+ self.child_handler.set_handler({2: self.parse_group,
+ 73: self.parse_lod,
+ 4: self.parse_object,
+ 10: self.parse_push,
+ 11: self.parse_pop,
+ 96: self.parse_unhandled, # switch
+ 14: self.parse_unhandled, # DOF
+ 91: self.parse_unhandled, # sound
+ 98: self.parse_unhandled, # clip
+ 63: self.parse_xref})
+
+ self.props['id'] = self.header.fw.read_string(8)
class Database(InterNode):
- def blender_import(self):
- self.tex_pal = dict(self.tex_pal_lst)
- del self.tex_pal_lst
-
- # Setup Textures
- bl_tex_pal_lst = []
- for i in self.tex_pal.keys():
- path_filename = FF.find(self.tex_pal[i])
- if path_filename != None:
- img = GRR.request_image(path_filename)
- if img:
- tex = GRR.request_texture(img)
- tex.setName(FF.strip_path(self.tex_pal[i]))
- bl_tex_pal_lst.append( (i, tex) )
- else:
- bl_tex_pal_lst.append( (i, None) )
- elif options.verbose >= 1:
- print 'Warning: Unable to find', self.tex_pal[i]
-
- self.bl_tex_pal = dict(bl_tex_pal_lst)
-
- # Setup Materials
- self.mat_desc_pal = dict(self.mat_desc_pal_lst)
-
- InterNode.blender_import(self)
-
- def parse_appearance_palette(self):
- props = dict()
- self.fw.read_ahead(4) # reserved
- props.update({'id': self.fw.read_string(256)})
- index = self.fw.read_int()
- props.update({'smc': self.fw.read_short()})
- props.update({'fid': self.fw.read_short()})
- props.update({'back color: a': self.fw.read_uchar()})
- props.update({'back color: b': self.fw.read_uchar()})
- props.update({'back color: g': self.fw.read_uchar()})
- props.update({'back color: r': self.fw.read_uchar()})
- props.update({'display mode': self.fw.read_int()})
- props.update({'intensity': self.fw.read_float()})
- props.update({'back intensity': self.fw.read_float()})
- props.update({'minimum defocus': self.fw.read_float()})
- props.update({'maximum defocus': self.fw.read_float()})
- props.update({'fading mode': self.fw.read_int()})
- props.update({'fog punch mode': self.fw.read_int()})
- props.update({'directional mode': self.fw.read_int()})
- props.update({'range mode': self.fw.read_int()})
- props.update({'min pixel size': self.fw.read_float()})
- props.update({'max pixel size': self.fw.read_float()})
- props.update({'actual size': self.fw.read_float()})
- props.update({'trans falloff pixel size': self.fw.read_float()})
- props.update({'trans falloff exponent': self.fw.read_float()})
- props.update({'trans falloff scalar': self.fw.read_float()})
- props.update({'trans falloff clamp': self.fw.read_float()})
- props.update({'fog scalar': self.fw.read_float()})
- props.update({'fog intensity': self.fw.read_float()})
- props.update({'size threshold': self.fw.read_float()})
- props.update({'directionality': self.fw.read_int()})
- props.update({'horizontal lobe angle': self.fw.read_float()})
- props.update({'vertical lobe angle': self.fw.read_float()})
- props.update({'lobe roll angle': self.fw.read_float()})
- props.update({'dir falloff exponent': self.fw.read_float()})
- props.update({'dir ambient intensity': self.fw.read_float()})
- props.update({'significance': self.fw.read_float()})
- props.update({'flags': self.fw.read_int()})
- props.update({'visibility range': self.fw.read_float()})
- props.update({'fade range ratio': self.fw.read_float()})
- props.update({'fade in duration': self.fw.read_float()})
- props.update({'fade out duration': self.fw.read_float()})
- props.update({'LOD range ratio': self.fw.read_float()})
- props.update({'LOD scale': self.fw.read_float()})
-
- self.lightpoint_appearance_pal.update({index: props})
-
- def parse_header(self):
- self.props['type'] = 'Header'
- self.props['comment'] = ''
- self.props['id'] = self.fw.read_string(8)
- self.props['version'] = self.fw.read_int()
- self.fw.read_ahead(46)
- self.props['units'] = self.fw.read_char()
- self.props['set white'] = bool(self.fw.read_char())
- self.props['flags'] = self.fw.read_int()
- self.fw.read_ahead(24)
- self.props['projection type'] = self.fw.read_int()
- self.fw.read_ahead(36)
- self.props['sw x'] = self.fw.read_double()
- self.props['sw y'] = self.fw.read_double()
- self.props['dx'] = self.fw.read_double()
- self.props['dy'] = self.fw.read_double()
- self.fw.read_ahead(24)
- self.props['sw lat'] = self.fw.read_double()
- self.props['sw lon'] = self.fw.read_double()
- self.props['ne lat'] = self.fw.read_double()
- self.props['ne lon'] = self.fw.read_double()
- self.props['origin lat'] = self.fw.read_double()
- self.props['origin lon'] = self.fw.read_double()
- self.props['lambert lat1'] = self.fw.read_double()
- self.props['lambert lat2'] = self.fw.read_double()
- self.fw.read_ahead(16)
- self.props['ellipsoid model'] = self.fw.read_int()
- self.fw.read_ahead(4)
- self.props['utm zone'] = self.fw.read_short()
- self.fw.read_ahead(6)
- self.props['dz'] = self.fw.read_double()
- self.props['radius'] = self.fw.read_double()
- self.fw.read_ahead(8)
- self.props['major axis'] = self.fw.read_double()
- self.props['minor axis'] = self.fw.read_double()
-
- if options.verbose >= 1:
- print 'OpenFlight Version:', float(self.props['version']) / 100.0
- print
-
- return True
-
- def parse_mat_palette(self):
- mat_desc = MaterialDesc()
- index = self.fw.read_int()
-
- name = self.fw.read_string(12)
- if len(mat_desc.name) > 0:
- mat_desc.name = name
-
- flag = self.fw.read_int()
- # skip material if not used
- if not flag & 0x80000000:
- return True
-
- ambient_col = [self.fw.read_float(), self.fw.read_float(), self.fw.read_float()]
- mat_desc.diffuse = [self.fw.read_float(), self.fw.read_float(), self.fw.read_float()]
- mat_desc.specular = [self.fw.read_float(), self.fw.read_float(), self.fw.read_float()]
- emissive_col = [self.fw.read_float(), self.fw.read_float(), self.fw.read_float()]
-
- mat_desc.shininess = self.fw.read_float() / 64.0 # [0.0, 128.0] => [0.0, 2.0]
- mat_desc.alpha = self.fw.read_float()
-
- # Convert ambient and emissive colors into intensitities.
- mat_desc.ambient = col_to_gray(ambient_col)
- mat_desc.emissive = col_to_gray(emissive_col)
-
- self.mat_desc_pal_lst.append( (index, mat_desc) )
-
- return True
-
- def get_color(self, color_index):
- index = color_index / 128
- intensity = float(color_index - 128.0 * index) / 127.0
-
- if index >= 0 and index <= 1023:
- brightest = self.col_pal[index]
- r = int(brightest[0] * intensity)
- g = int(brightest[1] * intensity)
- b = int(brightest[2] * intensity)
- #a = int(brightest[3] * intensity)
- a = int(brightest[3])
-
- color = [r, g, b, a]
-
- return color
-
- def parse_color_palette(self):
- self.header.fw.read_ahead(128)
- for i in range(1024):
- a = self.header.fw.read_uchar()
- b = self.header.fw.read_uchar()
- g = self.header.fw.read_uchar()
- r = self.header.fw.read_uchar()
- self.col_pal.append((r, g, b, a))
- return True
-
- def parse_vertex_palette(self):
- self.vert_pal = VertexPalette(self)
- self.vert_pal.parse()
- return True
-
- def parse_texture_palette(self):
- name = self.fw.read_string(200)
- index = self.fw.read_int()
- self.tex_pal_lst.append( (index, name) )
- return True
-
- def __init__(self, filename, parent=None):
- if options.verbose >= 1:
- print 'Parsing:', filename
- print
-
- self.fw = FltIn(filename)
- Node.__init__(self, parent, self)
- InterNode.__init__(self)
-
- self.root_handler.set_handler({1: self.parse_header,
- 67: self.parse_vertex_palette,
- 33: self.parse_long_id,
- 31: self.parse_comment,
- 64: self.parse_texture_palette,
- 32: self.parse_color_palette,
- 113: self.parse_mat_palette,
- 128: self.parse_appearance_palette,
- 10: self.parse_push})
- if parent:
- self.root_handler.set_throw_back_lst(throw_back_opcodes)
-
- self.child_handler.set_handler({#130: self.parse_indexed_light_point,
- #111: self.parse_inline_light_point,
- 2: self.parse_group,
- 73: self.parse_lod,
- 4: self.parse_object,
- 10: self.parse_push,
- 11: self.parse_pop,
- 96: self.parse_unhandled,
- 14: self.parse_unhandled,
- 91: self.parse_unhandled,
- 98: self.parse_unhandled,
- 63: self.parse_xref})
-
- self.vert_pal = None
- self.lightpoint_appearance_pal = dict()
- self.tex_pal = dict()
- self.tex_pal_lst = []
- self.bl_tex_pal = dict()
- self.col_pal = []
- self.mat_desc_pal_lst = []
- self.mat_desc_pal = dict()
- self.props = dict.fromkeys(['id', 'type', 'comment', 'version', 'units', 'set white',
- 'flags', 'projection type', 'sw x', 'sw y', 'dx', 'dy', 'dz', 'sw lat',
- 'sw lon', 'ne lat', 'ne lon', 'origin lat', 'origin lon', 'lambert lat1',
- 'lambert lat2', 'ellipsoid model', 'utm zone', 'radius', 'major axis', 'minor axis'])
+ def blender_import(self):
+ self.tex_pal = dict(self.tex_pal_lst)
+ del self.tex_pal_lst
+
+ # Setup Textures
+ bl_tex_pal_lst = list()
+ for i in self.tex_pal.iterkeys():
+ path_filename = FF.find(self.tex_pal[i])
+ if path_filename != None:
+ img = GRR.request_image(path_filename)
+ if img:
+ tex = GRR.request_texture(img)
+ tex.setName(FF.strip_path(self.tex_pal[i]))
+ bl_tex_pal_lst.append( (i, tex) )
+ else:
+ bl_tex_pal_lst.append( (i, None) )
+ elif global_prefs['verbose'] >= 1:
+ print 'Warning: Unable to find', self.tex_pal[i]
+
+ self.bl_tex_pal = dict(bl_tex_pal_lst)
+
+ # Setup Materials
+ self.mat_desc_pal = dict(self.mat_desc_pal_lst)
+
+ InterNode.blender_import(self)
+
+ def parse_appearance_palette(self):
+ props = dict()
+ self.fw.read_ahead(4) # reserved
+ props.update({'id': self.fw.read_string(256)})
+ index = self.fw.read_int()
+ props.update({'smc': self.fw.read_short()})
+ props.update({'fid': self.fw.read_short()})
+ props.update({'back color: a': self.fw.read_uchar()})
+ props.update({'back color: b': self.fw.read_uchar()})
+ props.update({'back color: g': self.fw.read_uchar()})
+ props.update({'back color: r': self.fw.read_uchar()})
+ props.update({'display mode': self.fw.read_int()})
+ props.update({'intensity': self.fw.read_float()})
+ props.update({'back intensity': self.fw.read_float()})
+ props.update({'minimum defocus': self.fw.read_float()})
+ props.update({'maximum defocus': self.fw.read_float()})
+ props.update({'fading mode': self.fw.read_int()})
+ props.update({'fog punch mode': self.fw.read_int()})
+ props.update({'directional mode': self.fw.read_int()})
+ props.update({'range mode': self.fw.read_int()})
+ props.update({'min pixel size': self.fw.read_float()})
+ props.update({'max pixel size': self.fw.read_float()})
+ props.update({'actual size': self.fw.read_float()})
+ props.update({'trans falloff pixel size': self.fw.read_float()})
+ props.update({'trans falloff exponent': self.fw.read_float()})
+ props.update({'trans falloff scalar': self.fw.read_float()})
+ props.update({'trans falloff clamp': self.fw.read_float()})
+ props.update({'fog scalar': self.fw.read_float()})
+ props.update({'fog intensity': self.fw.read_float()})
+ props.update({'size threshold': self.fw.read_float()})
+ props.update({'directionality': self.fw.read_int()})
+ props.update({'horizontal lobe angle': self.fw.read_float()})
+ props.update({'vertical lobe angle': self.fw.read_float()})
+ props.update({'lobe roll angle': self.fw.read_float()})
+ props.update({'dir falloff exponent': self.fw.read_float()})
+ props.update({'dir ambient intensity': self.fw.read_float()})
+ props.update({'significance': self.fw.read_float()})
+ props.update({'flags': self.fw.read_int()})
+ props.update({'visibility range': self.fw.read_float()})
+ props.update({'fade range ratio': self.fw.read_float()})
+ props.update({'fade in duration': self.fw.read_float()})
+ props.update({'fade out duration': self.fw.read_float()})
+ props.update({'LOD range ratio': self.fw.read_float()})
+ props.update({'LOD scale': self.fw.read_float()})
+
+ self.lightpoint_appearance_pal.update({index: props})
+
+ def parse_header(self):
+ self.props['type'] = 'Header'
+ self.props['comment'] = ''
+ self.props['id'] = self.fw.read_string(8)
+ self.props['version'] = self.fw.read_int()
+ self.fw.read_ahead(46)
+ self.props['units'] = self.fw.read_char()
+ self.props['set white'] = bool(self.fw.read_char())
+ self.props['flags'] = self.fw.read_int()
+ self.fw.read_ahead(24)
+ self.props['projection type'] = self.fw.read_int()
+ self.fw.read_ahead(36)
+ self.props['sw x'] = self.fw.read_double()
+ self.props['sw y'] = self.fw.read_double()
+ self.props['dx'] = self.fw.read_double()
+ self.props['dy'] = self.fw.read_double()
+ self.fw.read_ahead(24)
+ self.props['sw lat'] = self.fw.read_double()
+ self.props['sw lon'] = self.fw.read_double()
+ self.props['ne lat'] = self.fw.read_double()
+ self.props['ne lon'] = self.fw.read_double()
+ self.props['origin lat'] = self.fw.read_double()
+ self.props['origin lon'] = self.fw.read_double()
+ self.props['lambert lat1'] = self.fw.read_double()
+ self.props['lambert lat2'] = self.fw.read_double()
+ self.fw.read_ahead(16)
+ self.props['ellipsoid model'] = self.fw.read_int()
+ self.fw.read_ahead(4)
+ self.props['utm zone'] = self.fw.read_short()
+ self.fw.read_ahead(6)
+ self.props['dz'] = self.fw.read_double()
+ self.props['radius'] = self.fw.read_double()
+ self.fw.read_ahead(8)
+ self.props['major axis'] = self.fw.read_double()
+ self.props['minor axis'] = self.fw.read_double()
+
+ if global_prefs['verbose'] >= 1:
+ print 'OpenFlight Version:', float(self.props['version']) / 100.0
+ print
+
+ return True
+
+ def parse_mat_palette(self):
+ mat_desc = MaterialDesc()
+ index = self.fw.read_int()
+
+ name = self.fw.read_string(12)
+ if len(mat_desc.name) > 0:
+ mat_desc.name = name
+
+ flag = self.fw.read_int()
+ # skip material if not used
+ if not flag & 0x80000000:
+ return True
+
+ ambient_col = [self.fw.read_float(), self.fw.read_float(), self.fw.read_float()]
+ mat_desc.diffuse = [self.fw.read_float(), self.fw.read_float(), self.fw.read_float()]
+ mat_desc.specular = [self.fw.read_float(), self.fw.read_float(), self.fw.read_float()]
+ emissive_col = [self.fw.read_float(), self.fw.read_float(), self.fw.read_float()]
+
+ mat_desc.shininess = self.fw.read_float() / 64.0 # [0.0, 128.0] => [0.0, 2.0]
+ mat_desc.alpha = self.fw.read_float()
+
+ # Convert ambient and emissive colors into intensitities.
+ mat_desc.ambient = col_to_gray(ambient_col)
+ mat_desc.emissive = col_to_gray(emissive_col)
+
+ self.mat_desc_pal_lst.append( (index, mat_desc) )
+
+ return True
+
+ def get_color(self, color_index):
+ index = color_index / 128
+ intensity = float(color_index - 128.0 * index) / 127.0
+
+ if index >= 0 and index <= 1023:
+ brightest = self.col_pal[index]
+ r = int(brightest[0] * intensity)
+ g = int(brightest[1] * intensity)
+ b = int(brightest[2] * intensity)
+ #a = int(brightest[3] * intensity)
+ a = int(brightest[3])
+
+ color = [r, g, b, a]
+
+ return color
+
+ def parse_color_palette(self):
+ self.header.fw.read_ahead(128)
+ for i in xrange(1024):
+ a = self.header.fw.read_uchar()
+ b = self.header.fw.read_uchar()
+ g = self.header.fw.read_uchar()
+ r = self.header.fw.read_uchar()
+ self.col_pal.append((r, g, b, a))
+ return True
+
+ def parse_vertex_palette(self):
+ self.vert_pal = VertexPalette(self)
+ self.vert_pal.parse()
+ return True
+
+ def parse_texture_palette(self):
+ name = self.fw.read_string(200)
+ index = self.fw.read_int()
+ self.tex_pal_lst.append( (index, name) )
+ return True
+
+ def __init__(self, filename, parent=None):
+ if global_prefs['verbose'] >= 1:
+ print 'Parsing:', filename
+ print
+
+ self.fw = flt_filewalker.FltIn(filename)
+ Node.__init__(self, parent, self)
+ InterNode.__init__(self)
+
+ self.root_handler.set_handler({1: self.parse_header,
+ 67: self.parse_vertex_palette,
+ 33: self.parse_long_id,
+ 31: self.parse_comment,
+ 64: self.parse_texture_palette,
+ 32: self.parse_color_palette,
+ 113: self.parse_mat_palette,
+ 128: self.parse_appearance_palette,
+ 10: self.parse_push})
+ if parent:
+ self.root_handler.set_throw_back_lst(throw_back_opcodes)
+
+ self.child_handler.set_handler({#130: self.parse_indexed_light_point,
+ #111: self.parse_inline_light_point,
+ 2: self.parse_group,
+ 73: self.parse_lod,
+ 4: self.parse_object,
+ 10: self.parse_push,
+ 11: self.parse_pop,
+ 96: self.parse_unhandled,
+ 14: self.parse_unhandled,
+ 91: self.parse_unhandled,
+ 98: self.parse_unhandled,
+ 63: self.parse_xref})
+
+ self.vert_pal = None
+ self.lightpoint_appearance_pal = dict()
+ self.tex_pal = dict()
+ self.tex_pal_lst = list()
+ self.bl_tex_pal = dict()
+ self.col_pal = list()
+ self.mat_desc_pal_lst = list()
+ self.mat_desc_pal = dict()
+ self.props = dict.fromkeys(['id', 'type', 'comment', 'version', 'units', 'set white',
+ 'flags', 'projection type', 'sw x', 'sw y', 'dx', 'dy', 'dz', 'sw lat',
+ 'sw lon', 'ne lat', 'ne lon', 'origin lat', 'origin lon', 'lambert lat1',
+ 'lambert lat2', 'ellipsoid model', 'utm zone', 'radius', 'major axis', 'minor axis'])
def select_file(filename):
- Blender.Window.WaitCursor(True)
-
- if filename[-4:] != '.flt':
- msg = 'Error: Not a flight file.'
- Blender.Draw.PupMenu(msg)
- print msg
- print
- return
-
- if not Blender.sys.exists(filename):
- msg = 'Error: File ' + filename + ' does not exist.'
- Blender.Draw.PupMenu(msg)
- return
-
- FF.add_file_to_search_path(filename)
-
- if options.verbose >= 1:
- print 'Pass 1: Loading.'
- print
-
- load_time = Blender.sys.time()
- db = Database(filename)
- db.parse()
- load_time = Blender.sys.time() - load_time
-
- if options.verbose >= 1:
- print
- print 'Pass 2: Importing to Blender.'
- print
-
- import_time = Blender.sys.time()
- db.blender_import()
- import_time = Blender.sys.time() - import_time
-
- Blender.Window.ViewLayer(range(1,21))
- Blender.Window.RedrawAll()
-
- if options.verbose >= 1:
- print 'Done.'
- print
- print 'Time to parse file: %.3f seconds' % load_time
- print 'Time to import to blender: %.3f seconds' % import_time
- print 'Total time: %.3f seconds' % (load_time + import_time)
-
- Blender.Window.WaitCursor(False)
-
-
-if options.verbose >= 1:
- print
- print 'OpenFlight Importer'
- print 'Version:', __version__
- print 'Author: Greg MacDonald'
- print __url__[2]
- print
-
-Blender.Window.EditMode(0)
-
-winid = Blender.Window.GetScreenInfo(Blender.Window.Types.VIEW3D)[0]['id']
-
-Blender.Window.FileSelector(select_file, "Import OpenFlight", "*.flt")
+ if not Blender.sys.exists(filename):
+ msg = 'Error: File ' + filename + ' does not exist.'
+ Blender.Draw.PupMenu(msg)
+ return
+
+ if not filename.lower().endswith('.flt'):
+ msg = 'Error: Not a flight file.'
+ Blender.Draw.PupMenu(msg)
+ print msg
+ print
+ return
+
+ global_prefs['fltfile']= filename
+ global_prefs['verbose']= 1
+ global_prefs['get_texture'] = True
+ global_prefs['get_diffuse'] = True
+ global_prefs['get_specular'] = False
+ global_prefs['get_emissive'] = False
+ global_prefs['get_alpha'] = True
+ global_prefs['get_ambient'] = False
+ global_prefs['get_shininess'] = True
+ global_prefs['color_from_face'] = True
+
+ # Start loading the file,
+ # first set the context
+ Blender.Window.WaitCursor(True)
+ Blender.Window.EditMode(0)
+ for ob in scene.getChildren():
+ ob.sel=0
+
+
+ FF.add_file_to_search_path(filename)
+
+ if global_prefs['verbose'] >= 1:
+ print 'Pass 1: Loading.'
+ print
+
+ load_time = Blender.sys.time()
+ db = Database(filename)
+ db.parse()
+ load_time = Blender.sys.time() - load_time
+
+ if global_prefs['verbose'] >= 1:
+ print
+ print 'Pass 2: Importing to Blender.'
+ print
+
+ import_time = Blender.sys.time()
+ db.blender_import()
+ import_time = Blender.sys.time() - import_time
+
+ Blender.Window.ViewLayer(range(1,21))
+
+ # FIX UP AFTER DUMMY VERT AND REMOVE DOUBLES
+ Blender.Mesh.Mode(Blender.Mesh.SelectModes['VERTEX'])
+ for ob in Blender.Object.GetSelected():
+ if ob.getType()=='Mesh':
+ me=ob.getData(mesh=1)
+ me.verts.delete(0) # remove the dummy vert
+ me.sel= 1
+ me.remDoubles(0.0001)
+
+
+
+ Blender.Window.RedrawAll()
+
+ if global_prefs['verbose'] >= 1:
+ print 'Done.'
+ print
+ print 'Time to parse file: %.3f seconds' % load_time
+ print 'Time to import to blender: %.3f seconds' % import_time
+ print 'Total time: %.3f seconds' % (load_time + import_time)
+
+ Blender.Window.WaitCursor(False)
+
+
+if global_prefs['verbose'] >= 1:
+ print
+ print 'OpenFlight Importer'
+ print 'Version:', __version__
+ print 'Author: Greg MacDonald'
+ print __url__[2]
+ print
+
+
+if __name__ == '__main__':
+ Blender.Window.FileSelector(select_file, "Import OpenFlight", "*.flt")
+ #select_file('/Anti_tank_D30.flt')
+ #select_file('/metavr/file_examples/flt/cherrypoint/CherryPoint_liter_runway.flt')
+ \ No newline at end of file