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/wings_import.py')
-rw-r--r--release/scripts/wings_import.py191
1 files changed, 160 insertions, 31 deletions
diff --git a/release/scripts/wings_import.py b/release/scripts/wings_import.py
index 70f124b3bac..8bba6f52de7 100644
--- a/release/scripts/wings_import.py
+++ b/release/scripts/wings_import.py
@@ -11,7 +11,7 @@ __author__ = "Anthony D'Agostino (Scorpius)"
__url__ = ("blender", "elysiun",
"Author's homepage, http://www.redrival.com/scorpius",
"Wings 3D, http://www.wings3d.com")
-__version__ = "Part of IOSuite 0.5"
+__version__ = "Update on version from IOSuite 0.5"
__bpydoc__ = """\
This script imports Wings3D files to Blender.
@@ -37,7 +37,8 @@ fanning algorithm. Convex polygons (i.e., shaped like the letter "U")
require a different algorithm, and will be triagulated incorrectly.
Notes:<br>
- Last tested with Wings 3D 0.98.25 & Blender 2.35a.
+ Last tested with Wings 3D 0.98.25 & Blender 2.35a.<br>
+ This version has improvements made by Adam Saltsman (AdamAtomic) and Toastie.
"""
# $Id$
@@ -47,15 +48,29 @@ Notes:<br>
# | http://www.redrival.com/scorpius |
# | scorpius@netzero.com |
# | Feb 19, 2002 |
-# | Released under the Blender Artistic Licence (BAL) |
-# | Import Export Suite v0.5 |
-# +---------------------------------------------------------+
-# | Read and write Wings3D File Format (*.wings) |
-# +---------------------------------------------------------+
+
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# ***** END GPL LICENCE BLOCK *****
+
import Blender, meshtools
import struct, time, sys, os, zlib, cStringIO
-
+
# ==============================================
# === Read The 'Header' Common To All Chunks ===
# ==============================================
@@ -79,26 +94,28 @@ def read_mode(data):
# === Read Hard Edges ===
# =======================
def read_hardedges(data):
+ hardedge_table = {} # hard edges table
tag = data.read(1)
if tag == '\x6A':
- return # There are no hard edges
+ return hardedge_table # There are no hard edges
elif tag == '\x6B':
numhardedges, = struct.unpack(">H", data.read(2))
- print "numhardedges:", numhardedges
+ #print "numhardedges:", numhardedges
for i in range(numhardedges):
- data.read(1)
+ hardedge_table[i] = struct.unpack(">B", data.read(1))[0]
elif tag == '\x6C':
numhardedges, = struct.unpack(">L", data.read(4))
- print "numhardedges:", numhardedges
+ #print "numhardedges:", numhardedges
for i in range(numhardedges):
misc = data.read(1)
if misc == '\x61': # next value is stored as a byte
- data.read(1)
+ hardedge_table[i] = struct.unpack(">B", data.read(1))[0]
elif misc == '\x62': # next value is stored as a long
- data.read(4)
+ hardedge_table[i] = struct.unpack(">L", data.read(4))[0]
data.read(1) # 6A
else:
print tag
+ return hardedge_table
# ==================
# === Read Edges ===
@@ -134,6 +151,7 @@ def read_edges(data):
# === Read Faces ===
# ==================
def read_faces(data):
+ mat_table = {} #list of faces and material names
misc, numfaces = struct.unpack(">BL", data.read(5))
for i in range(numfaces):
if not i%100 and meshtools.show_progress: Blender.Window.DrawProgressBar(float(i)/numfaces, "Reading Faces")
@@ -141,10 +159,10 @@ def read_faces(data):
data.read(4)
read_chunkheader(data)
misc, namelen = struct.unpack(">BH", data.read(3))
- materialname = data.read(namelen)
- data.read(1)
+ mat_table[i] = data.read(namelen)
+ data.read(1) # 6A?
data.read(1) # 6A
- return numfaces
+ return mat_table
# ==================
# === Read Verts ===
@@ -169,8 +187,10 @@ def make_face_table(edge_table): # For Wings
for i in range(len(edge_table)):
Lf = edge_table[i][2]
Rf = edge_table[i][3]
- face_table[Lf] = i
- face_table[Rf] = i
+ if Lf >= 0:
+ face_table[Lf] = i
+ if Rf >= 0:
+ face_table[Rf] = i
return face_table
# =======================
@@ -198,14 +218,17 @@ def make_faces(edge_table): # For Wings
if i == edge_table[current_edge][3]:
next_edge = edge_table[current_edge][7] # Right successor edge
next_vert = edge_table[current_edge][0]
- else:
+ elif i == edge_table[current_edge][2]:
next_edge = edge_table[current_edge][5] # Left successor edge
next_vert = edge_table[current_edge][1]
+ else:
+ break
face_verts.append(next_vert)
current_edge = next_edge
if current_edge == face_table[i]: break
- face_verts.reverse()
- faces.append(face_verts)
+ if len(face_verts) > 0:
+ face_verts.reverse()
+ faces.append(face_verts)
return faces
# =======================
@@ -223,7 +246,7 @@ def dump_wings(filename):
file.close()
data = zlib.decompress(data)
if dsize != len(data): print "ERROR: uncompressed size does not match."
- data = cStringIO.StringIO(data)
+ data = cStringIO.StringIO(data)
print "header:", header
print read_chunkheader(data) # === wings chunk ===
data.read(4) # misc bytes
@@ -236,9 +259,10 @@ def dump_wings(filename):
objname = data.read(namelen)
print read_chunkheader(data) # === winged chunk ===
edge_table = read_edges(data)
- numfaces = read_faces(data)
+ mat_table = read_faces(data)
+ numfaces = len(mat_table)
verts = read_verts(data)
- read_hardedges(data)
+ hardedge_table = read_hardedges(data)
face_table = {} # contains an incident edge
vert_table = {} # contains an incident edge
@@ -255,25 +279,26 @@ def dump_wings(filename):
print
print "Ä"*79
print "edge_table:"
- pprint.pprint(edge_table)
+ #pprint.pprint(edge_table)
#for i in range(len(edge_table)): print "%2d" % (i), edge_table[i]
print
print "face_table:"
- pprint.pprint(face_table)
+ #pprint.pprint(face_table)
#for i in range(len(face_table)): print "%2d %2d" % (i, face_table[i])
print
print "vert_table:"
- pprint.pprint(vert_table)
+ #pprint.pprint(vert_table)
#for i in range(len(vert_table)): print "%2d %2d" % (i, vert_table[i])
file.close()
end = time.clock()
print '\a\r',
- sys.stderr.write("\nDone in %.2f %s" % (end-start, "seconds"))
+ sys.stderr.write("\nDone in %.2f %s\a\r" % (end-start, "seconds"))
# =========================
# === Read Wings Format ===
# =========================
def read(filename):
+
start = time.clock()
file = open(filename, "rb")
header = file.read(15)
@@ -299,9 +324,113 @@ def read(filename):
objname = data.read(namelen)
read_chunkheader(data) # winged chunk
edge_table = read_edges(data)
- numfaces = read_faces(data)
+ mat_table = read_faces(data)
+ numfaces = len(mat_table)
verts = read_verts(data)
- read_hardedges(data)
+ hardedge_table = read_hardedges(data)
+
+ # Manually split hard edges
+ # TODO: Handle the case where there are 2+ edges on a face
+ duped = {}
+ processed = []
+ cleanup = []
+ oldedgecount = len(edge_table)
+ for i in range(len(verts)):
+ duped[i] = -1
+ for j in range(len(hardedge_table)):
+ hardedge = hardedge_table[j]
+ oldedge = edge_table[hardedge]
+ newedge = [] # Copy old edge into a new list
+ for k in range(len(oldedge)):
+ newedge.append(oldedge[k])
+
+ # Duplicate start vert if not duped already
+ sv = newedge[0]
+ if duped[sv] == -1:
+ verts.append(verts[sv])
+ duped[sv] = len(verts)-1
+ newedge[0] = duped[sv]
+
+ # Duplicate end vert if not duped already
+ ev = newedge[1]
+ if duped[ev] == -1:
+ verts.append(verts[ev])
+ duped[ev] = len(verts)-1
+ newedge[1] = duped[ev]
+
+ # Decide which way to cut the edge
+ flip = 0
+ for v in range(len(processed)):
+ if processed[v][0] == oldedge[0]:
+ flip = 1
+ elif processed[v][1] == oldedge[1]:
+ flip = 1
+ if flip == 0:
+ of = 3
+ oe1 = 6
+ oe2 = 7
+ nf = 2
+ ne1 = 4
+ ne2 = 5
+ else:
+ of = 2
+ oe1 = 4
+ oe2 = 5
+ nf = 3
+ ne1 = 6
+ ne2 = 7
+
+ # Fix up side-specific edge fields
+ oldedge[of] = -1
+ oldedge[oe1] = -1
+ oldedge[oe2] = -1
+ newedge[nf] = -1
+ newedge[ne1] = -1
+ newedge[ne2] = -1
+
+ # Store new edge's neighbors for cleanup later
+ cleanup.append(edge_table[newedge[oe1]])
+ cleanup.append(edge_table[newedge[oe2]])
+
+ #DEBUG
+ # Sv Ev | Lf Rf | Lp Ls | Rp Rs
+ #print "Old Edge:",hardedge,oldedge
+ #print "New Edge:",len(edge_table),newedge
+
+ # Add this new edge to the edge table
+ edge_table[len(edge_table)] = newedge
+ if flip == 0:
+ processed.append(oldedge) # mark it off as processed
+
+ # Cycle through cleanup list and fix it up
+ for c in range(len(cleanup)):
+ cleanupedge = cleanup[c]
+
+ # Fix up their verts in case they were duped
+ sv = cleanupedge[0]
+ if sv < len(duped):
+ if duped[sv] >= 0:
+ cleanupedge[0] = duped[sv]
+ ev = cleanupedge[1]
+ if ev < len(duped):
+ if duped[ev] >= 0:
+ cleanupedge[1] = duped[ev]
+
+ # Fix up edge info (in case a hard edge was replaced with a new one)
+ edgecount = c/2
+ hardedge = hardedge_table[edgecount] # look up what edge we were replacing
+ newedgenum = oldedgecount+edgecount # calculate new edge's index
+ if cleanupedge[4] == hardedge:
+ cleanupedge[4] = newedgenum
+ if cleanupedge[5] == hardedge:
+ cleanupedge[5] = newedgenum
+ if cleanupedge[6] == hardedge:
+ cleanupedge[6] = newedgenum
+ if cleanupedge[7] == hardedge:
+ cleanupedge[7] = newedgenum
+
+ #for i in range(len(edge_table)): print "%2d" % (i), edge_table[i]
+
read_mode(data)
faces = make_faces(edge_table)
message += "%s %8s %8s %8s\n" % (objname.ljust(15), len(faces), len(edge_table), len(verts))