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/lightwave_import.py')
-rw-r--r--release/scripts/lightwave_import.py1705
1 files changed, 0 insertions, 1705 deletions
diff --git a/release/scripts/lightwave_import.py b/release/scripts/lightwave_import.py
deleted file mode 100644
index 6d02467cef8..00000000000
--- a/release/scripts/lightwave_import.py
+++ /dev/null
@@ -1,1705 +0,0 @@
-#!BPY
-"""
-Name: 'LightWave (.lwo)...'
-Blender: 239
-Group: 'Import'
-Tooltip: 'Import LightWave Object File Format'
-"""
-
-__author__ = ["Alessandro Pirovano, Anthony D'Agostino (Scorpius)", "Campbell Barton (ideasman42)", "ZanQdo"]
-__url__ = ("www.blender.org", "blenderartist.org",
-"Anthony's homepage, http://www.redrival.com/scorpius", "Alessandro's homepage, http://uaraus.altervista.org")
-
-importername = "lwo_import 0.4.0"
-
-# +---------------------------------------------------------+
-# | Save your work before and after use. |
-# | Please report any useful comment to: |
-# | uaraus-dem@yahoo.it |
-# | Thanks |
-# +---------------------------------------------------------+
-# +---------------------------------------------------------+
-# | Copyright (c) 2002 Anthony D'Agostino |
-# | http://www.redrival.com/scorpius |
-# | scorpius@netzero.com |
-# | April 21, 2002 |
-# | Import Export Suite v0.5 |
-# +---------------------------------------------------------+
-# | Read and write LightWave Object File Format (*.lwo) |
-# +---------------------------------------------------------+
-# +---------------------------------------------------------+
-# | Alessandro Pirovano tweaked starting on March 2005 |
-# | http://uaraus.altervista.org |
-# +---------------------------------------------------------+
-# +----------------------------------------------------------
-# | GPL license block
-# |
-# | This program is free software; you can redistribute it and/or modify
-# | it under the terms of the GNU General Public License as published by
-# | the Free Software Foundation; either version 2 of the License, or
-# | (at your option) any later version.
-# |
-# | This program is distributed in the hope that it will be useful,
-# | but WITHOUT ANY WARRANTY; without even the implied warranty of
-# | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# | GNU General Public License for more details.
-# |
-# | You should have received a copy of the GNU General Public License
-# | along with this program; if not, write to the Free Software
-# | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-# +----------------------------------------------------------
-# +---------------------------------------------------------+
-# | Release log: |
-# | 0.4.0 : Updated for blender 2.44 |
-# | ZanQdo - made the mesh import the right way up |
-# | Ideasman42 - Updated functions for the bew API |
-# | as well as removing the text object class |
-# | 0.2.2 : This code works with Blender 2.42 RC3 |
-# | Added a new PolyFill function for BPYMesh's |
-# | ngon() to use, checked compatibility |
-# | lightwaves ngons are imported as fgons |
-# | Checked compatibility against 1711 lwo files |
-# | 0.2.1 : This code works with Blender 2.40 RC1 |
-# | modified material mode assignment to deal with |
-# | Python API modification |
-# | Changed script license to GNU GPL |
-# | 0.2.0: This code works with Blender 2.40a2 or up |
-# | Major rewrite to deal with large meshes |
-# | - 2 pass file parsing |
-# | - lower memory foot###if DEBUG: print |
-# | (as long as python gc allows) |
-# | 2.40a2 - Removed subsurf settings patches=poly |
-# | 2.40a2 - Edge generation instead of 2vert faces |
-# | 0.1.16: fixed (try 2) texture offset calculations |
-# | added hint on axis mapping |
-# | added hint on texture blending mode |
-# | added hint on texture transparency setting |
-# | search images in original directory first |
-# | fixed texture order application |
-# | 0.1.15: added release log |
-# | fixed texture offset calculations (non-UV) |
-# | fixed reverting vertex order in face generation |
-# | associate texture on game-engine settings |
-# | vector math definitely based on mathutils |
-# | search images in "Images" and "../Images" dir |
-# | revised logging facility |
-# | fixed subsurf texture and material mappings |
-# | 0.1.14: patched missing mod_vector (not definitive) |
-# | 0.1.13: first public release |
-# +---------------------------------------------------------+
-
-#blender related import
-import Blender
-import bpy
-
-# use for comprehensiveImageLoad
-import BPyImage
-
-# Use this ngon function
-import BPyMesh
-
-import BPyMessages
-
-#python specific modules import
-try:
- import struct, chunk, cStringIO
-except:
- struct= chunk= cStringIO= None
-
-# python 2.3 has no reversed() iterator. this will only work on lists and tuples
-try:
- reversed
-except:
- def reversed(l): return l[::-1]
-
-### # Debuggin disabled in release.
-### # do a search replace to enabe debug prints
-### DEBUG = False
-
-# ===========================================================
-# === Utility Preamble ======================================
-# ===========================================================
-
-textname = None
-#uncomment the following line to enable logging facility to the named text object
-#textname = "lwo_log"
-
-TXMTX = Blender.Mathutils.Matrix(\
-[1, 0, 0, 0],\
-[0, 0, 1, 0],\
-[0, 1, 0, 0],\
-[0, 0, 0, 1])
-
-# ===========================================================
-# === Make sure it is a string ... deal with strange chars ==
-# ===========================================================
-def safestring(st):
- myst = ""
- for ll in xrange(len(st)):
- if st[ll] < " ":
- myst += "#"
- else:
- myst += st[ll]
- return myst
-
-# ===========================================================
-# === Main read functions ===================================
-# ===========================================================
-
-# =============================
-# === Read LightWave Format ===
-# =============================
-def read(filename):
- if BPyMessages.Error_NoFile(filename):
- return
-
- print "This is: %s" % importername
- print "Importing file:", filename
- bpy.data.scenes.active.objects.selected = []
-
- start = Blender.sys.time()
- file = open(filename, "rb")
-
- editmode = Blender.Window.EditMode() # are we in edit mode? If so ...
- if editmode: Blender.Window.EditMode(0) # leave edit mode before getting the mesh # === LWO header ===
-
- try:
- form_id, form_size, form_type = struct.unpack(">4s1L4s", file.read(12))
- except:
- Blender.Draw.PupMenu('Error%t|This is not a lightwave file')
- return
-
- if (form_type == "LWOB"):
- read_lwob(file, filename)
- elif (form_type == "LWO2"):
- read_lwo2(file, filename)
- else:
- print "Can't read a file with the form_type: %s" % form_type
- return
-
- Blender.Window.DrawProgressBar(1.0, "") # clear progressbar
- file.close()
- end = Blender.sys.time()
- seconds = " in %.2f %s" % (end-start, "seconds")
- if form_type == "LWO2": fmt = " (v6.0 Format)"
- if form_type == "LWOB": fmt = " (v5.5 Format)"
- print "Successfully imported " + filename.split('\\')[-1].split('/')[-1] + fmt + seconds
-
- if editmode: Blender.Window.EditMode(1) # optional, just being nice
- Blender.Redraw()
-
-# enddef read
-
-
-# =================================
-# === Read LightWave 5.5 format ===
-# =================================
-def read_lwob(file, filename):
- #This function is directly derived from the LWO2 import routine
- #dropping all the material analysis parts
-
- ###if DEBUG: print "LightWave 5.5 format"
-
- dir_part = Blender.sys.dirname(filename)
- fname_part = Blender.sys.basename(filename)
- #ask_weird = 1
-
- #first initialization of data structures
- defaultname = Blender.sys.splitext(fname_part)[0]
- tag_list = [] #tag list: global for the whole file?
- surf_list = [] #surf list: global for the whole file?
- clip_list = [] #clip list: global for the whole file?
- object_index = 0
- object_list = None
- objspec_list = None
-
- #add default material for orphaned faces, if any
- surf_list.append({'NAME': "_Orphans", 'g_MAT': bpy.data.materials.new("_Orphans")})
-
- #pass 2: effectively generate objects
- ###if DEBUG: print "Pass 1: dry import"
- file.seek(0)
- objspec_list = ["imported", {}, [], [], {}, {}, 0, {}, {}]
- # === LWO header ===
- form_id, form_size, form_type = struct.unpack(">4s1L4s", file.read(12))
- if (form_type != "LWOB"):
- ###if DEBUG: print "??? Inconsistent file type: %s" % form_type
- return
- while 1:
- try:
- lwochunk = chunk.Chunk(file)
- except EOFError:
- break
- ###if DEBUG: print ' ',
- if lwochunk.chunkname == "LAYR":
- ###if DEBUG: print "---- LAYR",
- objname = read_layr(lwochunk)
- ###if DEBUG: print objname
- if objspec_list != None: #create the object
- create_objects(clip_list, objspec_list, surf_list)
- update_material(clip_list, objspec_list, surf_list) #give it all the object
- objspec_list = [objname, {}, [], [], {}, {}, 0, {}, {}]
- object_index += 1
- elif lwochunk.chunkname == "PNTS": # Verts
- ###if DEBUG: print "---- PNTS",
- verts = read_verts(lwochunk)
- objspec_list[2] = verts
- elif lwochunk.chunkname == "POLS": # Faces v5.5
- ###if DEBUG: print "-------- POLS(5.5)"
- faces = read_faces_5(lwochunk)
- flag = 0
- #flag is 0 for regular polygon, 1 for patches (= subsurf), 2 for anything else to be ignored
- if flag<2:
- if objspec_list[3] != []:
- #create immediately the object
- create_objects(clip_list, objspec_list, surf_list)
- update_material(clip_list, objspec_list, surf_list) #give it all the object
- #update with new data
- objspec_list = [objspec_list[0], #update name
- {}, #init
- objspec_list[2], #same vertexes
- faces, #give it the new faces
- {}, #no need to copy - filled at runtime
- {}, #polygon tagging will follow
- flag, #patch flag
- objspec_list[7], #same uvcoords
- {}] #no vmad mapping
- object_index += 1
- #end if already has a face list
- objspec_list[3] = faces
- objname = objspec_list[0]
- if objname == None:
- objname = defaultname
- #end if processing a valid poly type
- else: # Misc Chunks
- ###if DEBUG: print "---- %s: skipping (definitely!)" % lwochunk.chunkname
- lwochunk.skip()
- #uncomment here to log data structure as it is built
- # ###if DEBUG: print object_list
- #last object read
- create_objects(clip_list, objspec_list, surf_list)
- update_material(clip_list, objspec_list, surf_list) #give it all the object
- objspec_list = None
- surf_list = None
- clip_list = None
-
-
- ###if DEBUG: print "\nFound %d objects:" % object_index
-
-# enddef read_lwob
-
-
-# =============================
-# === Read LightWave Format ===
-# =============================
-def read_lwo2(file, filename, typ="LWO2"):
-
- ###if DEBUG: print "LightWave 6 (and above) format"
-
- dir_part = Blender.sys.dirname(filename)
- fname_part = Blender.sys.basename(filename)
- ask_weird = 1
-
- #first initialization of data structures
- defaultname = Blender.sys.splitext(fname_part)[0]
- tag_list = [] #tag list: global for the whole file?
- surf_list = [] #surf list: global for the whole file?
- clip_list = [] #clip list: global for the whole file?
- object_index = 0
- object_list = None
- objspec_list = None
- # init value is: object_list = [[None, {}, [], [], {}, {}, 0, {}, {}]]
- #0 - objname #original name
- #1 - obj_dict = {TAG} #objects created
- #2 - verts = [] #object vertexes
- #3 - faces = [] #object faces (associations poly -> vertexes)
- #4 - obj_dim_dict = {TAG} #tuples size and pos in local object coords - used for NON-UV mappings
- #5 - polytag_dict = {TAG} #tag to polygons mapping
- #6 - patch_flag #0 = surf; 1 = patch (subdivision surface) - it was the image list
- #7 - uvcoords_dict = {name} #uvmap coordinates (mixed mode per vertex/per face)
- #8 - facesuv_dict = {name} #vmad only coordinates associations poly & vertex -> uv tuples
-
- #pass 1: look in advance for materials
- ###if DEBUG: print "Starting Pass 1: hold on tight"
- while 1:
- try:
- lwochunk = chunk.Chunk(file)
- except EOFError:
- break
- ###if DEBUG: print ' ',
- if lwochunk.chunkname == "TAGS": # Tags
- ###if DEBUG: print "---- TAGS"
- tag_list.extend(read_tags(lwochunk))
- elif lwochunk.chunkname == "SURF": # surfaces
- ###if DEBUG: print "---- SURF"
- surf_list.append(read_surfs(lwochunk, surf_list, tag_list))
- elif lwochunk.chunkname == "CLIP": # texture images
- ###if DEBUG: print "---- CLIP"
- clip_list.append(read_clip(lwochunk, dir_part))
- ###if DEBUG: print "read total %s clips up to now" % len(clip_list)
- else: # Misc Chunks
- if ask_weird:
- ckname = safestring(lwochunk.chunkname)
- if "#" in ckname:
- choice = Blender.Draw.PupMenu("WARNING: file could be corrupted.%t|Import anyway|Give up")
- if choice != 1:
- ###if DEBUG: print "---- %s: Maybe file corrupted. Terminated by user" % lwochunk.chunkname
- return
- ask_weird = 0
- ###if DEBUG: print "---- %s: skipping (maybe later)" % lwochunk.chunkname
- lwochunk.skip()
-
- #add default material for orphaned faces, if any
- surf_list.append({'NAME': "_Orphans", 'g_MAT': bpy.data.materials.new("_Orphans")})
-
- #pass 2: effectively generate objects
- ###if DEBUG: print "Pass 2: now for the hard part"
- file.seek(0)
- # === LWO header ===
- form_id, form_size, form_type = struct.unpack(">4s1L4s", file.read(12))
- if (form_type != "LWO2"):
- ###if DEBUG: print "??? Inconsistent file type: %s" % form_type
- return
- while 1:
- try:
- lwochunk = chunk.Chunk(file)
- except EOFError:
- break
- ###if DEBUG: print ' ',
- if lwochunk.chunkname == "LAYR":
- ###if DEBUG: print "---- LAYR"
- objname = read_layr(lwochunk)
- ###if DEBUG: print objname
- if objspec_list != None: #create the object
- create_objects(clip_list, objspec_list, surf_list)
- update_material(clip_list, objspec_list, surf_list) #give it all the object
- objspec_list = [objname, {}, [], [], {}, {}, 0, {}, {}]
- object_index += 1
- elif lwochunk.chunkname == "PNTS": # Verts
- ###if DEBUG: print "---- PNTS"
- verts = read_verts(lwochunk)
- objspec_list[2] = verts
- elif lwochunk.chunkname == "VMAP": # MAPS (UV)
- ###if DEBUG: print "---- VMAP"
- #objspec_list[7] = read_vmap(objspec_list[7], len(objspec_list[2]), lwochunk)
- read_vmap(objspec_list[7], len(objspec_list[2]), lwochunk)
- elif lwochunk.chunkname == "VMAD": # MAPS (UV) per-face
- ###if DEBUG: print "---- VMAD"
- #objspec_list[7], objspec_list[8] = read_vmad(objspec_list[7], objspec_list[8], len(objspec_list[3]), len(objspec_list[2]), lwochunk)
- read_vmad(objspec_list[7], objspec_list[8], len(objspec_list[3]), len(objspec_list[2]), lwochunk)
- elif lwochunk.chunkname == "POLS": # Faces v6.0
- ###if DEBUG: print "-------- POLS(6)"
- faces, flag = read_faces_6(lwochunk)
- #flag is 0 for regular polygon, 1 for patches (= subsurf), 2 for anything else to be ignored
- if flag<2:
- if objspec_list[3] != []:
- #create immediately the object
- create_objects(clip_list, objspec_list, surf_list)
- update_material(clip_list, objspec_list, surf_list) #give it all the object
- #update with new data
- objspec_list = [objspec_list[0], #update name
- {}, #init
- objspec_list[2], #same vertexes
- faces, #give it the new faces
- {}, #no need to copy - filled at runtime
- {}, #polygon tagging will follow
- flag, #patch flag
- objspec_list[7], #same uvcoords
- {}] #no vmad mapping
- object_index += 1
- #end if already has a face list
- objspec_list[3] = faces
- objname = objspec_list[0]
- if objname == None:
- objname = defaultname
- #end if processing a valid poly type
- elif lwochunk.chunkname == "PTAG": # PTags
- ###if DEBUG: print "---- PTAG"
- polytag_dict = read_ptags(lwochunk, tag_list)
- for kk, polytag_dict_val in polytag_dict.iteritems(): objspec_list[5][kk] = polytag_dict_val
- else: # Misc Chunks
- ###if DEBUG: print "---- %s: skipping (definitely!)" % lwochunk.chunkname
- lwochunk.skip()
- #uncomment here to log data structure as it is built
-
- #last object read
- create_objects(clip_list, objspec_list, surf_list)
- update_material(clip_list, objspec_list, surf_list) #give it all the object
- objspec_list = None
- surf_list = None
- clip_list = None
-
- ###if DEBUG: print "\nFound %d objects:" % object_index
-# enddef read_lwo2
-
-
-
-
-
-
-# ===========================================================
-# === File reading routines =================================
-# ===========================================================
-# ==================
-# === Read Verts ===
-# ==================
-def read_verts(lwochunk):
- #data = cStringIO.StringIO(lwochunk.read())
- numverts = lwochunk.chunksize/12
- return [struct.unpack(">fff", lwochunk.read(12)) for i in xrange(numverts)]
-# enddef read_verts
-
-
-# =================
-# === Read Name ===
-# =================
-# modified to deal with odd lenght strings
-def read_name(file):
- name = ""
- while 1:
- char = file.read(1)
- if char == "\0": break
- else: name += char
- len_name = len(name) + 1 #count the trailing zero
- if len_name%2==1:
- char = file.read(1) #remove zero padding to even lenght
- len_name += 1
- return name, len_name
-
-
-# ==================
-# === Read Layer ===
-# ==================
-def read_layr(lwochunk):
- data = cStringIO.StringIO(lwochunk.read())
- idx, flags = struct.unpack(">hh", data.read(4))
- pivot = struct.unpack(">fff", data.read(12))
- layer_name, discard = read_name(data)
- if not layer_name: layer_name = "NoName"
- return layer_name
-# enddef read_layr
-
-
-# ======================
-# === Read Faces 5.5 ===
-# ======================
-def read_faces_5(lwochunk):
- data = cStringIO.StringIO(lwochunk.read())
- faces = []
- i = 0
- while i < lwochunk.chunksize:
- #if not i%1000 and my_meshtools.show_progress:
- # Blender.Window.DrawProgressBar(float(i)/lwochunk.chunksize, "Reading Faces")
-
- numfaceverts, = struct.unpack(">H", data.read(2))
- facev = [struct.unpack(">H", data.read(2))[0] for j in xrange(numfaceverts)]
- facev.reverse()
- faces.append(facev)
- surfaceindex, = struct.unpack(">H", data.read(2))
- if surfaceindex < 0:
- ###if DEBUG: print "***Error. Referencing uncorrect surface index"
- return
- i += (4+numfaceverts*2)
- return faces
-
-
-# ==================================
-# === Read Variable-Length Index ===
-# ==================================
-def read_vx(data):
- byte1, = struct.unpack(">B", data.read(1))
- if byte1 != 0xFF: # 2-byte index
- byte2, = struct.unpack(">B", data.read(1))
- index = byte1*256 + byte2
- index_size = 2
- else: # 4-byte index
- byte2, byte3, byte4 = struct.unpack(">3B", data.read(3))
- index = byte2*65536 + byte3*256 + byte4
- index_size = 4
- return index, index_size
-
-
-# ======================
-# === Read uvmapping ===
-# ======================
-def read_vmap(uvcoords_dict, maxvertnum, lwochunk):
-
- if maxvertnum == 0:
- ###if DEBUG: print "Found VMAP but no vertexes to map!"
- return uvcoords_dict
- data = cStringIO.StringIO(lwochunk.read())
- map_type = data.read(4)
- if map_type != "TXUV":
- ###if DEBUG: print "Reading VMAP: No Texture UV map Were Found. Map Type: %s" % map_type
- return uvcoords_dict
- dimension, = struct.unpack(">H", data.read(2))
- name, i = read_name(data) #i initialized with string lenght + zeros
- ###if DEBUG: print "TXUV %d %s" % (dimension, name)
- #note if there is already a VMAD it will be lost
- #it is assumed that VMAD will follow the corresponding VMAP
- Vector = Blender.Mathutils.Vector
- try: #if uvcoords_dict.has_key(name):
- my_uv_dict = uvcoords_dict[name] #update existing
- except: #else:
- my_uv_dict = {} #start a brand new: this could be made more smart
- while (i < lwochunk.chunksize - 6): #4+2 header bytes already read
- vertnum, vnum_size = read_vx(data)
- uv = struct.unpack(">ff", data.read(8))
- if vertnum >= maxvertnum:
- ###if DEBUG: print "Hem: more uvmap than vertexes? ignoring uv data for vertex %d" % vertnum
- pass
- else:
- my_uv_dict[vertnum] = Vector(uv)
- i += 8 + vnum_size
- #end loop on uv pairs
- uvcoords_dict[name] = my_uv_dict
- #this is a per-vertex mapping AND the uv tuple is vertex-ordered, so faces_uv is the same as faces
- #return uvcoords_dict
- return
-
-# ========================
-# === Read uvmapping 2 ===
-# ========================
-def read_vmad(uvcoords_dict, facesuv_dict, maxfacenum, maxvertnum, lwochunk):
- if maxvertnum == 0 or maxfacenum == 0:
- ###if DEBUG: print "Found VMAD but no vertexes to map!"
- return uvcoords_dict, facesuv_dict
- data = cStringIO.StringIO(lwochunk.read())
- map_type = data.read(4)
- if map_type != "TXUV":
- ###if DEBUG: print "Reading VMAD: No Texture UV map Were Found. Map Type: %s" % map_type
- return uvcoords_dict, facesuv_dict
- dimension, = struct.unpack(">H", data.read(2))
- name, i = read_name(data) #i initialized with string lenght + zeros
- ###if DEBUG: print "TXUV %d %s" % (dimension, name)
- try: #if uvcoords_dict.has_key(name):
- my_uv_dict = uvcoords_dict[name] #update existing
- except: #else:
- my_uv_dict = {} #start a brand new: this could be made more smart
- my_facesuv_list = []
- newindex = maxvertnum + 10 #why +10? Why not?
- #end variable initialization
- Vector = Blender.Mathutils.Vector
- while (i < lwochunk.chunksize - 6): #4+2 header bytes already read
- vertnum, vnum_size = read_vx(data)
- i += vnum_size
- polynum, vnum_size = read_vx(data)
- i += vnum_size
- uv = struct.unpack(">ff", data.read(8))
- if polynum >= maxfacenum or vertnum >= maxvertnum:
- ###if DEBUG: print "Hem: more uvmap than vertexes? ignorig uv data for vertex %d" % vertnum
- pass
- else:
- my_uv_dict[newindex] = Vector(uv)
- my_facesuv_list.append([polynum, vertnum, newindex])
- newindex += 1
- i += 8
- #end loop on uv pairs
- uvcoords_dict[name] = my_uv_dict
- facesuv_dict[name] = my_facesuv_list
- ###if DEBUG: print "updated %d vertexes data" % (newindex-maxvertnum-10)
- return
-
-
-# =================
-# === Read tags ===
-# =================
-def read_tags(lwochunk):
- data = cStringIO.StringIO(lwochunk.read())
- tag_list = []
- current_tag = ""
- i = 0
- while i < lwochunk.chunksize:
- char = data.read(1)
- if char == "\0":
- tag_list.append(current_tag)
- if (len(current_tag) % 2 == 0): char = data.read(1)
- current_tag = ""
- else:
- current_tag += char
- i += 1
- ###if DEBUG: print "read %d tags, list follows: %s" % (len(tag_list), tag_list)
- return tag_list
-
-
-# ==================
-# === Read Ptags ===
-# ==================
-def read_ptags(lwochunk, tag_list):
- data = cStringIO.StringIO(lwochunk.read())
- polygon_type = data.read(4)
- if polygon_type != "SURF":
- ###if DEBUG: print "No Surf Were Found. Polygon Type: %s" % polygon_type
- return {}
- ptag_dict = {}
- i = 0
- while(i < lwochunk.chunksize-4): #4 bytes polygon type already read
- #if not i%1000 and my_meshtools.show_progress:
- # Blender.Window.DrawProgressBar(float(i)/lwochunk.chunksize, "Reading PTAGS")
- poln, poln_size = read_vx(data)
- i += poln_size
- tag_index, = struct.unpack(">H", data.read(2))
- if tag_index > (len(tag_list)):
- ###if DEBUG: print "Reading PTAG: Surf belonging to undefined TAG: %d. Skipping" % tag_index
- return {}
- i += 2
- tag_key = tag_list[tag_index]
- try:
- ptag_dict[tag_list[tag_index]].append(poln)
- except: #if not(ptag_dict.has_key(tag_key)):
- ptag_dict[tag_list[tag_index]] = [poln]
-
- ###if DEBUG: for i, ptag_dict_val in ptag_dict.iteritems(): print "read %d polygons belonging to TAG %s" % (len(ptag_dict_val ), i)
- return ptag_dict
-
-
-
-# ==================
-# === Read Clips ===
-# ==================
-def read_clip(lwochunk, dir_part):
-# img, IMG, g_IMG refers to blender image objects
-# ima, IMAG, g_IMAG refers to clip dictionary 'ID' entries: refer to blok and surf
- clip_dict = {}
- data = cStringIO.StringIO(lwochunk.read())
- data_str = data.read(4)
- if len(data_str) < 4: # can be zero also??? :/
- # Should not happen but lw can import so we should too
- return
-
- image_index, = struct.unpack(">L", data_str)
- clip_dict['ID'] = image_index
- i = 4
- while(i < lwochunk.chunksize):
- subchunkname, = struct.unpack("4s", data.read(4))
- subchunklen, = struct.unpack(">H", data.read(2))
- if subchunkname == "STIL":
- ###if DEBUG: print "-------- STIL"
- clip_name, k = read_name(data)
- #now split text independently from platform
- #depend on the system where image was saved. NOT the one where the script is run
- no_sep = "\\"
- if Blender.sys.sep == no_sep: no_sep ="/"
- if (no_sep in clip_name):
- clip_name = clip_name.replace(no_sep, Blender.sys.sep)
- short_name = Blender.sys.basename(clip_name)
- if clip_name == "" or short_name == "":
- ###if DEBUG: print "Reading CLIP: Empty clip name not allowed. Skipping"
- discard = data.read(subchunklen-k)
- clip_dict['NAME'] = clip_name
- clip_dict['BASENAME'] = short_name
- elif subchunkname == "XREF": #cross reference another image
- ###if DEBUG: print "-------- XREF"
- image_index, = struct.unpack(">L", data.read(4))
- clip_name, k = read_name(data)
- clip_dict['NAME'] = clip_name
- clip_dict['XREF'] = image_index
- elif subchunkname == "NEGA": #negate texture effect
- ###if DEBUG: print "-------- NEGA"
- n, = struct.unpack(">H", data.read(2))
- clip_dict['NEGA'] = n
- else: # Misc Chunks
- ###if DEBUG: print "-------- CLIP:%s: skipping" % subchunkname
- discard = data.read(subchunklen)
- i = i + 6 + subchunklen
- #end loop on surf chunks
- ###if DEBUG: print "read image:%s" % clip_dict
- if 'XREF' in clip_dict: # has_key
- ###if DEBUG: print "Cross-reference: no image pre-allocated."
- return clip_dict
- #look for images
- #img = load_image("",clip_dict['NAME'])
- NAME= BASENAME= None
-
- try:
- NAME= clip_dict['NAME']
- BASENAME= clip_dict['BASENAME']
- except:
- clip_dict['g_IMG'] = None
- return
- # ###if DEBUG: print 'test', NAME, BASENAME
- img = BPyImage.comprehensiveImageLoad(NAME, dir_part, PLACE_HOLDER= False, RECURSIVE=False)
- if not img:
- ###if DEBUG: print "***No image %s found: trying LWO file subdir" % NAME
- img = BPyImage.comprehensiveImageLoad(BASENAME, dir_part, PLACE_HOLDER= False, RECURSIVE=False)
-
- ###if DEBUG: if not img: print "***No image %s found: giving up" % BASENAME
- #lucky we are: we have an image
- ###if DEBUG: print "Image pre-allocated."
- clip_dict['g_IMG'] = img
-
- return clip_dict
-
-
-# ===========================
-# === Read Surfaces Block ===
-# ===========================
-def read_surfblok(subchunkdata):
- lenght = len(subchunkdata)
- my_dict = {}
- my_uvname = ""
- data = cStringIO.StringIO(subchunkdata)
- ##############################################################
- # blok header sub-chunk
- ##############################################################
- subchunkname, = struct.unpack("4s", data.read(4))
- subchunklen, = struct.unpack(">h", data.read(2))
- accumulate_i = subchunklen + 6
- if subchunkname != 'IMAP':
- ###if DEBUG: print "---------- SURF: BLOK: %s: block aborting" % subchunkname
- return {}, ""
- ###if DEBUG: print "---------- IMAP"
- ordinal, i = read_name(data)
- my_dict['ORD'] = ordinal
- #my_dict['g_ORD'] = -1
- my_dict['ENAB'] = True
- while(i < subchunklen): # ---------left 6------------------------- loop on header parameters
- sub2chunkname, = struct.unpack("4s", data.read(4))
- sub2chunklen, = struct.unpack(">h", data.read(2))
- i = i + 6 + sub2chunklen
- if sub2chunkname == "CHAN":
- ###if DEBUG: print "------------ CHAN"
- sub2chunkname, = struct.unpack("4s", data.read(4))
- my_dict['CHAN'] = sub2chunkname
- sub2chunklen -= 4
- elif sub2chunkname == "ENAB": #only present if is to be disabled
- ###if DEBUG: print "------------ ENAB"
- ena, = struct.unpack(">h", data.read(2))
- my_dict['ENAB'] = ena
- sub2chunklen -= 2
- elif sub2chunkname == "NEGA": #only present if is to be enabled
- ###if DEBUG: print "------------ NEGA"
- ena, = struct.unpack(">h", data.read(2))
- if ena == 1:
- my_dict['NEGA'] = ena
- sub2chunklen -= 2
- elif sub2chunkname == "OPAC": #only present if is to be disabled
- ###if DEBUG: print "------------ OPAC"
- opa, = struct.unpack(">h", data.read(2))
- s, = struct.unpack(">f", data.read(4))
- envelope, env_size = read_vx(data)
- my_dict['OPAC'] = opa
- my_dict['OPACVAL'] = s
- sub2chunklen -= 6
- elif sub2chunkname == "AXIS":
- ###if DEBUG: print "------------ AXIS"
- ena, = struct.unpack(">h", data.read(2))
- my_dict['DISPLAXIS'] = ena
- sub2chunklen -= 2
- else: # Misc Chunks
- ###if DEBUG: print "------------ SURF: BLOK: IMAP: %s: skipping" % sub2chunkname
- discard = data.read(sub2chunklen)
- #end loop on blok header subchunks
- ##############################################################
- # blok attributes sub-chunk
- ##############################################################
- subchunkname, = struct.unpack("4s", data.read(4))
- subchunklen, = struct.unpack(">h", data.read(2))
- accumulate_i += subchunklen + 6
- if subchunkname != 'TMAP':
- ###if DEBUG: print "---------- SURF: BLOK: %s: block aborting" % subchunkname
- return {}, ""
- ###if DEBUG: print "---------- TMAP"
- i = 0
- while(i < subchunklen): # -----------left 6----------------------- loop on header parameters
- sub2chunkname, = struct.unpack("4s", data.read(4))
- sub2chunklen, = struct.unpack(">h", data.read(2))
- i = i + 6 + sub2chunklen
- if sub2chunkname == "CNTR":
- ###if DEBUG: print "------------ CNTR"
- x, y, z = struct.unpack(">fff", data.read(12))
- envelope, env_size = read_vx(data)
- my_dict['CNTR'] = [x, y, z]
- sub2chunklen -= (12+env_size)
- elif sub2chunkname == "SIZE":
- ###if DEBUG: print "------------ SIZE"
- x, y, z = struct.unpack(">fff", data.read(12))
- envelope, env_size = read_vx(data)
- my_dict['SIZE'] = [x, y, z]
- sub2chunklen -= (12+env_size)
- elif sub2chunkname == "ROTA":
- ###if DEBUG: print "------------ ROTA"
- x, y, z = struct.unpack(">fff", data.read(12))
- envelope, env_size = read_vx(data)
- my_dict['ROTA'] = [x, y, z]
- sub2chunklen -= (12+env_size)
- elif sub2chunkname == "CSYS":
- ###if DEBUG: print "------------ CSYS"
- ena, = struct.unpack(">h", data.read(2))
- my_dict['CSYS'] = ena
- sub2chunklen -= 2
- else: # Misc Chunks
- ###if DEBUG: print "------------ SURF: BLOK: TMAP: %s: skipping" % sub2chunkname
- pass
- if sub2chunklen > 0:
- discard = data.read(sub2chunklen)
- #end loop on blok attributes subchunks
- ##############################################################
- # ok, now other attributes without sub_chunks
- ##############################################################
- while(accumulate_i < lenght): # ---------------------------------- loop on header parameters: lenght has already stripped the 6 bypes header
- subchunkname, = struct.unpack("4s", data.read(4))
- subchunklen, = struct.unpack(">H", data.read(2))
- accumulate_i = accumulate_i + 6 + subchunklen
- if subchunkname == "PROJ":
- ###if DEBUG: print "---------- PROJ"
- p, = struct.unpack(">h", data.read(2))
- my_dict['PROJ'] = p
- subchunklen -= 2
- elif subchunkname == "AXIS":
- ###if DEBUG: print "---------- AXIS"
- a, = struct.unpack(">h", data.read(2))
- my_dict['MAJAXIS'] = a
- subchunklen -= 2
- elif subchunkname == "IMAG":
- ###if DEBUG: print "---------- IMAG"
- i, i_size = read_vx(data)
- my_dict['IMAG'] = i
- subchunklen -= i_size
- elif subchunkname == "WRAP":
- ###if DEBUG: print "---------- WRAP"
- ww, wh = struct.unpack(">hh", data.read(4))
- #reduce width and height to just 1 parameter for both
- my_dict['WRAP'] = max([ww,wh])
- #my_dict['WRAPWIDTH'] = ww
- #my_dict['WRAPHEIGHT'] = wh
- subchunklen -= 4
- elif subchunkname == "WRPW":
- ###if DEBUG: print "---------- WRPW"
- w, = struct.unpack(">f", data.read(4))
- my_dict['WRPW'] = w
- envelope, env_size = read_vx(data)
- subchunklen -= (env_size+4)
- elif subchunkname == "WRPH":
- ###if DEBUG: print "---------- WRPH"
- w, = struct.unpack(">f", data.read(4))
- my_dict['WRPH'] = w
- envelope, env_size = read_vx(data)
- subchunklen -= (env_size+4)
- elif subchunkname == "VMAP":
- ###if DEBUG: print "---------- VMAP"
- vmp, i = read_name(data)
- my_dict['VMAP'] = vmp
- my_uvname = vmp
- subchunklen -= i
- else: # Misc Chunks
- ###if DEBUG: print "---------- SURF: BLOK: %s: skipping" % subchunkname
- pass
- if subchunklen > 0:
- discard = data.read(subchunklen)
- #end loop on blok subchunks
- return my_dict, my_uvname
-
-
-# =====================
-# === Read Surfaces ===
-# =====================
-def read_surfs(lwochunk, surf_list, tag_list):
- my_dict = {}
- data = cStringIO.StringIO(lwochunk.read())
- surf_name, i = read_name(data)
- parent_name, j = read_name(data)
- i += j
- if (surf_name == "") or not(surf_name in tag_list):
- ###if DEBUG: print "Reading SURF: Actually empty surf name not allowed. Skipping"
- return {}
- if (parent_name != ""):
- parent_index = [x['NAME'] for x in surf_list].count(parent_name)
- if parent_index >0:
- my_dict = surf_list[parent_index-1]
- my_dict['NAME'] = surf_name
- ###if DEBUG: print "Surface data for TAG %s" % surf_name
- while(i < lwochunk.chunksize):
- subchunkname, = struct.unpack("4s", data.read(4))
- subchunklen, = struct.unpack(">H", data.read(2))
- i = i + 6 + subchunklen #6 bytes subchunk header
- if subchunkname == "COLR": #color: mapped on color
- ###if DEBUG: print "-------- COLR"
- r, g, b = struct.unpack(">fff", data.read(12))
- envelope, env_size = read_vx(data)
- my_dict['COLR'] = [r, g, b]
- subchunklen -= (12+env_size)
- elif subchunkname == "DIFF": #diffusion: mapped on reflection (diffuse shader)
- ###if DEBUG: print "-------- DIFF"
- s, = struct.unpack(">f", data.read(4))
- envelope, env_size = read_vx(data)
- my_dict['DIFF'] = s
- subchunklen -= (4+env_size)
- elif subchunkname == "SPEC": #specularity: mapped to specularity (spec shader)
- ###if DEBUG: print "-------- SPEC"
- s, = struct.unpack(">f", data.read(4))
- envelope, env_size = read_vx(data)
- my_dict['SPEC'] = s
- subchunklen -= (4+env_size)
- elif subchunkname == "REFL": #reflection: mapped on raymirror
- ###if DEBUG: print "-------- REFL"
- s, = struct.unpack(">f", data.read(4))
- envelope, env_size = read_vx(data)
- my_dict['REFL'] = s
- subchunklen -= (4+env_size)
- elif subchunkname == "TRNL": #translucency: mapped on same param
- ###if DEBUG: print "-------- TRNL"
- s, = struct.unpack(">f", data.read(4))
- envelope, env_size = read_vx(data)
- my_dict['TRNL'] = s
- subchunklen -= (4+env_size)
- elif subchunkname == "GLOS": #glossiness: mapped on specularity hardness (spec shader)
- ###if DEBUG: print "-------- GLOS"
- s, = struct.unpack(">f", data.read(4))
- envelope, env_size = read_vx(data)
- my_dict['GLOS'] = s
- subchunklen -= (4+env_size)
- elif subchunkname == "TRAN": #transparency: inverted and mapped on alpha channel
- ###if DEBUG: print "-------- TRAN"
- s, = struct.unpack(">f", data.read(4))
- envelope, env_size = read_vx(data)
- my_dict['TRAN'] = s
- subchunklen -= (4+env_size)
- elif subchunkname == "LUMI": #luminosity: mapped on emit channel
- ###if DEBUG: print "-------- LUMI"
- s, = struct.unpack(">f", data.read(4))
- envelope, env_size = read_vx(data)
- my_dict['LUMI'] = s
- subchunklen -= (4+env_size)
- elif subchunkname == "GVAL": #glow: mapped on add channel
- ###if DEBUG: print "-------- GVAL"
- s, = struct.unpack(">f", data.read(4))
- envelope, env_size = read_vx(data)
- my_dict['GVAL'] = s
- subchunklen -= (4+env_size)
- elif subchunkname == "SMAN": #smoothing angle
- ###if DEBUG: print "-------- SMAN"
- s, = struct.unpack(">f", data.read(4))
- my_dict['SMAN'] = s
- subchunklen -= 4
- elif subchunkname == "SIDE": #double sided?
- ###if DEBUG: print "-------- SIDE" #if 1 side do not define key
- s, = struct.unpack(">H", data.read(2))
- if s == 3:
- my_dict['SIDE'] = s
- subchunklen -= 2
- elif subchunkname == "RIND": #Refraction: mapped on IOR
- ###if DEBUG: print "-------- RIND"
- s, = struct.unpack(">f", data.read(4))
- envelope, env_size = read_vx(data)
- my_dict['RIND'] = s
- subchunklen -= (4+env_size)
- elif subchunkname == "BLOK": #blocks
- ###if DEBUG: print "-------- BLOK"
- rr, uvname = read_surfblok(data.read(subchunklen))
- #paranoia setting: preventing adding an empty dict
- if rr: # != {}
- try:
- my_dict['BLOK'].append(rr)
- except:
- my_dict['BLOK'] = [rr]
-
- if uvname: # != "":
- my_dict['UVNAME'] = uvname #theoretically there could be a number of them: only one used per surf
- # all are dictionaries - so testing keys
- if not('g_IMAG' in my_dict) and ('CHAN' in rr) and ('OPAC' in rr) and ('IMAG' in rr):
- if (rr['CHAN'] == 'COLR') and (rr['OPAC'] == 0):
- my_dict['g_IMAG'] = rr['IMAG'] #do not set anything, just save image object for later assignment
- subchunklen = 0 #force ending
- else: # Misc Chunks
- pass
- ###if DEBUG: print "-------- SURF:%s: skipping" % subchunkname
- if subchunklen > 0:
- discard = data.read(subchunklen)
- #end loop on surf chunks
- try:#if my_dict.has_key('BLOK'):
- my_dict['BLOK'].reverse() #texture applied in reverse order with respect to reading from lwo
- except:
- pass
-
- #uncomment this if material pre-allocated by read_surf
- my_dict['g_MAT'] = bpy.data.materials.new(my_dict['NAME'])
- ###if DEBUG: print "-> Material pre-allocated."
- return my_dict
-
-# =========================
-# === Recalculate Faces ===
-# =========================
-
-def get_uvface(complete_list, facenum):
- # extract from the complete list only vertexes of the desired polygon
- '''
- my_facelist = []
- for elem in complete_list:
- if elem[0] == facenum:
- my_facelist.append(elem)
- return my_facelist
- '''
- return [elem for elem in complete_list if elem[0] == facenum]
-
-def get_newindex(polygon_list, vertnum):
- # extract from the polygon list the new index associated to a vertex
- if not polygon_list: # == []
- return -1
- for elem in polygon_list:
- if elem[1] == vertnum:
- return elem[2]
- # ###if DEBUG: print "WARNING: expected vertex %s for polygon %s. Polygon_list dump follows" % (vertnum, polygon_list[0][0])
- # ###if DEBUG: print polygon_list
- return -1
-
-def get_surf(surf_list, cur_tag):
- for elem in surf_list: # elem can be None
- if elem and elem['NAME'] == cur_tag:
- return elem
- return {}
-
-
-
-# ====================================
-# === Modified Create Blender Mesh ===
-# ====================================
-def my_create_mesh(clip_list, surf, objspec_list, current_facelist, objname, not_used_faces):
- #take the needed faces and update the not-used face list
- complete_vertlist = objspec_list[2]
- complete_facelist = objspec_list[3]
- uvcoords_dict = objspec_list[7]
- facesuv_dict = objspec_list[8]
- vertex_map = {} #implementation as dict
- cur_ptag_faces = []
- cur_ptag_faces_indexes = []
- maxface = len(complete_facelist)
- for ff in current_facelist:
- if ff >= maxface:
- ###if DEBUG: print "Non existent face addressed: Giving up with this object"
- return None, not_used_faces #return the created object
- cur_face = complete_facelist[ff]
- cur_ptag_faces_indexes.append(ff)
- if not_used_faces: # != []
- not_used_faces[ff] = -1
- for vv in cur_face: vertex_map[vv] = 1
- #end loop on faces
- store_edge = 0
-
- scn= bpy.data.scenes.active
- msh = bpy.data.meshes.new()
- obj = scn.objects.new(msh)
-
- mat = None
- try:
- msh.materials = [surf['g_MAT']]
- except:
- pass
-
- msh.mode |= Blender.Mesh.Modes.AUTOSMOOTH #smooth it anyway
- if 'SMAN' in surf: # has_key
- #not allowed mixed mode mesh (all the mesh is smoothed and all with the same angle)
- #only one smoothing angle will be active! => take the max one
- msh.degr = min(80, int(surf['SMAN']/3.1415926535897932384626433832795*180.0)) #lwo in radians - blender in degrees
-
- try:
- img= lookup_imag(clip_list, surf['g_IMAG'])['g_IMG']
- except:
- img= None
-
- #uv_flag = ((surf.has_key('UVNAME')) and (uvcoords_dict.has_key(surf['UVNAME'])) and (img != None))
- uv_flag = (('UVNAME' in surf) and (surf['UVNAME'] in uvcoords_dict))
-
- ###if DEBUG: print "\n#===================================================================#"
- ###if DEBUG: print "Processing Object: %s" % objname
- ###if DEBUG: print "#===================================================================#"
-
- if uv_flag:
- msh.verts.extend([(0.0,0.0,0.0),])
- j = 1
- else:
- j = 0
-
- def tmp_get_vert(k, i):
- vertex_map[k] = i+j # j is the dummy vert
- # ###if DEBUG: print complete_vertlist[i]
- return complete_vertlist[k]
-
-
-
- msh.verts.extend([tmp_get_vert(k, i) for i, k in enumerate(vertex_map.iterkeys())])
- msh.transform(TXMTX) # faster then applying while reading.
- #end sweep over vertexes
-
- #append faces
- FACE_TEX= Blender.Mesh.FaceModes.TEX
- FACE_ALPHA= Blender.Mesh.FaceTranspModes.ALPHA
- EDGE_DRAW_FLAG= Blender.Mesh.EdgeFlags.EDGEDRAW | Blender.Mesh.EdgeFlags.EDGERENDER
-
-
- edges = []
- face_data = [] # [(indicies, material, uvs, image), ]
- face_uvs = []
- edges_fgon = []
-
- if uv_flag:
- uvcoords_dict_context = uvcoords_dict[surf['UVNAME']]
- try: current_uvdict = facesuv_dict[surf['UVNAME']]
- except: current_uvdict = None
-
- default_uv = Blender.Mathutils.Vector(0,0)
- def tmp_get_face_uvs(cur_face, i):
- uvs = []
- if current_uvdict:
- uvface = get_uvface(current_uvdict,i)
- for vi in cur_face:
- ni = get_newindex(uvface, vi)
- if ni == -1: ni = vi
-
- try:
- uvs.append(uvcoords_dict_context[ ni ])
- except:
- ###if DEBUG: print '\tWarning, Corrupt UVs'
- uvs.append(default_uv)
- else:
- for vi in cur_face:
- try:
- uvs.append(uvcoords_dict_context[ vi ])
- except:
- ###if DEBUG: print '\tWarning, Corrupt UVs'
- uvs.append(default_uv)
-
- return uvs
- cur_face
- for i in cur_ptag_faces_indexes:
- cur_face = complete_facelist[i]
- numfaceverts = len(cur_face)
-
- if numfaceverts == 2: edges.append((vertex_map[cur_face[0]], vertex_map[cur_face[1]]))
- elif numfaceverts == 3 or numfaceverts == 4:
- rev_face = [__i for __i in reversed(cur_face)]
- face_data.append( [vertex_map[j] for j in rev_face] )
- if uv_flag: face_uvs.append(tmp_get_face_uvs(rev_face, i))
- elif numfaceverts > 4:
- meta_faces= BPyMesh.ngon(complete_vertlist, cur_face, PREF_FIX_LOOPS= True)
- edge_face_count = {}
- for mf in meta_faces:
- # These will always be tri's since they are scanfill faces
- mf = cur_face[mf[2]], cur_face[mf[1]], cur_face[mf[0]]
- face_data.append( [vertex_map[j] for j in mf] )
-
- if uv_flag: face_uvs.append(tmp_get_face_uvs(mf, i))
-
- #if USE_FGON:
- if len(meta_faces) > 1:
- mf = face_data[-1] # reuse mf
- for j in xrange(3):
- v1= mf[j]
- v2= mf[j-1]
- if v1!=v2:
- if v1>v2:
- v2,v1= v1,v2
- try:
- edge_face_count[v1,v2]+= 1
- except:
- edge_face_count[v1,v2]= 0
-
-
-
- if edge_face_count:
- edges_fgon.extend( [vert_key for vert_key, count in edge_face_count.iteritems() if count] )
-
- if edges:
- msh.edges.extend(edges)
-
- face_mapping_removed = msh.faces.extend(face_data, indexList=True)
- if 'TRAN' in surf or (mat and mat.alpha<1.0): # incase mat is null
- transp_flag = True
- else:
- transp_flag = False
-
- if uv_flag:
- msh.faceUV = True
- msh_faces= msh.faces
- for i, uvs in enumerate(face_uvs):
- i_mapped = face_mapping_removed[i]
- if i_mapped != None:
- f = msh_faces[i_mapped]
- f.uv = uvs
- if img:
- f.image = img
-
- if transp_flag: f.transp |= FACE_ALPHA
-
- if edges_fgon:
- msh_edges = msh.edges
- FGON= Blender.Mesh.EdgeFlags.FGON
- edges_fgon = msh.findEdges( edges_fgon )
- if type(edges_fgon) != list: edges_fgon = [edges_fgon]
- for ed in edges_fgon:
- if ed!=None:
- msh_edges[ed].flag |= FGON
-
- if not(uv_flag): #clear eventual UV data
- msh.faceUV = False
-
- if uv_flag:
- msh.verts.delete([0,])
-
- return obj, not_used_faces #return the created object
-
-
-# ============================================
-# === Set Subsurf attributes on given mesh ===
-# ============================================
-def set_subsurf(obj):
- mods = obj.modifiers # get the object's modifiers
- mod = mods.append(Blender.Modifier.Type.SUBSURF) # add a new subsurf modifier
- mod[Blender.Modifier.Settings.LEVELS] = 2 # set subsurf subdivision levels to 2
- mod[Blender.Modifier.Settings.RENDLEVELS] = 2 # set subsurf rendertime subdivision levels to 2
- obj.makeDisplayList()
-
-
-# =================================
-# === object size and dimension ===
-# =================================
-def obj_size_pos(obj):
- bbox = obj.getBoundBox()
- bbox_min = map(lambda *row: min(row), *bbox) #transpose & get min
- bbox_max = map(lambda *row: max(row), *bbox) #transpose & get max
- obj_size = (bbox_max[0]-bbox_min[0], bbox_max[1]-bbox_min[1], bbox_max[2]-bbox_min[2])
- obj_pos = ( (bbox_max[0]+bbox_min[0]) / 2, (bbox_max[1]+bbox_min[1]) / 2, (bbox_max[2]+bbox_min[2]) / 2)
- return (obj_size, obj_pos)
-
-
-# =========================
-# === Create the object ===
-# =========================
-def create_objects(clip_list, objspec_list, surf_list):
- nf = len(objspec_list[3])
- not_used_faces = range(nf)
- ptag_dict = objspec_list[5]
- obj_dict = {} #links tag names to object, used for material assignments
- obj_dim_dict = {}
- obj_list = [] #have it handy for parent association
- middlechar = "+"
- endchar = ""
- if (objspec_list[6] == 1):
- middlechar = endchar = "#"
- for cur_tag, ptag_dict_val in ptag_dict.iteritems():
- if ptag_dict_val != []:
- cur_surf = get_surf(surf_list, cur_tag)
- cur_obj, not_used_faces= my_create_mesh(clip_list, cur_surf, objspec_list, ptag_dict_val, objspec_list[0][:9]+middlechar+cur_tag[:9], not_used_faces)
- # Works now with new modifiers
- if objspec_list[6] == 1:
- set_subsurf(cur_obj)
- if cur_obj: # != None
- obj_dict[cur_tag] = cur_obj
- obj_dim_dict[cur_tag] = obj_size_pos(cur_obj)
- obj_list.append(cur_obj)
- #end loop on current group
- #and what if some faces not used in any named PTAG? get rid of unused faces
- orphans = []
- for tt in not_used_faces:
- if tt > -1: orphans.append(tt)
- #end sweep on unused face list
- not_used_faces = None
- if orphans: # != []
- cur_surf = get_surf(surf_list, "_Orphans")
- cur_obj, not_used_faces = my_create_mesh(clip_list, cur_surf, objspec_list, orphans, objspec_list[0][:9]+middlechar+"Orphans", [])
- if cur_obj: # != None
- if objspec_list[6] == 1:
- set_subsurf(cur_obj)
- obj_dict["_Orphans"] = cur_obj
- obj_dim_dict["_Orphans"] = obj_size_pos(cur_obj)
- obj_list.append(cur_obj)
- objspec_list[1]= obj_dict
- objspec_list[4]= obj_dim_dict
-
- return
-
-
-
-# ===========================================
-# === Lookup for image index in clip_list ===
-# ===========================================
-def lookup_imag(clip_list, ima_id):
- for ii in clip_list:
- if ii and ii['ID'] == ima_id:
- if 'XREF' in ii: # has_key
- #cross reference - recursively look for images
- return lookup_imag(clip_list, ii['XREF'])
- else:
- return ii
- return None
-
-
-# ===================================================
-# === Create and assign image mapping to material ===
-# ===================================================
-def create_blok(surf, mat, clip_list, obj_size, obj_pos):
-
- def output_size_ofs(size, pos, blok):
- #just automate repetitive task
- # 0 == X, 1 == Y, 2 == Z
- size_default = [1.0] * 3
- size2 = [1.0] * 3
- ofs_default = [0.0] * 3
- offset = [1.0] * 3
- axis_default = [Blender.Texture.Proj.X, Blender.Texture.Proj.Y, Blender.Texture.Proj.Z]
- axis = [1.0] * 3
- c_map_txt = [" X--", " -Y-", " --Z"]
- c_map = [0,1,2] # standard, good for Z axis projection
- if blok['MAJAXIS'] == 0:
- c_map = [1,2,0] # X axis projection
- if blok['MAJAXIS'] == 2:
- c_map = [0,2,1] # Y axis projection
-
- ###if DEBUG: print "!!!axis mapping:"
- #this is the smart way
- ###if DEBUG: for mp in c_map: print c_map_txt[mp]
-
- if blok['SIZE'][0] != 0.0: #paranoia controls
- size_default[0] = (size[0]/blok['SIZE'][0])
- ofs_default[0] = ((blok['CNTR'][0]-pos[0])/blok['SIZE'][0])
- if blok['SIZE'][1] != 0.0:
- size_default[2] = (size[2]/blok['SIZE'][1])
- ofs_default[2] = ((blok['CNTR'][1]-pos[2])/blok['SIZE'][1])
- if blok['SIZE'][2] != 0.0:
- size_default[1] = (size[1]/blok['SIZE'][2])
- ofs_default[1] = ((blok['CNTR'][2]-pos[1])/blok['SIZE'][2])
-
- for mp in xrange(3):
- axis[mp] = axis_default[c_map[mp]]
- size2[mp] = size_default[c_map[mp]]
- offset[mp] = ofs_default[c_map[mp]]
- if offset[mp]>10.0: offset[mp]-10.0
- if offset[mp]<-10.0: offset[mp]+10.0
-# size = [size_default[mp] for mp in c_map]
-
- ###if DEBUG: print "!!!texture size and offsets:"
- ###if DEBUG: print " sizeX = %.5f; sizeY = %.5f; sizeZ = %.5f" % (size[0],size[1],size[2])
- ###if DEBUG: print " ofsX = %.5f; ofsY = %.5f; ofsZ = %.5f" % (offset[0],offset[1],offset[2])
- return axis, size2, offset
-
- ti = 0
- alphaflag = 0 #switched to 1 if some tex in this block is using alpha
- lastimag = 0 #experimental ....
- for blok in surf['BLOK']:
- ###if DEBUG: print "#...................................................................#"
- ###if DEBUG: print "# Processing texture block no.%s for surf %s" % (ti,surf['NAME'])
- ###if DEBUG: print "#...................................................................#"
- # tobj.pdict (blok)
- if ti > 9: break #only 8 channels 0..7 allowed for texture mapping
- #if not blok['ENAB']:
- # ###if DEBUG: print "***Image is not ENABled! Quitting this block"
- # break
- if not('IMAG' in blok): # has_key
- ###if DEBUG: print "***No IMAGE for this block? Quitting"
- break #extract out the image index within the clip_list
- if blok['IMAG'] == 0: blok['IMAG'] = lastimag #experimental ....
- ###if DEBUG: print "looking for image number %d" % blok['IMAG']
- ima = lookup_imag(clip_list, blok['IMAG'])
- if ima == None:
- ###if DEBUG: print "***Block index image not within CLIP list? Quitting Block"
- break #safety check (paranoia setting)
- img = ima['g_IMG']
- lastimag = blok['IMAG'] #experimental ....
- if img == None:
- ###if DEBUG: print "***Failed to pre-allocate image %s found: giving up" % ima['BASENAME']
- break
- tname = str(ima['ID'])
- if blok['ENAB']:
- tname += "+"
- else:
- tname += "x" #let's signal when should not be enabled
- if 'CHAN' in blok: # has_key
- tname += blok['CHAN']
- newtex = bpy.data.textures.new(tname)
- newtex.setType('Image') # make it anu image texture
- newtex.image = img
- #how does it extends beyond borders
- if 'WRAP' in blok: # has_key
- if (blok['WRAP'] == 3) or (blok['WRAP'] == 2):
- newtex.setExtend('Extend')
- elif (blok['WRAP'] == 1):
- newtex.setExtend('Repeat')
- elif (blok['WRAP'] == 0):
- newtex.setExtend('Clip')
- ###if DEBUG: print "generated texture %s" % tname
-
- #MapTo is determined by CHAN parameter
- #assign some defaults
- colfac = 1.0
- dvar = 1.0
- norfac = 0.5
- nega = False
- mapflag = Blender.Texture.MapTo.COL #default to color
- maptype = Blender.Texture.Mappings.FLAT
- if 'CHAN' in blok: # has_key
- if blok['CHAN'] == 'COLR' and 'OPACVAL' in blok: # has_key
- colfac = blok['OPACVAL']
- # Blender needs this to be clamped
- colfac = max(0.0, min(1.0, colfac))
- ###if DEBUG: print "!!!Set Texture -> MapTo -> Col = %.3f" % colfac
- if blok['CHAN'] == 'BUMP':
- mapflag = Blender.Texture.MapTo.NOR
- if 'OPACVAL' in blok: norfac = blok['OPACVAL'] # has_key
- ###if DEBUG: print "!!!Set Texture -> MapTo -> Nor = %.3f" % norfac
- if blok['CHAN'] == 'LUMI':
- mapflag = Blender.Texture.MapTo.EMIT
- if 'OPACVAL' in blok: dvar = blok['OPACVAL'] # has_key
- ###if DEBUG: print "!!!Set Texture -> MapTo -> DVar = %.3f" % dvar
- if blok['CHAN'] == 'DIFF':
- mapflag = Blender.Texture.MapTo.REF
- if 'OPACVAL' in blok: dvar = blok['OPACVAL'] # has_key
- ###if DEBUG: print "!!!Set Texture -> MapTo -> DVar = %.3f" % dvar
- if blok['CHAN'] == 'SPEC':
- mapflag = Blender.Texture.MapTo.SPEC
- if 'OPACVAL' in blok: dvar = blok['OPACVAL'] # has_key
- ###if DEBUG: print "!!!Set Texture -> MapTo -> DVar = %.3f" % dvar
- if blok['CHAN'] == 'TRAN':
- mapflag = Blender.Texture.MapTo.ALPHA
- if 'OPACVAL' in blok: dvar = blok['OPACVAL'] # has_key
- ###if DEBUG: print "!!!Set Texture -> MapTo -> DVar = %.3f" % dvar
- alphaflag = 1
- nega = True
- if 'NEGA' in blok: # has_key
- ###if DEBUG: print "!!!Watch-out: effect of this texture channel must be INVERTED!"
- nega = not nega
-
- blendmode_list = ['Mix',
- 'Subtractive',
- 'Difference',
- 'Multiply',
- 'Divide',
- 'Mix with calculated alpha layer and stencil flag',
- 'Texture Displacement',
- 'Additive']
- set_blendmode = 7 #default additive
- if 'OPAC' in blok: # has_key
- set_blendmode = blok['OPAC']
- if set_blendmode == 5: #transparency
- newtex.imageFlags |= Blender.Texture.ImageFlags.CALCALPHA
- if nega: newtex.flags |= Blender.Texture.Flags.NEGALPHA
- ###if DEBUG: print "!!!Set Texture -> MapTo -> Blending Mode = %s" % blendmode_list[set_blendmode]
-
- #the TexCo flag is determined by PROJ parameter
- axis = [Blender.Texture.Proj.X, Blender.Texture.Proj.Y, Blender.Texture.Proj.Z]
- size = [1.0] * 3
- ofs = [0.0] * 3
- if 'PROJ' in blok: # has_key
- if blok['PROJ'] == 0: #0 - Planar
- ###if DEBUG: print "!!!Flat projection"
- coordflag = Blender.Texture.TexCo.ORCO
- maptype = Blender.Texture.Mappings.FLAT
- elif blok['PROJ'] == 1: #1 - Cylindrical
- ###if DEBUG: print "!!!Cylindrical projection"
- coordflag = Blender.Texture.TexCo.ORCO
- maptype = Blender.Texture.Mappings.TUBE
- elif blok['PROJ'] == 2: #2 - Spherical
- ###if DEBUG: print "!!!Spherical projection"
- coordflag = Blender.Texture.TexCo.ORCO
- maptype = Blender.Texture.Mappings.SPHERE
- elif blok['PROJ'] == 3: #3 - Cubic
- ###if DEBUG: print "!!!Cubic projection"
- coordflag = Blender.Texture.TexCo.ORCO
- maptype = Blender.Texture.Mappings.CUBE
- elif blok['PROJ'] == 4: #4 - Front Projection
- ###if DEBUG: print "!!!Front projection"
- coordflag = Blender.Texture.TexCo.ORCO
- maptype = Blender.Texture.Mappings.FLAT # ??? could it be a FLAT with some other TexCo type?
- elif blok['PROJ'] == 5: #5 - UV
- ###if DEBUG: print "UVMapped"
- coordflag = Blender.Texture.TexCo.UV
- maptype = Blender.Texture.Mappings.FLAT #in case of UV default to FLAT mapping => effectively not used
- if blok['PROJ'] != 5: #This holds for any projection map except UV
- axis, size, ofs = output_size_ofs(obj_size, obj_pos, blok)
-
- # Clamp ofs and size else blender will raise an error
- for ii in xrange(3):
- ofs[ii]= min(10.0, max(-10, ofs[ii]))
- size[ii]= min(100, max(-100, size[ii]))
-
- mat.setTexture(ti, newtex, coordflag, mapflag)
- current_mtex = mat.getTextures()[ti]
- current_mtex.mapping = maptype
- current_mtex.colfac = colfac
- current_mtex.dvar = dvar
- current_mtex.norfac = norfac
- current_mtex.neg = nega
- current_mtex.xproj = axis[0]
- current_mtex.yproj = axis[1]
- current_mtex.zproj = axis[2]
- current_mtex.size = tuple(size)
- current_mtex.ofs = tuple(ofs)
- if (set_blendmode == 5): #transparency
- current_mtex.stencil = not (nega)
-
- ti += 1
- #end loop over bloks
- return alphaflag
-
-
-# ========================================
-# === Create and assign a new material ===
-# ========================================
-#def update_material(surf_list, ptag_dict, obj, clip_list, uv_dict, dir_part):
-def update_material(clip_list, objspec, surf_list):
- if (surf_list == []) or (objspec[5] == {}) or (objspec[1] == {}):
- ###if DEBUG: print "something getting wrong in update_material: dump follows ..."
- ###if DEBUG: print surf_list
- ###if DEBUG: print objspec[5]
- ###if DEBUG: print objspec[1]
- return
- obj_dict = objspec[1]
- all_faces = objspec[3]
- obj_dim_dict = objspec[4]
- ptag_dict = objspec[5]
- uvcoords_dict = objspec[7]
- facesuv_dict = objspec[8]
- for surf in surf_list:
- if surf and surf['NAME'] in ptag_dict: # in ptag_dict.keys()
- ###if DEBUG: print "#-------------------------------------------------------------------#"
- ###if DEBUG: print "Processing surface (material): %s" % surf['NAME']
- ###if DEBUG: print "#-------------------------------------------------------------------#"
- #material set up
- facelist = ptag_dict[surf['NAME']]
- #bounding box and position
- cur_obj = obj_dict[surf['NAME']]
- obj_size = obj_dim_dict[surf['NAME']][0]
- obj_pos = obj_dim_dict[surf['NAME']][1]
- ###if DEBUG: print surf
- #uncomment this if material pre-allocated by read_surf
- mat = surf['g_MAT']
- if mat == None:
- ###if DEBUG: print "Sorry, no pre-allocated material to update. Giving up for %s." % surf['NAME']
- break
- #mat = Blender.Material.New(surf['NAME'])
- #surf['g_MAT'] = mat
- if 'COLR' in surf: # has_key
- mat.rgbCol = surf['COLR']
- if 'LUMI' in surf:
- mat.setEmit(surf['LUMI'])
- if 'GVAL' in surf: # has_key
- mat.setAdd(surf['GVAL'])
- if 'SPEC' in surf: # has_key
- mat.setSpec(surf['SPEC']) #it should be * 2 but seems to be a bit higher lwo [0.0, 1.0] - blender [0.0, 2.0]
- if 'DIFF' in surf: # has_key
- mat.setRef(surf['DIFF']) #lwo [0.0, 1.0] - blender [0.0, 1.0]
- if 'GLOS' in surf: # has_key #lwo [0.0, 1.0] - blender [0, 255]
- glo = int(371.67 * surf['GLOS'] - 42.334) #linear mapping - seems to work better than exp mapping
- if glo <32: glo = 32 #clamped to 32-255
- if glo >255: glo = 255
- mat.setHardness(glo)
- if 'TRNL' in surf: # has_key
- mat.setTranslucency(surf['TRNL']) #NOT SURE ABOUT THIS lwo [0.0, 1.0] - blender [0.0, 1.0]
-
- mm = mat.mode
- mm |= Blender.Material.Modes.TRANSPSHADOW
- if 'REFL' in surf: # has_key
- mat.setRayMirr(surf['REFL']) #lwo [0.0, 1.0] - blender [0.0, 1.0]
- mm |= Blender.Material.Modes.RAYMIRROR
- if 'TRAN' in surf: # has_key
- mat.setAlpha(1.0-surf['TRAN']) #lwo [0.0, 1.0] - blender [1.0, 0.0]
- mm |= Blender.Material.Modes.RAYTRANSP
- if 'RIND' in surf: # has_key
- s = surf['RIND']
- if s < 1.0: s = 1.0
- if s > 3.0: s = 3.0
- mat.setIOR(s) #clipped to blender [1.0, 3.0]
- mm |= Blender.Material.Modes.RAYTRANSP
- if 'BLOK' in surf and surf['BLOK'] != []:
- #update the material according to texture.
- alphaflag = create_blok(surf, mat, clip_list, obj_size, obj_pos)
- if alphaflag:
- mm |= Blender.Material.Modes.RAYTRANSP
- mat.mode = mm
- #finished setting up the material
- #end if exist SURF
- #end loop on materials (SURFs)
- return
-
-
-# ======================
-# === Read Faces 6.0 ===
-# ======================
-def read_faces_6(lwochunk):
- data = cStringIO.StringIO(lwochunk.read())
- faces = []
- polygon_type = data.read(4)
- subsurf = 0
- if polygon_type != "FACE" and polygon_type != "PTCH":
- ###if DEBUG: print "No FACE/PATCH Were Found. Polygon Type: %s" % polygon_type
- return "", 2
- if polygon_type == 'PTCH': subsurf = 1
- i = 0
- while(i < lwochunk.chunksize-4):
- #if not i%1000 and my_meshtools.show_progress:
- # Blender.Window.DrawProgressBar(float(i)/lwochunk.chunksize, "Reading Faces")
- facev = []
- numfaceverts, = struct.unpack(">H", data.read(2))
- i += 2
-
- for j in xrange(numfaceverts):
- index, index_size = read_vx(data)
- i += index_size
- facev.append(index)
- faces.append(facev)
- ###if DEBUG: print "read %s faces; type of block %d (0=FACE; 1=PATCH)" % (len(faces), subsurf)
- return faces, subsurf
-
-def main():
- if not struct:
- Blender.Draw.PupMenu('This importer requires a full python install')
- return
-
- Blender.Window.FileSelector(read, "Import LWO", '*.lwo')
-
-if __name__=='__main__':
- main()
-
-
-# Cams debugging lwo loader
-"""
-TIME= Blender.sys.time()
-import os
-print 'Searching for files'
-os.system('find /fe/lwo/Objects/ -follow -iname "*.lwo" > /tmp/templwo_list')
-# os.system('find /storage/ -iname "*.lwo" > /tmp/templwo_list')
-print '...Done'
-file= open('/tmp/templwo_list', 'r')
-lines= file.readlines()
-
-# sort by filesize for faster testing
-lines_size = [(os.path.getsize(f[:-1]), f[:-1]) for f in lines]
-lines_size.sort()
-lines = [f[1] for f in lines_size]
-
-file.close()
-
-def between(v,a,b):
- if v <= max(a,b) and v >= min(a,b):
- return True
-
- return False
-size= 0.0
-for i, _lwo in enumerate(lines):
- #if i==425: # SCANFILL
- #if 1:
- #if i==520: # SCANFILL CRASH
- #if i==47: # SCANFILL CRASH
- #if between(i, 525, 550):
- #if i > 1635:
- #if i != 1519: # 730
- if i>141:
- #if 1:
- # _lwo= _lwo[:-1]
- print 'Importing', _lwo, '\nNUMBER', i, 'of', len(lines)
- _lwo_file= _lwo.split('/')[-1].split('\\')[-1]
- newScn= bpy.data.scenes.new(_lwo_file)
- bpy.data.scenes.active = newScn
- size += ((os.path.getsize(_lwo)/1024.0))/ 1024.0
- read(_lwo)
- # Remove objects to save memory?
- '''
- for ob in newScn.objects:
- if ob.type=='Mesh':
- me= ob.getData(mesh=1)
- me.verts= None
- newScn.unlink(ob)
- '''
- print 'mb size so far', size
-
-print 'TOTAL TIME: %.6f' % (Blender.sys.time() - TIME)
-""" \ No newline at end of file