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:
Diffstat (limited to 'release/scripts/flt_import.py')
-rw-r--r--release/scripts/flt_import.py2534
1 files changed, 0 insertions, 2534 deletions
diff --git a/release/scripts/flt_import.py b/release/scripts/flt_import.py
deleted file mode 100644
index f8d31f7bb57..00000000000
--- a/release/scripts/flt_import.py
+++ /dev/null
@@ -1,2534 +0,0 @@
-#!BPY
-""" Registration info for Blender menus:
-Name: 'OpenFlight (.flt)...'
-Blender: 245
-Group: 'Import'
-Tip: 'Import OpenFlight (.flt)'
-"""
-
-
-
-__author__ = "Greg MacDonald, Campbell Barton, Geoffrey Bantle"
-__version__ = "2.0 11/21/07"
-__url__ = ("blender", "blenderartists.org", "Author's homepage, http://sourceforge.net/projects/blight/")
-__bpydoc__ = """\
-This script imports OpenFlight files into Blender. OpenFlight is a
-registered trademark of MultiGen-Paradigm, Inc.
-
-Feature overview and more availible at:
-http://wiki.blender.org/index.php/Scripts/Manual/Import/openflight_fltss
-
-Note: This file is a grab-bag of old and new code. It needs some cleanup still.
-"""
-
-# flt_import.py is an OpenFlight importer for blender.
-# Copyright (C) 2005 Greg MacDonald, 2007 Blender Foundation
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-
-import Blender
-import os
-import BPyMesh
-import BPyImage
-import flt_filewalker
-import flt_properties
-import sys
-reload(flt_properties)
-from flt_properties import *
-
-#Globals. Should Clean these up and minimize their usage.
-
-typecodes = ['c','C','s','S','i','I','f','d','t']
-records = dict()
-
-FLTBaseLabel = None
-FLTBaseString = None
-FLTBaseChooser = None
-FLTExport = None
-FLTClose = None
-FLTDoXRef = None
-FLTScale = None
-FLTShadeImport = None
-FLTAttrib = None
-FLTWarn = None
-
-Vector= Blender.Mathutils.Vector
-FLOAT_TOLERANCE = 0.01
-
-FF = flt_filewalker.FileFinder()
-current_layer = 0x01
-
-global_prefs = dict()
-global_prefs['verbose']= 4
-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']= ''
-global_prefs['smoothshading'] = 1
-global_prefs['doxrefs'] = 1
-global_prefs['scale'] = 1.0
-global_prefs['attrib'] = 0
-msg_once = False
-
-reg = Blender.Registry.GetKey('flt_import',1)
-if reg:
- for key in global_prefs:
- if reg.has_key(key):
- global_prefs[key] = reg[key]
-
-
-
-throw_back_opcodes = [2, 73, 4, 11, 96, 14, 91, 98, 63,111] # Opcodes that indicate its time to return control to parent.
-do_not_report_opcodes = [76, 78, 79, 80, 81, 82, 94, 83, 33, 112, 101, 102, 97, 31, 103, 104, 117, 118, 120, 121, 124, 125]
-
-#Process FLT record definitions
-for record in FLT_Records:
- props = dict()
- for prop in FLT_Records[record]:
- position = ''
- slice = 0
- (format,name) = prop.split('!')
- for i in format:
- if i not in typecodes:
- position = position + i
- slice = slice + 1
- else:
- break
- type = format[slice:]
- length = type[1:]
- if len(length) == 0:
- length = 1
- else:
- type = type[0]
- length = int(length)
-
- props[int(position)] = (type,length,prop)
- records[record] = props
-
-def col_to_gray(c):
- return 0.3*c[0] + 0.59*c[1] + 0.11*c[2]
-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 = 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'])
-
-class VertexDesc:
- def make_key(self):
- return round(self.x, 6), round(self.y, 6), round(self.z, 6)
-
- def __init__(self):
-
- # Assign later, save memory, all verts have a loc
- self.x = 0.0
- self.y = 0.0
- self.z = 0.0
-
-
- self.nx = 0.0
- self.ny = 0.0
- self.nz = 0.0
-
- self.uv= Vector(0,0)
- self.cindex = 127 #default/lowest
- self.cnorm = False
-
-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})
-
-class GlobalResourceRepository:
- def request_lightpoint_app(self, desc, scene):
- 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.objects.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()
-
- # Dont use request_vert - faster to make it from the vector direct.
- """
- 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)
- ''' IGNORE_NORMALS
- 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 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):
-
- #list of scenes xrefs belong to.
- self.xrefs = dict()
- # 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()
-
-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.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 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 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 '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 parse_extension(self):
- extension = dict()
- props = records[100]
- propkeys = props.keys()
- propkeys.sort()
- for position in propkeys:
- (type,length,name) = props[position]
- extension[name] = read_prop(self.header.fw,type,length)
- #read extension data.
- dstring = list()
- for i in xrange(self.header.fw.get_length()-24):
- dstring.append(self.header.fw.read_char())
- extension['data'] = dstring
- self.extension = extension
- def parse_record(self):
- self.props['type'] = self.opcode
- props = records[self.opcode]
- propkeys = props.keys()
- propkeys.sort()
- for position in propkeys:
- (type,length,name) = props[position]
- self.props[name] = read_prop(self.header.fw,type,length)
- try: #remove me!
- self.props['id'] = self.props['3t8!id']
- except:
- pass
- 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 __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()
-
-
- def blender_import(self):
- self.blender_verts.extend([Vector(vert_desc.x, vert_desc.y, vert_desc.z) for vert_desc in self.vert_desc_lst ])
-
- def parse_vertex_common(self):
- # Add this vertex to an offset to index dictionary.
- #self.index_lst.append( (self.offset, self.next_index) )
- self.index[self.offset]= len(self.index)
-
- # 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) #skip packed color
- v.cindex = self.header.fw.read_uint()
- 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.cnorm = True
- 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.uv[:] = self.header.fw.read_float(), self.header.fw.read_float()
-
- self.parse_vertex_post_common(v)
-
- return True
-
- def parse_vertex_cnuv(self):
- v = self.parse_vertex_common()
- v.cnorm = True
- v.nx = self.header.fw.read_float()
- v.ny = self.header.fw.read_float()
- v.nz = self.header.fw.read_float()
-
- v.uv[:] = self.header.fw.read_float(), self.header.fw.read_float()
-
- self.parse_vertex_post_common(v)
-
- return True
-
- def parse(self): # Run once per import
- Node.parse(self)
-
-
-class InterNode(Node):
- def __init__(self):
- self.object = None
- self.mesh = None
- self.swapmesh = None
- self.hasMesh = False
- self.faceLs= []
- self.matrix = None
- self.vis = True
- self.hasmtex = False
- self.uvlayers = dict()
- self.blayernames = dict()
- self.subfacelevel = 0
- self.extension = None
-
- mask = 2147483648
- for i in xrange(7):
- self.uvlayers[mask] = False
- mask = mask / 2
-
- #######################################################
- ## Begin Remove Doubles Replacement ##
- #######################################################
- def __xvertsort(self,__a,__b):
- (__vert, __x1) = __a
- (__vert2,__x2) = __b
-
- if __x1 > __x2:
- return 1
- elif __x1 < __x2:
- return -1
- return 0
- def __calcFaceNorm(self,__face):
- if len(__face) == 3:
- return Blender.Mathutils.TriangleNormal(__face[0].co, __face[1].co, __face[2].co)
- elif len(__face) == 4:
- return Blender.Mathutils.QuadNormal(__face[0].co, __face[1].co, __face[2].co, __face[3].co)
-
- def __replaceFaceVert(self,__weldface, __oldvert, __newvert):
- __index = None
- for __i, __v in enumerate(__weldface):
- if __v == __oldvert:
- __index = __i
- break
- __weldface[__index] = __newvert
-
- def __matchEdge(self,__weldmesh, __edge1, __edge2):
- if __edge1[0] in __weldmesh['Vertex Disk'][__edge2[1]] and __edge1[1] in __weldmesh['Vertex Disk'][__edge2[0]]:
- return True
- return False
- #have to compare original faces!
- def __faceWinding(self, __weldmesh, __face1, __face2):
-
- __f1edges = list()
- __f2edges = list()
-
- __f1edges.append((__face1.verts[0], __face1.verts[1]))
- __f1edges.append((__face1.verts[1], __face1.verts[2]))
- if len(__face1.verts) == 3:
- __f1edges.append((__face1.verts[2], __face1.verts[0]))
- else:
- __f1edges.append((__face1.verts[2], __face1.verts[3]))
- __f1edges.append((__face1.verts[3], __face1.verts[0]))
-
- __f2edges.append((__face2.verts[0], __face2.verts[1]))
- __f2edges.append((__face2.verts[1], __face2.verts[2]))
- if len(__face2.verts) == 3:
- __f2edges.append((__face2.verts[2], __face2.verts[0]))
- else:
- __f2edges.append((__face2.verts[2], __face2.verts[3]))
- __f2edges.append((__face2.verts[3], __face2.verts[0]))
-
-
- #find a matching edge
- for __edge1 in __f1edges:
- for __edge2 in __f2edges:
- if self.__matchEdge(__weldmesh, __edge1, __edge2): #no more tests nessecary
- return True
-
- return False
-
- def __floatcompare(self, __f1, __f2):
- epsilon = 0.1
- if ((__f1 + epsilon) > __f2) and ((__f1 - epsilon) < __f2):
- return True
- return False
- def __testFace(self,__weldmesh,__v1face, __v2face, __v1bface, __v2bface):
- limit = 0.01
- __matchvert = None
- #frst test (for real this time!). Are the faces the same face?
- if __v1face == __v2face:
- return False
-
- #first test: Do the faces possibly geometrically share more than two vertices? we should be comparing original faces for this? - Yes.....
- __match = 0
- for __vert in __v1bface.verts:
- for __vert2 in __v2bface.verts:
- #if (abs(__vert.co[0] - __vert2.co[0]) <= limit) and (abs(__vert.co[1] - __vert2.co[1]) <= limit) and (abs(__vert.co[2] - __vert2.co[2]) <= limit): #this needs to be fixed!
- if __vert2 in __weldmesh['Vertex Disk'][__vert] or __vert == __vert2:
- __match += 1
- __matchvert = __vert2
- #avoid faces sharing more than two verts
- if __match > 2:
- return False
-
- #consistent winding for face normals
- if __match == 2:
- if not self.__faceWinding(__weldmesh, __v1bface, __v2bface):
- return False
-
- #second test: Compatible normals.Anything beyond almost exact opposite is 'ok'
- __v1facenorm = self.__calcFaceNorm(__v1face)
- __v2facenorm = self.__calcFaceNorm(__v2face)
-
- #dont even mess with zero length faces
- if __v1facenorm.length < limit:
- return False
- if __v2facenorm.length < limit:
- return False
-
- __v1facenorm.normalize()
- __v2facenorm.normalize()
-
- if __match == 1:
- #special case, look for comparison of normals angle
- __angle = Blender.Mathutils.AngleBetweenVecs(__v1facenorm, __v2facenorm)
- if __angle > 70.0:
- return False
-
-
-
- __v2facenorm = __v2facenorm.negate()
-
- if self.__floatcompare(__v1facenorm[0], __v2facenorm[0]) and self.__floatcompare(__v1facenorm[1], __v2facenorm[1]) and self.__floatcompare(__v1facenorm[2], __v2facenorm[2]):
- return False
-
- #next test: dont weld a subface to a non-subface!
- if __v1bface.getProperty("FLT_SFLEVEL") != __v2bface.getProperty("FLT_SFLEVEL"):
- return False
-
- #final test: edge test - We dont want to create a non-manifold edge through our weld operation
-
- return True
-
- def __copyFaceData(self, __source, __target):
- #copy vcolor layers.
- __actColLayer = self.mesh.activeColorLayer
- for __colorlayer in self.mesh.getColorLayerNames():
- self.mesh.activeColorLayer = __colorlayer
- for __i, __col in enumerate(__source.col):
- __target.col[__i].r = __col.r
- __target.col[__i].g = __col.g
- __target.col[__i].b = __col.b
-
- self.mesh.activeColorLayer = __actColLayer
- #copy uv layers.
- __actUVLayer = self.mesh.activeUVLayer
- for __uvlayer in self.mesh.getUVLayerNames():
- self.mesh.activeUVLayer = __uvlayer
- __target.image = __source.image
- __target.mode = __source.mode
- __target.smooth = __source.smooth
- __target.transp = __source.transp
- for __i, __uv in enumerate(__source.uv):
- __target.uv[__i][0] = __uv[0]
- __target.uv[__i][1] = __uv[1]
-
- self.mesh.activeUVLayer = __actUVLayer
- #copy property layers
- for __property in self.mesh.faces.properties:
- __target.setProperty(__property, __source.getProperty(__property))
-
- def findDoubles(self):
- limit = 0.01
- sortblock = list()
- double = dict()
- for vert in self.mesh.verts:
- double[vert] = None
- sortblock.append((vert, vert.co[0] + vert.co[1] + vert.co[2]))
- sortblock.sort(self.__xvertsort)
-
- a = 0
- while a < len(self.mesh.verts):
- (vert,xsort) = sortblock[a]
- b = a+1
- if not double[vert]:
- while b < len(self.mesh.verts):
- (vert2, xsort2) = sortblock[b]
- if not double[vert2]:
- #first test, simple distance
- if (xsort2 - xsort) > limit:
- break
- #second test, more expensive
- if (abs(vert.co[0] - vert2.co[0]) <= limit) and (abs(vert.co[1] - vert2.co[1]) <= limit) and (abs(vert.co[2] - vert2.co[2]) <= limit):
- double[vert2] = vert
- b+=1
- a+=1
-
- return double
-
- def buildWeldMesh(self):
-
- weldmesh = dict()
- weldmesh['Vertex Disk'] = dict() #this is geometric adjacency
- weldmesh['Vertex Faces'] = dict() #topological adjacency
-
- #find the doubles for this mesh
- double = self.findDoubles()
-
- for vert in self.mesh.verts:
- weldmesh['Vertex Faces'][vert] = list()
-
- #create weld faces
- weldfaces = list()
- originalfaces = list()
- for face in self.mesh.faces:
- weldface = list()
- for vert in face.verts:
- weldface.append(vert)
- weldfaces.append(weldface)
- originalfaces.append(face)
- for i, weldface in enumerate(weldfaces):
- for vert in weldface:
- weldmesh['Vertex Faces'][vert].append(i)
- weldmesh['Weld Faces'] = weldfaces
- weldmesh['Original Faces'] = originalfaces
-
- #Now we need to build the vertex disk data. first we do just the 'target' vertices
- for vert in self.mesh.verts:
- if not double[vert]: #its a target
- weldmesh['Vertex Disk'][vert] = list()
- for vert in self.mesh.verts:
- if double[vert]: #its a double
- weldmesh['Vertex Disk'][double[vert]].append(vert)
-
- #Now we need to create the disk information for the remaining vertices
- targets = weldmesh['Vertex Disk'].keys()
- for target in targets:
- for doublevert in weldmesh['Vertex Disk'][target]:
- weldmesh['Vertex Disk'][doublevert] = [target]
- for othervert in weldmesh['Vertex Disk'][target]:
- if othervert != doublevert:
- weldmesh['Vertex Disk'][doublevert].append(othervert)
-
- return weldmesh
-
- def weldFuseFaces(self,weldmesh):
-
- #retain original loose vertices
- looseverts = dict()
- for vert in self.mesh.verts:
- looseverts[vert] = 0
- for edge in self.mesh.edges:
- looseverts[edge.v1] += 1
- looseverts[edge.v2] += 1
-
-
-
- #slight modification here: we need to walk around the mesh as many times as it takes to have no more matches
- done = 0
- while not done:
- done = 1
- for windex, weldface in enumerate(weldmesh['Weld Faces']):
- for vertex in weldface:
- #we walk around the faces of the doubles of this vertex and if possible, we weld them.
- for doublevert in weldmesh['Vertex Disk'][vertex]:
- removeFaces = list() #list of faces to remove from doubleverts face list
- for doublefaceindex in weldmesh['Vertex Faces'][doublevert]:
- doubleface = weldmesh['Weld Faces'][doublefaceindex]
- oface1 = self.mesh.faces[windex]
- oface2 = self.mesh.faces[doublefaceindex]
- ok = self.__testFace(weldmesh, weldface, doubleface, oface1, oface2)
- if ok:
- done = 0
- removeFaces.append(doublefaceindex)
- self.__replaceFaceVert(doubleface, doublevert, vertex)
- for doublefaceindex in removeFaces:
- weldmesh['Vertex Faces'][doublevert].remove(doublefaceindex)
- #old faces first
- oldindices = list()
- for face in self.mesh.faces:
- oldindices.append(face.index)
- #make our new faces.
- newfaces = list()
- for weldface in weldmesh['Weld Faces']:
- newfaces.append(weldface)
- newindices = self.mesh.faces.extend(newfaces, indexList=True, ignoreDups=True)
- #copy custom data over
- for i, newindex in enumerate(newindices):
- try:
- self.__copyFaceData(self.mesh.faces[oldindices[i]], self.mesh.faces[newindex])
- except:
- print "warning, could not copy face data!"
- #delete the old faces
- self.mesh.faces.delete(1, oldindices)
-
- #Clean up stray vertices
- vertuse = dict()
- for vert in self.mesh.verts:
- vertuse[vert] = 0
- for face in self.mesh.faces:
- for vert in face.verts:
- vertuse[vert] += 1
- delverts = list()
- for vert in self.mesh.verts:
- if not vertuse[vert] and vert.index != 0 and looseverts[vert]:
- delverts.append(vert)
-
- self.mesh.verts.delete(delverts)
-
-
- #######################################################
- ## End Remove Doubles Replacement ##
- #######################################################
-
- def blender_import_my_faces(self):
-
- # Add the verts onto the mesh
- blender_verts= self.header.vert_pal.blender_verts
- vert_desc_lst= self.header.vert_pal.vert_desc_lst
-
- vert_list= [ i for flt_face in self.faceLs for i in flt_face.indices] #splitting faces apart. Is this a good thing?
- face_edges= []
- face_verts= []
- self.mesh.verts.extend([blender_verts[i] for i in vert_list])
-
- new_faces= []
- new_faces_props= []
- ngon= BPyMesh.ngon
- vert_index= 1
-
- #add vertex color layer for baked face colors.
- self.mesh.addColorLayer("FLT_Fcol")
- self.mesh.activeColorLayer = "FLT_Fcol"
-
- FLT_OrigIndex = 0
- for flt_face in self.faceLs:
- if flt_face.tex_index != -1:
- try:
- image= self.header.tex_pal[flt_face.tex_index][1]
- except KeyError:
- image= None
- else:
- image= None
- face_len= len(flt_face.indices)
-
- #create dummy uvert dicts
- if len(flt_face.uverts) == 0:
- for i in xrange(face_len):
- flt_face.uverts.append(dict())
- #May need to patch up MTex info
- if self.hasmtex:
- #For every layer in mesh, there should be corresponding layer in the face
- for mask in self.uvlayers.keys():
- if self.uvlayers[mask]:
- if not flt_face.uvlayers.has_key(mask): #Does the face have this layer?
- #Create Layer info for this face
- flt_face.uvlayers[mask] = dict()
- flt_face.uvlayers[mask]['texture index'] = -1
- flt_face.uvlayers[mask]['texture enviorment'] = 3
- flt_face.uvlayers[mask]['texture mapping'] = 0
- flt_face.uvlayers[mask]['texture data'] = 0
-
- #now go through and create dummy uvs for this layer
- for uvert in flt_face.uverts:
- uv = Vector(0.0,0.0)
- uvert[mask] = uv
-
- # Get the indicies in reference to the mesh.
- uvs= [vert_desc_lst[j].uv for j in flt_face.indices]
- if face_len == 1:
- pass
- elif face_len == 2:
- face_edges.append((vert_index, vert_index+1))
- elif flt_face.props['draw type'] == 2 or flt_face.props['draw type'] == 3:
- i = 0
- while i < (face_len-1):
- face_edges.append((vert_index + i, vert_index + i + 1))
- i = i + 1
- if flt_face.props['draw type'] == 2:
- face_edges.append((vert_index + i,vert_index))
- elif face_len == 3 or face_len == 4: # tri or quad
- #if face_len == 1:
- # pass
- #if face_len == 2:
- # face_edges.append((vert_index, vert_index+1))
- new_faces.append( [i+vert_index for i in xrange(face_len)] )
- new_faces_props.append((None, image, uvs, flt_face.uverts, flt_face.uvlayers, flt_face.color_index, flt_face.props,FLT_OrigIndex,0, flt_face.subfacelevel))
-
- else: # fgon
- mesh_face_indicies = [i+vert_index for i in xrange(face_len)]
- tri_ngons= ngon(self.mesh, mesh_face_indicies)
- if len(tri_ngons) != 1:
- new_faces.extend([ [mesh_face_indicies[t] for t in tri] for tri in tri_ngons])
- new_faces_props.extend( [ (None, image, (uvs[tri[0]], uvs[tri[1]], uvs[tri[2]]), [flt_face.uverts[tri[0]], flt_face.uverts[tri[1]], flt_face.uverts[tri[2]]], flt_face.uvlayers, flt_face.color_index, flt_face.props,FLT_OrigIndex,1, flt_face.subfacelevel) for tri in tri_ngons ])
-
- vert_index+= face_len
- FLT_OrigIndex+=1
-
- self.mesh.faces.extend(new_faces)
- self.mesh.edges.extend(face_edges)
-
- #add in the FLT_ORIGINDEX layer
- if len(self.mesh.faces):
- try: self.mesh.faceUV= True
- except: pass
-
- if self.mesh.faceUV == True:
- self.mesh.renameUVLayer(self.mesh.activeUVLayer, 'Layer0')
-
- #create name layer for faces
- self.mesh.faces.addPropertyLayer("FLT_ID",Blender.Mesh.PropertyTypes["STRING"])
- #create layer for face color indices
- self.mesh.faces.addPropertyLayer("FLT_COL",Blender.Mesh.PropertyTypes["INT"])
- #create index layer for faces. This is needed by both FGONs and subfaces
- self.mesh.faces.addPropertyLayer("FLT_ORIGINDEX",Blender.Mesh.PropertyTypes["INT"])
- #create temporary FGON flag layer. Delete after remove doubles
- self.mesh.faces.addPropertyLayer("FLT_FGON",Blender.Mesh.PropertyTypes["INT"])
- self.mesh.faces.addPropertyLayer("FLT_SFLEVEL", Blender.Mesh.PropertyTypes["INT"])
-
- for i, f in enumerate(self.mesh.faces):
- props = new_faces_props[i]
- if props[6]['template billboard'] > 0:
- f.transp |= Blender.Mesh.FaceTranspModes["ALPHA"]
- if props[6]['template billboard'] == 2:
- f.mode |= Blender.Mesh.FaceModes["BILLBOARD"]
- f.mode |= Blender.Mesh.FaceModes["LIGHT"]
- if props[6]['draw type'] == 1:
- f.mode |= Blender.Mesh.FaceModes["TWOSIDE"]
-
- #f.mat = props[0]
- f.image = props[1]
- f.uv = props[2]
- #set vertex colors
- color = self.header.get_color(props[5])
- if not color:
- color = [255,255,255,255]
- for mcol in f.col:
- mcol.a = color[3]
- mcol.r = color[0]
- mcol.g = color[1]
- mcol.b = color[2]
-
- f.setProperty("FLT_SFLEVEL", props[9])
- f.setProperty("FLT_ORIGINDEX",i)
- f.setProperty("FLT_ID",props[6]['id'])
- #if props[5] > 13199:
- # print "Warning, invalid color index read in! Using default!"
- # f.setProperty("FLT_COL",127)
- #else:
- if(1): #uh oh....
- value = struct.unpack('>i',struct.pack('>I',props[5]))[0]
- f.setProperty("FLT_COL",value)
-
- #if props[8]:
- # f.setProperty("FLT_FGON",1)
- #else:
- # f.setProperty("FLT_FGON",0)
-
-
- #Create multitex layers, if present.
- actuvlayer = self.mesh.activeUVLayer
- if(self.hasmtex):
- #For every multi-tex layer, we have to add a new UV layer to the mesh
- for i,mask in enumerate(reversed(sorted(self.uvlayers))):
- if self.uvlayers[mask]:
- self.blayernames[mask] = "Layer" + str(i+1)
- self.mesh.addUVLayer(self.blayernames[mask])
-
- #Cycle through availible multi-tex layers and add face UVS
- for mask in self.uvlayers:
- if self.uvlayers[mask]:
- self.mesh.activeUVLayer = self.blayernames[mask]
- for j, f in enumerate(self.mesh.faces):
- if props[6]['draw type'] == 1:
- f.mode |= Blender.Mesh.FaceModes["TWOSIDE"]
- f.transp |= Blender.Mesh.FaceTranspModes["ALPHA"]
- f.mode |= Blender.Mesh.FaceModes["LIGHT"]
- props = new_faces_props[j]
- uvlayers = props[4]
- if uvlayers.has_key(mask): #redundant
- uverts = props[3]
- for k, uv in enumerate(f.uv):
- uv[0] = uverts[k][mask][0]
- uv[1] = uverts[k][mask][1]
-
- uvlayer = uvlayers[mask]
- tex_index = uvlayer['texture index']
- if tex_index != -1:
- try:
- f.image = self.header.tex_pal[tex_index][1]
- except KeyError:
- f.image = None
-
- if global_prefs['smoothshading'] == True and len(self.mesh.faces):
- #We need to store per-face vertex normals in the faces as UV layers and delete them later.
- self.mesh.addUVLayer("FLTNorm1")
- self.mesh.addUVLayer("FLTNorm2")
- self.mesh.activeUVLayer = "FLTNorm1"
- for f in self.mesh.faces:
- f.smooth = 1
- #grab the X and Y components of normal and store them in UV
- for i, uv in enumerate(f.uv):
- vert = f.v[i].index
- vert_desc = vert_desc_lst[vert_list[vert-1]]
- if vert_desc.cnorm:
- uv[0] = vert_desc.nx
- uv[1] = vert_desc.ny
- else:
- uv[0] = 0.0
- uv[1] = 0.0
-
- #Now go through and populate the second UV Layer with the z component
- self.mesh.activeUVLayer = "FLTNorm2"
- for f in self.mesh.faces:
- for i, uv in enumerate(f.uv):
- vert = f.v[i].index
- vert_desc = vert_desc_lst[vert_list[vert-1]]
- if vert_desc.cnorm:
- uv[0] = vert_desc.nz
- uv[1] = 0.0
- else:
- uv[0] = 0.0
- uv[1] = 0.0
-
-
-
- #Finally, go through, remove dummy vertex, remove doubles and add edgesplit modifier.
- Blender.Mesh.Mode(Blender.Mesh.SelectModes['VERTEX'])
- self.mesh.sel= 1
- self.header.scene.update(1) #slow!
-
- #self.mesh.remDoubles(0.0001)
- weldmesh = self.buildWeldMesh()
- welded = self.weldFuseFaces(weldmesh)
- self.mesh.verts.delete(0) # remove the dummy vert
-
- edgeHash = dict()
-
- for edge in self.mesh.edges:
- edgeHash[edge.key] = edge.index
-
-
- if global_prefs['smoothshading'] == True and len(self.mesh.faces):
-
- #rip out the custom vertex normals from the mesh and place them in a face aligned list. Easier to compare this way.
- facenorms = []
- self.mesh.activeUVLayer = "FLTNorm1"
- for face in self.mesh.faces:
- facenorm = []
- for uv in face.uv:
- facenorm.append(Vector(uv[0],uv[1],0.0))
- facenorms.append(facenorm)
- self.mesh.activeUVLayer = "FLTNorm2"
- for i, face in enumerate(self.mesh.faces):
- facenorm = facenorms[i]
- for j, uv in enumerate(face.uv):
- facenorm[j][2] = uv[0]
- self.mesh.removeUVLayer("FLTNorm1")
- self.mesh.removeUVLayer("FLTNorm2")
-
- #find hard edges
- #store edge data for lookup by faces
- #edgeHash = dict()
- #for edge in self.mesh.edges:
- # edgeHash[edge.key] = edge.index
-
- edgeNormHash = dict()
- #make sure to align the edgenormals to key value!
- for i, face in enumerate(self.mesh.faces):
-
- facenorm = facenorms[i]
- faceEdges = []
- faceEdges.append((face.v[0].index,face.v[1].index,facenorm[0],facenorm[1],face.edge_keys[0]))
- faceEdges.append((face.v[1].index,face.v[2].index,facenorm[1],facenorm[2],face.edge_keys[1]))
- if len(face.v) == 3:
- faceEdges.append((face.v[2].index,face.v[0].index,facenorm[2],facenorm[0],face.edge_keys[2]))
- elif len(face.v) == 4:
- faceEdges.append((face.v[2].index,face.v[3].index,facenorm[2],facenorm[3],face.edge_keys[2]))
- faceEdges.append((face.v[3].index,face.v[0].index,facenorm[3],facenorm[0],face.edge_keys[3]))
-
- #check to see if edgeNormal has been placed in the edgeNormHash yet
- #this is a redundant test, and should be optimized to not be called as often as it is.
- for j, faceEdge in enumerate(faceEdges):
- #the value we are looking for is (faceEdge[2],faceEdge[3])
- hashvalue = (faceEdge[2],faceEdge[3])
- if (faceEdge[0],faceEdge[1]) != faceEdge[4]:
- hashvalue = (hashvalue[1],hashvalue[0])
- assert (faceEdge[1],faceEdge[0]) == faceEdge[4]
- if edgeNormHash.has_key(faceEdge[4]):
- #compare value in the hash, if different, mark as sharp
- edgeNorm = edgeNormHash[faceEdge[4]]
- if\
- abs(hashvalue[0][0] - edgeNorm[0][0]) > FLOAT_TOLERANCE or\
- abs(hashvalue[0][1] - edgeNorm[0][1]) > FLOAT_TOLERANCE or\
- abs(hashvalue[0][2] - edgeNorm[0][2]) > FLOAT_TOLERANCE or\
- abs(hashvalue[1][0] - edgeNorm[1][0]) > FLOAT_TOLERANCE or\
- abs(hashvalue[1][1] - edgeNorm[1][1]) > FLOAT_TOLERANCE or\
- abs(hashvalue[1][2] - edgeNorm[1][2]) > FLOAT_TOLERANCE:
- edge = self.mesh.edges[edgeHash[faceEdge[4]]]
- edge.flag |= Blender.Mesh.EdgeFlags.SHARP
-
- else:
- edgeNormHash[faceEdge[4]] = hashvalue
-
- #add in edgesplit modifier
- mod = self.object.modifiers.append(Blender.Modifier.Types.EDGESPLIT)
- mod[Blender.Modifier.Settings.EDGESPLIT_FROM_SHARP] = True
- mod[Blender.Modifier.Settings.EDGESPLIT_FROM_ANGLE] = False
-
- if(actuvlayer):
- self.mesh.activeUVLayer = actuvlayer
-
- def blender_import(self):
- if self.vis and self.parent.object:
- self.vis = self.parent.vis
- name = self.props['id']
-
-
- if self.hasMesh:
- self.mesh = Blender.Mesh.New()
- self.mesh.name = 'FLT_FaceList'
- self.mesh.fakeUser = True
- self.mesh.verts.extend( Vector()) #DUMMYVERT
- self.object = self.header.scene.objects.new(self.mesh)
- else:
- self.object = self.header.scene.objects.new('Empty')
-
- self.object.name = name
- self.header.group.objects.link(self.object)
-
- #id props import
- self.object.properties['FLT'] = dict()
- for key in self.props:
- try:
- self.object.properties['FLT'][key] = self.props[key]
- except: #horrible...
- pass
-
-
- if self.extension:
- self.object.properties['FLT']['EXT'] = dict()
- for key in self.extension:
- self.object.properties['FLT']['EXT'][key] = self.extension[key]
-
- if self.parent and self.parent.object and (self.header.scene == self.parent.header.scene):
- self.parent.object.makeParent([self.object],1)
-
- if self.matrix:
- self.object.setMatrix(self.matrix)
-
- if self.vis == False:
- self.object.restrictDisplay = True
- self.object.restrictRender = True
-
- else: #check for LOD children and set the proper flags
- lodlist = list()
- for child in self.children:
- if child.props.has_key('type') and child.props['type'] == 73:
- if child.props['6d!switch out'] != 0.0:
- child.vis = False
- #lodlist.append(child)
-
- #def LODmin(a,b):
- # if a.props['5d!switch in'] < b.props['5d!switch in']:
- # return a
- # return b
-
- #min= None
- #if len(lodlist) > 1:
- # for lod in lodlist:
- # lod.vis = False
- # min = lodlist[0]
- # for i in xrange(len(lodlist)):
- # min= LODmin(min,lodlist[i])
- # min.vis = True
-
-
- Node.blender_import(self) # Attach faces to self.faceLs
-
- if self.hasMesh:
- # Add all my faces into the mesh at once
- self.blender_import_my_faces()
-
- def parse_face(self):
- child = Face(self, self.subfacelevel)
- 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_dof(self):
- child = DOF(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 parse_subpush(self):
- self.parse_push()
- self.subfacelevel+= 1
- return True
- def parse_subpop(self):
- self.parse_pop()
- self.subfacelevel -= 1
- return True
-
-
-
-class Face(Node):
- def __init__(self, parent,subfacelevel):
- Node.__init__(self, parent, parent.header)
- self.root_handler.set_handler({31: self.parse_comment,
- 10: self.parse_push,
- 52: self.parse_multitex})
- 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,
- 53: self.parse_uvlist})
-
- if parent:
- parent.hasMesh = True
-
- self.subfacelevel = subfacelevel
- self.indices = list() # face verts here
- self.uvlayers = dict() # MultiTexture layers keyed to layer bitmask.
- self.uverts = list() # Vertex aligned list of dictionaries keyed to layer bitmask.
- self.uvmask = 0 # Bitfield read from MTex record
-
- self.comment = ''
- self.props = dict()
- self.props['id'] = self.header.fw.read_string(8)
- # 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 parse_comment(self):
- self.comment = self.header.fw.read_string(self.header.fw.get_length()-4)
- return True
-
- def blender_import(self):
- vert_count = len(self.indices)
- if vert_count < 1:
- if global_prefs['verbose'] >= 2:
- print 'Warning: Ignoring face with no vertices.'
- return
-
- # Assign material and image
-
- self.parent.faceLs.append(self)
- #need to store comment in mesh prop layer!
-
- # 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
-
- if self.uvlayers:
- #Make sure that the mesh knows about the layers that this face uses
- self.parent.hasmtex = True
- for mask in self.uvlayers.keys():
- self.parent.uvlayers[mask] = True
-
- 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
-
- # If this ever fails the chunk below does error checking
- self.indices= [vert_pal.index[fw.read_int()] for i in xrange(count)]
- '''
- 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 parse_multitex(self):
- #Parse MultiTex Record.
- length = self.header.fw.get_length()
- fw = self.header.fw
- #num layers == (length - 8) / 4
- uvmask = fw.read_uint()
- mask = 2147483648
- for i in xrange(7):
- if mask & uvmask:
- uvlayer = dict()
- self.uvlayers[mask] = uvlayer
- mask = mask / 2
-
- #read in record for each individual layer.
- for key in reversed(sorted(self.uvlayers)):
- uvlayer = self.uvlayers[key]
- uvlayer['texture index'] = fw.read_ushort()
- uvlayer['texture enviorment'] = fw.read_ushort()
- uvlayer['texture mapping'] = fw.read_ushort()
- uvlayer['texture data'] = fw.read_ushort()
-
- self.uvmask = uvmask
-
- def parse_uvlist(self):
- #for each uvlayer, add uv vertices
- length = self.header.fw.get_length()
- fw = self.header.fw
- uvmask = fw.read_uint()
- if uvmask != self.uvmask: #This should never happen!
- fw.read_ahead(self.length - 4) #potentially unnessecary?
- else:
- #need to store in uvverts dictionary for each vertex.
- totverts = len(self.indices)
- for i in xrange(totverts):
- uvert = dict()
- for key in reversed(sorted(self.uvlayers)):
- uv = Vector(0.0,0.0)
- uv[0] = fw.read_float()
- uv[1] = fw.read_float()
- uvert[key] = uv
- self.uverts.append(uvert)
-
-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,
- 21: self.parse_push_extension,
- 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,
- 19: self.parse_subpush,
- 20: self.parse_subpop,
- 111: self.parse_inline_light_point,
- 10: self.parse_push,
- 11: self.parse_pop})
- self.extension_handler.set_handler({22: self.parse_pop_extension,
- 100: self.parse_extension})
-
- self.extension = dict()
- self.props = dict()
- self.props['comment'] = ''
- self.parse_record()
-
-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,
- 21: self.parse_push_extension})
- self.root_handler.set_throw_back_lst(throw_back_opcodes)
-
- self.child_handler.set_handler({5: self.parse_face,
- 19: self.parse_subpush,
- 20: self.parse_subpop,
- 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_dof,
- 91: self.parse_unhandled,
- 98: self.parse_unhandled,
- 63: self.parse_xref})
-
- self.extension_handler.set_handler({22: self.parse_pop_extension,
- 100: self.parse_extension})
-
- self.props = dict.fromkeys(['type', 'id', 'comment', 'priority', 'flags', 'special1',
- 'special2', 'significance', 'layer code', 'loop count',
- 'loop duration', 'last frame duration'])
-
- self.props['comment'] = ''
- self.parse_record()
-
- #self.props['type'] = str(self.opcode) + ':' + opcode_name[self.opcode]
- #props = records[self.opcode]
- #propkeys = props.keys()
- #propkeys.sort()
- #for position in propkeys:
- # (type,length,name) = props[position]
- # self.props[name] = read_prop(self.header.fw,type,length)
- #self.props['id'] = self.props['3t8!id']
-
-class DOF(InterNode):
- def blender_import(self):
- 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,
- 21: self.parse_push_extension})
- 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_dof,
- 91: self.parse_unhandled,
- 98: self.parse_unhandled,
- 63: self.parse_xref})
- self.extension_handler.set_handler({22: self.parse_pop_extension,
- 100: self.parse_extension})
- self.props = dict()
- self.props['comment'] = ''
- self.parse_record()
-
-
-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)
-
- self.props = dict()
- self.props['comment'] = ''
- self.parse_record()
-
- xref_filename = self.props['3t200!filename'] #I dont even think there is a reason to keep this around...
-
- if not os.path.isabs(xref_filename):
- absname = os.path.join(os.path.dirname(self.header.filename), xref_filename)
- else:
- absname = xref_filename
-
- self.props['id'] = 'X: ' + Blender.sys.splitext(Blender.sys.basename(xref_filename))[0] #this is really wrong as well....
-
- if global_prefs['doxrefs'] and os.path.exists(absname) and not self.header.grr.xrefs.has_key(xref_filename):
- self.xref = Database(absname, self.header.grr, self)
- self.header.grr.xrefs[xref_filename] = self.xref
- else:
- self.xref = None
-
-
- def blender_import(self):
- #name = self.props['type'] + ': ' + self.props['id']
- name = self.props['id']
- self.object = self.header.scene.objects.new('Empty')
- self.object.name = name
- self.object.enableDupGroup = True
- self.header.group.objects.link(self.object)
-
- #for broken links its ok to leave this empty! they purely for visual purposes anyway.....
- try:
- self.object.DupGroup = self.header.grr.xrefs[self.props['3t200!filename']].group
- except:
- pass
-
-
-
-
- if self.parent and self.parent.object:
- self.parent.object.makeParent([self.object],1)
-
- if self.matrix:
- self.object.setMatrix(self.matrix)
-
-
- #id props import
- self.object.properties['FLT'] = dict()
- for key in self.props:
- try:
- self.object.properties['FLT'][key] = self.props[key]
- except: #horrible...
- pass
-
- self.object.Layer = current_layer
- self.object.sel = 1
-
- Node.blender_import(self)
-
-
-class LOD(InterNode):
- def blender_import(self):
- #self.move_to_next_layer()
- InterNode.blender_import(self)
- #self.object.properties['FLT'] = self.props.copy()
-
- 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,
- 21: self.parse_push_extension})
- self.root_handler.set_throw_back_lst(throw_back_opcodes)
-
- self.child_handler.set_handler({2: self.parse_group,
- 111: self.parse_inline_light_point,
- 73: self.parse_lod,
- 4: self.parse_object,
- 10: self.parse_push,
- 11: self.parse_pop,
- 96: self.parse_unhandled, # switch
- 14: self.parse_dof, # DOF
- 91: self.parse_unhandled, # sound
- 98: self.parse_unhandled, # clip
- 63: self.parse_xref})
- self.extension_handler.set_handler({22: self.parse_pop_extension,
- 100: self.parse_extension})
-
-
- self.props = dict()
- self.props['comment'] = ''
- self.parse_record()
-
-class InlineLightPoint(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,
- 21: self.parse_push_extension,
- 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.extension_handler.set_handler({22: self.parse_pop_extension,
- 100: self.parse_extension})
-
- self.indices = list()
- self.props = dict()
- self.props['comment'] = ''
- self.parse_record()
-
-
- def blender_import(self):
-
-
- name = self.props['id']
- self.mesh= Blender.Mesh.New()
- self.mesh.name = 'FLT_LP'
- self.object = self.header.scene.objects.new(self.mesh)
- self.object.name = name
- #self.mesh.verts.extend(Vector() ) # DUMMYVERT
- self.object.Layer = current_layer
- self.object.sel= 1
-
- self.object.properties['FLT'] = dict()
- for key in self.props:
- try:
- self.object.properties['FLT'][key] = self.props[key]
- except: #horrible...
- pass
-
- if self.extension:
- self.object.properties['FLT']['EXT'] = dict()
- for key in self.extension:
- self.object.properties['FLT']['EXT'][key] = self.extension[key]
-
- if self.parent and self.parent.object and self.header.scene == self.parent.header.scene:
- self.parent.object.makeParent([self.object])
-
- if self.matrix:
- self.object.setMatrix(self.matrix)
-
- self.mesh.verts.extend([self.header.vert_pal.blender_verts[i] for i in self.indices])
-
- #add color index information.
- self.mesh.verts.addPropertyLayer("FLT_VCOL",Blender.Mesh.PropertyTypes["INT"])
- for i, vindex in enumerate(self.indices):
- vdesc = self.header.vert_pal.vert_desc_lst[vindex]
- v = self.mesh.verts[i]
- v.setProperty("FLT_VCOL",vdesc.cindex)
- #for i, v in enumerate(self.mesh.verts):
- # vdesc = self.header.vert_pal.vert_desc_lst[i]
- # v.setProperty("FLT_VCOL",vdesc.cindex)
- 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
-
- # If this ever fails the chunk below does error checking
- self.indices= [vert_pal.index[fw.read_int()] for i in xrange(count)]
-
- '''
- 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
-
-
-
-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 = self.header.grr.request_lightpoint_app(app_desc, self.header.scene)
-
- 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= Blender.Mesh.New()
- self.mesh.verts.extend( Vector() ) # DUMMYVERT
- 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)
-
- self.header.scene.objects.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
-
- # If this ever fails the chunk below does error checking
- self.indices= [vert_pal.index[fw.read_int()] for i in xrange(count)]
-
- '''
- 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_dof, # 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):
- for key in self.tex_pal.keys():
- path_filename= FF.find(self.tex_pal[key][0])
- if path_filename != None:
- img = self.grr.request_image(path_filename)
- if img:
- self.tex_pal[key][1] = img
- elif global_prefs['verbose'] >= 1:
- print 'Warning: Unable to find', self.tex_pal[key][0]
-
- self.scene.properties['FLT'] = dict()
- for key in self.props:
- try:
- self.scene.properties['FLT'][key] = self.props[key]
- except: #horrible...
- pass
-
- self.scene.properties['FLT']['Main'] = 0
- self.scene.properties['FLT']['Filename'] = self.bname
-
- for child in self.children:
- if child.props.has_key('type') and child.props['type'] == 73:
- if child.props['6d!switch out'] != 0.0:
- child.vis = False
-
- #import color palette
- carray = list()
- for color in self.col_pal:
- carray.append(struct.unpack('>i',struct.pack('>BBBB',color[0],color[1],color[2],color[3]))[0])
- self.scene.properties['FLT']['Color Palette'] = carray
- Node.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):
- color = None
- 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])
-
- 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[index]= [name, None]
- return True
-
- def read_attribute_files(self):
- for tex in self.tex_pal.keys():
- [name,image] = self.tex_pal[tex]
- basename = os.path.basename(name)
- if(image):
- basename = basename + ".attr"
- dirname = os.path.dirname(Blender.sys.expandpath(image.getFilename())) #can't rely on original info stored in pallette since it might be relative link
- newpath = os.path.join(dirname, basename)
- if os.path.exists(newpath) and not image.properties.has_key('FLT'):
- fw = flt_filewalker.FltIn(newpath)
- fw.read_ahead(8) #We dont care what the attribute file says about x/y dimensions
- image.properties['FLT']={}
-
- #need to steal code from parse records....
- props = records['Image']
- propkeys = props.keys()
- propkeys.sort()
- for position in propkeys:
- (type,length,name) = props[position]
- image.properties['FLT'][name] = read_prop(fw,type,length)
- fw.close_file()
-
- #copy clamp settings
- wrap = image.properties['FLT']['10i!Wrap']
- wrapu = image.properties['FLT']['11i!WrapU']
- wrapv = image.properties['FLT']['12i!WrapV']
-
- if wrapu == 3 or wrapv == 3:
- wrapuv = (wrap,wrap)
- else:
- wrapuv = (wrapu, wrapv)
- image.clampX = wrapuv[0]
- image.clampY = wrapuv[1]
-
- elif not os.path.exists(newpath):
- print "Cannot read attribute file:" + newpath
-
- def __init__(self, filename, grr, parent=None):
- if global_prefs['verbose'] >= 1:
- print 'Parsing:', filename
- print
-
- #check to see if filename is a relative path
- #filename = os.path.abspath(filename)
-
- self.fw = flt_filewalker.FltIn(filename)
- self.filename = filename
- self.bname = os.path.splitext(os.path.basename(filename))[0]
- self.grr = grr
-
- 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_dof,
- 91: self.parse_unhandled,
- 98: self.parse_unhandled,
- 63: self.parse_xref})
-
- self.scene = Blender.Scene.New(self.bname)
- self.group = Blender.Group.New(self.bname)
-
- 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 clearparent(root,childhash):
- for child in childhash[root]:
- clearparent(child,childhash)
- root.clrParent(2,0)
-
-def fixscale(root,childhash):
- for child in childhash[root]:
- fixscale(child,childhash)
- location = Blender.Mathutils.Vector(root.getLocation('worldspace'))
- if location[0] != 0.0 or location[1] != 0.0 or location[2] != 0.0:
- #direction = Blender.Mathutils.Vector(0-location[0],0-location[1],0-location[2]) #reverse vector
- smat = Blender.Mathutils.ScaleMatrix(global_prefs['scale'],4)
- root.setLocation(location * smat)
- #if its a mesh, we need to scale all of its vertices too
- if root.type == 'Mesh':
- smat = Blender.Mathutils.ScaleMatrix(global_prefs['scale'],4)
- rmesh = root.getData(mesh=True)
- for v in rmesh.verts:
- v.co = v.co * smat
-
-def reparent(root,childhash,sce):
- for child in childhash[root]:
- reparent(child,childhash,sce)
-
- root.makeParent(childhash[root])
- sce.update(1)
-
-def update_scene(root,sdone):
- for object in root.objects:
- if object.DupGroup:
- try:
- child = Blender.Scene.Get(object.DupGroup.name)
- except:
- child = None
- if child and child not in sdone:
- update_scene(child,sdone)
- root.makeCurrent()
- #create a list of children for each object
- childhash = dict()
- for object in root.objects:
- childhash[object] = list()
-
- for object in root.objects:
- if object.parent:
- childhash[object.parent].append(object)
-
- for object in root.objects:
- if not object.parent:
- #recursivley go through and clear all the children of their transformation, starting at deepest level first.
- clearparent(object,childhash)
- #now fix the location of everything
- fixscale(object,childhash)
- #now fix the parenting
- reparent(object,childhash,root)
-
- for object in root.objects:
- object.makeDisplayList()
- root.update(1)
- sdone.append(root)
-
-
-def select_file(filename, grr):
- 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
- global_prefs['log to blender'] = True
-
-
-
- Blender.Window.WaitCursor(True)
- Blender.Window.EditMode(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,grr)
- 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()
-
- if global_prefs['attrib']:
- print "reading attribute files"
- db.read_attribute_files()
-
- Blender.Window.ViewLayer(range(1,21))
-
- update_scene(db.scene,[])
- import_time = Blender.sys.time() - import_time
- 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)
-
-def setimportscale(ID,val):
- global global_prefs
- global_prefs['scale'] = val
-def setBpath(fname):
- global_prefs['fltfile'] = fname
- d = dict()
- for key in global_prefs:
- d[key] = global_prefs[key]
- Blender.Registry.SetKey('flt_import', d, 1)
-
-def event(evt,val):
- pass
-
-from Blender.BGL import *
-from Blender import Draw
-
-def but_event(evt):
-
- global FLTBaseLabel
- global FLTBaseString
- global FLTBaseChooser
-
- global FLTExport
- global FLTClose
-
- global FLTDoXRef
- global FLTShadeImport
- global FLTAttrib
-
- global FLTWarn
-
- #Import DB
- if evt == 1:
- if global_prefs['verbose'] >= 1:
- print
- print 'OpenFlight Importer'
- print 'Version:', __version__
- print 'Author: Greg MacDonald, Campbell Barton, Geoffrey Bantle'
- print __url__[2]
- print
-
- GRR = GlobalResourceRepository()
-
- try:
- select_file(global_prefs['fltfile'], GRR)
- except:
- import traceback
- FLTWarn = Draw.PupBlock("Ixport Error", ["See console for output!"])
- traceback.print_exception(sys.exc_type, sys.exc_value, sys.exc_traceback)
-
- #choose base path for export
- if evt == 4:
- Blender.Window.FileSelector(setBpath, "DB Root", global_prefs['fltfile'])
- #Import custom shading?
- if evt == 9:
- global_prefs['smoothshading'] = FLTShadeImport.val
- #Import Image attribute files
- if evt == 10:
- global_prefs['attrib'] = FLTAttrib.val
- #export XRefs
- if evt == 13:
- global_prefs['doxrefs'] = FLTDoXRef.val
-
- if evt == 2:
- Draw.Exit()
-
- d = dict()
- for key in global_prefs:
- d[key] = global_prefs[key]
- Blender.Registry.SetKey('flt_import', d, 1)
-
-def gui():
-
- global FLTBaseLabel
- global FLTBaseString
- global FLTBaseChooser
-
- global FLTExport
- global FLTClose
-
- global FLTDoXRef
- global FLTShadeImport
-
- global FLTAttrib
-
-
- glClearColor(0.772,0.832,0.847,1.0)
- glClear(GL_COLOR_BUFFER_BIT)
-
- areas = Blender.Window.GetScreenInfo()
- curarea = Blender.Window.GetAreaID()
- curRect = None
-
- for area in areas:
- if area['id'] == curarea:
- curRect = area['vertices']
- break
-
- width = curRect[2] - curRect[0]
- height = curRect[3] - curRect[1]
- cx = 50
- cy = height - 80
-
- FLTBaseLabel = Draw.Label("Base file:",cx,cy,100,20)
- FLTBaseString = Draw.String("",3,cx+100,cy,300,20,global_prefs['fltfile'],255,"Root DB file")
- FLTBaseChooser = Draw.PushButton("...",4,cx+400,cy,20,20,"Choose Folder")
-
- cy = cy-40
- FLTScale = Draw.Number("Import Scale",14,cx,cy,220,20,global_prefs['scale'],0.0,100.0,"Export scaleing factor",setimportscale)
-
- cy = cy-40
- FLTDoXRef = Draw.Toggle("Import XRefs", 13,cx,cy,220,20,global_prefs['doxrefs'],"Import External references")
-
- cy = cy-40
- FLTShadeImport = Draw.Toggle("Import Custom Shading",9,cx,cy,220,20,global_prefs['smoothshading'],"Import custom shading via edgesplit modifiers")
-
- cy = cy-40
- FLTAttrib = Draw.Toggle("Import Attribute Files", 10,cx,cy,220,20,global_prefs['attrib'],"Import Image Attribute files")
-
- cy = cy - 40
- FLTExport = Draw.PushButton("Import",1,cx,20,100,20,"Import FLT Database")
- FLTClose = Draw.PushButton("Close",2,cx+120,20,100,20,"Close Window")
-
-
-
-Draw.Register(gui,event,but_event) \ No newline at end of file