[Bf-extensions-cvs] SVN commit: /data/svn/bf-extensions [991] trunk/py/scripts/addons/ io_import_scene_lwo.py: add absolute morph and edge weighting (crease) support.
Ken Nign
ken at virginpi.com
Wed Sep 8 05:55:51 CEST 2010
Revision: 991
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-extensions&revision=991
Author: ken9
Date: 2010-09-08 05:55:42 +0200 (Wed, 08 Sep 2010)
Log Message:
-----------
add absolute morph and edge weighting (crease) support.
safely create new edges.
trailing whitespace cleanup.
Modified Paths:
--------------
trunk/py/scripts/addons/io_import_scene_lwo.py
Modified: trunk/py/scripts/addons/io_import_scene_lwo.py
===================================================================
--- trunk/py/scripts/addons/io_import_scene_lwo.py 2010-09-08 02:23:49 UTC (rev 990)
+++ trunk/py/scripts/addons/io_import_scene_lwo.py 2010-09-08 03:55:42 UTC (rev 991)
@@ -21,7 +21,7 @@
bl_addon_info= {
"name": "Import LightWave Objects",
"author": "Ken Nign (Ken9)",
- "version": (1,0),
+ "version": (1, 2),
"blender": (2, 5, 3),
"api": 31744,
"location": "File > Import > LightWave Object (.lwo)",
@@ -35,7 +35,7 @@
# Copyright (c) Ken Nign 2010
# ken at virginpi.com
#
-# Version 1.0 - Sep 1, 2010
+# Version 1.2 - Sep 7, 2010
#
# Loads a LightWave .lwo object file, including the vertex maps such as
# UV, Morph, Color and Weight maps.
@@ -50,10 +50,17 @@
# NGons, polygons with more than 4 points are supported, but are
# added (as triangles) after the vertex maps have been applied. Thus they
# won't contain all the vertex data that the original ngon had.
-#
+#
# Blender is limited to only 8 UV Texture and 8 Vertex Color maps,
# thus only the first 8 of each can be imported.
+#
+# History:
+#
+# 1.2 Added Absolute Morph and CC Edge Weight support.
+# Made edge creation safer.
+# 1.0 First Release
+
import os
import io
import time
@@ -80,6 +87,7 @@
"colmaps",
"uvmaps",
"morphs",
+ "edge_weights",
"surf_tags",
"has_subds",
)
@@ -87,7 +95,7 @@
self.name= ""
self.index= -1
self.parent_index= -1
- self.pivot= [0,0,0]
+ self.pivot= [0, 0, 0]
self.pols= []
self.bones= []
self.bone_names= {}
@@ -97,6 +105,7 @@
self.colmaps= {}
self.uvmaps= {}
self.morphs= {}
+ self.edge_weights= {}
self.surf_tags= {}
self.has_subds= False
@@ -141,38 +150,39 @@
def load_lwo(filename,
context,
- ADD_SUBD_MOD= True,
- LOAD_HIDDEN= False,
- SKEL_TO_ARM= True):
+ ADD_SUBD_MOD=True,
+ LOAD_HIDDEN=False,
+ SKEL_TO_ARM=True):
'''Read the LWO file, hand off to version specific function.'''
name, ext= os.path.splitext(os.path.basename(filename))
file= open(filename, 'rb')
-
+
try:
header, chunk_size, chunk_name = struct.unpack(">4s1L4s", file.read(12))
except:
print("Error parsing file header!")
file.close()
return
-
+
layers= []
surfs= {}
tags= []
# Gather the object data using the version specific handler.
if chunk_name == b'LWO2':
read_lwo2(file, filename, layers, surfs, tags, ADD_SUBD_MOD, LOAD_HIDDEN, SKEL_TO_ARM)
- elif chunk_name == b'LWOB' or chunk_name == b'LWLO': # LWLO is a layered object.
+ elif chunk_name == b'LWOB' or chunk_name == b'LWLO':
+ # LWOB and LWLO are the old format, LWLO is a layered object.
read_lwob(file, filename, layers, surfs, tags, ADD_SUBD_MOD)
else:
print("Not a supported file type!")
file.close()
return
-
+
file.close()
-
+
# With the data gathered, build the object(s).
build_objects(layers, surfs, tags, name, ADD_SUBD_MOD, SKEL_TO_ARM)
-
+
layers= None
surfs.clear()
tags= None
@@ -184,13 +194,13 @@
last_pols_count= 0
just_read_bones= False
print("Importing LWO: " + filename + "\nLWO v2 Format")
-
+
while True:
try:
rootchunk = chunk.Chunk(file)
except EOFError:
break
-
+
if rootchunk.chunkname == b'TAGS':
read_tags(rootchunk.read(), tags)
elif rootchunk.chunkname == b'LAYR':
@@ -199,33 +209,39 @@
read_pnts(rootchunk.read(), layers)
elif rootchunk.chunkname == b'VMAP' and handle_layer:
vmap_type = rootchunk.read(4)
-
+
if vmap_type == b'WGHT':
read_weightmap(rootchunk.read(), layers)
elif vmap_type == b'MORF':
- read_morph(rootchunk.read(), layers)
+ read_morph(rootchunk.read(), layers, False)
+ elif vmap_type == b'SPOT':
+ read_morph(rootchunk.read(), layers, True)
elif vmap_type == b'TXUV':
read_uvmap(rootchunk.read(), layers)
elif vmap_type == b'RGB ' or vmap_type == b'RGBA':
read_colmap(rootchunk.read(), layers)
else:
rootchunk.skip()
-
+
elif rootchunk.chunkname == b'VMAD' and handle_layer:
vmad_type= rootchunk.read(4)
-
+
if vmad_type == b'TXUV':
read_uv_vmad(rootchunk.read(), layers, last_pols_count)
elif vmad_type == b'RGB ' or vmad_type == b'RGBA':
read_color_vmad(rootchunk.read(), layers, last_pols_count)
+ elif vmad_type == b'WGHT':
+ # We only read the Edge Weight map if it's there.
+ read_weight_vmad(rootchunk.read(), layers)
else:
rootchunk.skip()
-
+
elif rootchunk.chunkname == b'POLS' and handle_layer:
face_type = rootchunk.read(4)
just_read_bones= False
# PTCH is LW's Subpatches, SUBD is CatmullClark.
- if (face_type == b'FACE' or face_type == b'PTCH' or face_type == b'SUBD') and handle_layer:
+ if (face_type == b'FACE' or face_type == b'PTCH' or
+ face_type == b'SUBD') and handle_layer:
last_pols_count= read_pols(rootchunk.read(), layers)
if face_type != b'FACE':
layers[-1].has_subds= True
@@ -234,13 +250,13 @@
just_read_bones= True
else:
rootchunk.skip()
-
+
elif rootchunk.chunkname == b'PTAG' and handle_layer:
- tag_type,= struct.unpack("4s", rootchunk.read(4));
+ tag_type,= struct.unpack("4s", rootchunk.read(4))
if tag_type == b'SURF' and not just_read_bones:
- # We have to ignore the surface data if we just read a bones chunk.
+ # Ignore the surface data if we just read a bones chunk.
read_surf_tags(rootchunk.read(), layers, last_pols_count)
-
+
elif skel_to_arm:
if tag_type == b'BNUP':
read_bone_tags(rootchunk.read(), layers, tags, 'BNUP')
@@ -262,19 +278,20 @@
'''Read version 1 file, LW < 6.'''
last_pols_count= 0
print("Importing LWO: " + filename + "\nLWO v1 Format")
-
+
while True:
try:
rootchunk = chunk.Chunk(file)
except EOFError:
break
-
+
if rootchunk.chunkname == b'SRFS':
read_tags(rootchunk.read(), tags)
elif rootchunk.chunkname == b'LAYR':
read_layr_5(rootchunk.read(), layers)
elif rootchunk.chunkname == b'PNTS':
- if len(layers) == 0: # LWOB files have no LAYR chunk to set this up
+ if len(layers) == 0:
+ # LWOB files have no LAYR chunk to set this up.
nlayer= _obj_layer()
nlayer.name= "Layer 1"
layers.append(nlayer)
@@ -285,7 +302,7 @@
last_pols_count= read_pols_5(rootchunk.read(), layers)
layers[-1].has_subds= True
elif rootchunk.chunkname == b'PTAG':
- tag_type,= struct.unpack("4s", rootchunk.read(4));
+ tag_type,= struct.unpack("4s", rootchunk.read(4))
if tag_type == b'SURF':
read_surf_tags_5(rootchunk.read(), layers, last_pols_count)
else:
@@ -306,7 +323,7 @@
name_len = i + 1
if name_len % 2 == 1: # Test for oddness.
name_len += 1
-
+
if i > 0:
# Some plugins put non-text strings in the tags chunk.
name = raw_name[0:i].decode("utf-8", "ignore")
@@ -315,7 +332,7 @@
return name, name_len
-
+
def read_vx(pointdata):
'''Read a variable-length index.'''
if pointdata[0] != 255:
@@ -324,10 +341,10 @@
else:
index= pointdata[1]*65536 + pointdata[2]*256 + pointdata[3]
size= 4
-
+
return index, size
-
+
def read_tags(tag_bytes, object_tags):
'''Read the object's Tags chunk.'''
offset= 0
@@ -343,25 +360,25 @@
'''Read the object's layer data.'''
new_layr= _obj_layer()
new_layr.index, flags= struct.unpack(">HH", layr_bytes[0:4])
-
+
if flags > 0 and not load_hidden:
return False
-
+
print("Reading Object Layer")
offset= 4
new_layr.pivot= struct.unpack(">fff", layr_bytes[offset:offset+12])
offset+= 12
layr_name, name_len = read_lwostring(layr_bytes[offset:])
offset+= name_len
-
+
if layr_name:
new_layr.name= layr_name
else:
new_layr.name= "Layer %d" % (new_layr.index + 1)
-
+
if len(layr_bytes) == offset+2:
new_layr.parent_index,= struct.unpack(">h", layr_bytes[offset:offset+2])
-
+
object_layers.append(new_layr)
return True
@@ -371,26 +388,26 @@
# XXX: Need to check what these two exactly mean for a LWOB/LWLO file.
new_layr= _obj_layer()
new_layr.index, flags= struct.unpack(">HH", layr_bytes[0:4])
-
+
print("Reading Object Layer")
offset= 4
layr_name, name_len = read_lwostring(layr_bytes[offset:])
offset+= name_len
-
+
if name_len > 2 and layr_name != 'noname':
new_layr.name= layr_name
else:
new_layr.name= "Layer %d" % new_layr.index
-
+
object_layers.append(new_layr)
-
+
def read_pnts(pnt_bytes, object_layers):
'''Read the layer's points.'''
print("\tReading Layer ("+object_layers[-1].name+") Points")
offset= 0
chunk_len= len(pnt_bytes)
-
+
while offset < chunk_len:
pnts= struct.unpack(">fff", pnt_bytes[offset:offset+12])
offset+= 12
@@ -408,35 +425,41 @@
name, name_len= read_lwostring(weight_bytes[offset:])
offset+= name_len
weights= []
-
+
while offset < chunk_len:
pnt_id, pnt_id_len= read_vx(weight_bytes[offset:offset+4])
offset+= pnt_id_len
value,= struct.unpack(">f", weight_bytes[offset:offset+4])
offset+= 4
weights.append([pnt_id, value])
-
+
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-extensions-cvs
mailing list