Changeset 354
- Timestamp:
- 11/04/02 00:07:40 (6 years ago)
- Files:
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/RBRapier/RBRapier/Formats/Lightwave/Loader.py
r353 r354 32 32 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 33 33 34 class _LWOSubChunk(chunk.Chunk): 35 """Adapt python's chunk.Chunk class to be able to read LWO sub-chunks...""" 36 def __init__(self, file, align = 1, bigendian = 1, inclheader = 0): 37 import struct 38 self.closed = 0 39 self.align = align # whether to align to word (2-byte) boundaries 40 if bigendian: 41 strflag = '>' 42 else: 43 strflag = '<' 44 self.file = file 45 self.chunkname = file.read(4) 46 if len(self.chunkname) < 4: 47 raise EOFError 48 try: 49 self.chunksize = struct.unpack(strflag+'h', file.read(2))[0] 50 except struct.error: 51 raise EOFError 52 if inclheader: 53 self.chunksize = self.chunksize - 6 # subtract header 54 self.size_read = 0 55 try: 56 self.offset = self.file.tell() 57 except (AttributeError, IOError): 58 self.seekable = 0 59 else: 60 self.seekable = 1 61 62 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 63 64 def _ReadChunkString(chunk, readstep=2): 65 result = '' 66 while result[-1:] != '\0': 67 result += chunk.read(readstep) 68 result = result[:result.find('\0')] 69 return result 70 71 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 72 73 class _LWOSurface(object): 74 def __init__(self, Name): 75 self.Name = Name 76 self.Faces = [] 77 78 def ReadFormat(self, SurfaceDefChunk): 79 print self.Name 80 print "TODO: read materials" 81 SurfaceDefChunk.skip() 82 #try: 83 # while 1: 84 # SubChunk = _LWOSubChunk(SurfaceDefChunk) 85 # print SubChunk.getname(), SubChunk.getsize(), `SubChunk.read()` 86 #except EOFError: 87 # pass # end of chunk 88 89 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 90 91 class _LWOFace(object): 92 def ReadFormat(self, FacesChunk): 93 NumIndices = struct.unpack(">H", FacesChunk.read(2))[0] 94 self.IndexList = [struct.unpack(">H", FacesChunk.read(2))[0] for each in xrange(NumIndices)] 95 self.SurfaceIndex = struct.unpack(">h", FacesChunk.read(2))[0] 96 ByteLen = len(self.IndexList)*2 + 4 97 if self.SurfaceIndex < 0: 98 self.SurfaceIndex = -self.SurfaceIndex 99 # This polygon has "detail polygons", but the reference says to ignore them 100 # as they are mostly obsolete 101 NumDetailPolys = struct.unpack(">H", FacesChunk.read(2))[0] 102 ByteLen += 2 103 # we exit at this point so the detail polys are handled as normal polys... call me lazy! 104 self.SurfaceIndex -= 1 # Make index zero based 105 return ByteLen 106 107 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 34 108 35 109 class LightwaveLWOLoader(object): … … 48 122 self.Name = None 49 123 self.Vertices = [] 50 self.Normals = [] 51 self.TexCoords = [] 52 self.Groups = [] 124 self.Surfaces = {} 53 125 54 126 ChunkTypeTable = { … … 72 144 except KeyError: 73 145 if self.RaiseMissingElements: 74 raise ValueError, "Unknown LightwaveOBJ chunk type '%s'" % NextChunk.getname()146 raise NotImplemented, "Unknown LightwaveOBJ chunk type '%s'" % NextChunk.getname() 75 147 elif self.WarnMissingElements: 76 148 print "Unknown LightwaveOBJ chunk type '%s'" % NextChunk.getname() … … 86 158 87 159 def _ReadSurfaces(self, SurfacesChunk): 88 self.Surface s = filter(None, SurfacesChunk.read().split('\0'))89 print "Surface Types:", ' '.join(self.Surfaces)160 self.SurfaceNames = filter(None, SurfacesChunk.read().split('\0')) 161 self.Surfaces = dict([(name, _LWOSurface(name)) for name in self.SurfaceNames]) 90 162 91 163 def _ReadPoints(self, PointsChunk): 92 164 NumPoints = PointsChunk.getsize() / 12 93 165 self.Vertices = [struct.unpack(">3f", PointsChunk.read(12)) for idx in xrange(NumPoints)] 94 print "Vertices:", len(self.Vertices)95 166 96 167 def _ReadFaces(self, FacesChunk): 97 def ReadFace():98 NumIndices = struct.unpack(">H", FacesChunk.read(2))[0]99 IndexList = [struct.unpack(">H", FacesChunk.read(2))[0] for each in xrange(NumIndices)]100 SurfaceIndex = struct.unpack(">h", FacesChunk.read(2))[0]101 return SurfaceIndex, IndexList, len(IndexList)*2 + 4102 103 Faces = {}104 168 BytesLeft = FacesChunk.getsize() 105 169 while BytesLeft > 0: 106 SurfaceIndex, IndexList, BytesConsumed = ReadFace() 107 Faces.setdefault(SurfaceIndex, []).append(IndexList) 170 face = _LWOFace() 171 BytesConsumed = face.ReadFormat(FacesChunk) 172 FaceSurfaceName = self.SurfaceNames[face.SurfaceIndex-1] 173 self.Surfaces[FaceSurfaceName].Faces.append(face) 108 174 BytesLeft -= BytesConsumed 109 175 assert BytesLeft == 0 110 print "Faces: ", ' '.join(['Surf %d: %d;' % (k, len(v)) for k,v in Faces.iteritems()])111 176 112 177 def _ReadSurfaceDefinition(self, SurfaceDefChunk): 113 Name, EmptyStr, SurfaceDef = SurfaceDefChunk.read().split('\0', 2) 114 assert EmptyStr == '' 115 #SurfaceDefChunk.skip() 116 print 117 print Name 118 print `SurfaceDef` 119 print 178 SurfaceName = _ReadChunkString(SurfaceDefChunk) 179 self.Surfaces[SurfaceName].ReadFormat(SurfaceDefChunk) 120 180 121 181 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
