(no commit message)
authorJerome Mahieux <jerome.le.chat@free.fr>
Wed, 25 Jan 2012 03:20:42 +0000 (03:20 +0000)
committerJerome Mahieux <jerome.le.chat@free.fr>
Wed, 25 Jan 2012 03:20:42 +0000 (03:20 +0000)
io_directx_bel/README
io_directx_bel/__init__.py
io_directx_bel/bel/uv.py
io_directx_bel/import_x.py

index 7301fb89e8b77d9d55728bda9df26c0df41087c5..c147ac95b048c43f9a2b186a0d54052f3a3992aa 100644 (file)
@@ -20,13 +20,17 @@ PLY won't be used unfortunately (it's way too slow as far as I tested)
 \r
 \r
 TO TEST THE SCRIPT :\r
-  . copy the 'bel' folder in /scripts/modules. can reside in /addons but Blender will complain a bit in the console. (harmless)\r
-  . copy the 'io_directx_bel' in /scripts/addons\r
+  . copy the 'io_directx_bel' in /scripts/addons or addons_contrib\r
   . start blender\r
   . enable then addon in  user prefs > addons\r
   . run the script with file > import > directX\r
 \r
-13/01/12 rc 0.16\r
+25/01/12 0.17\r
+  . faster, 60% faster in some case : various loops improvements, infile templates parsing disabled by default\r
+    saw another bottleneck about data chunks as string but will wait for binary support for better point of view.\r
+  . interface cosmetics\r
+    \r
+23/01/12 rc 0.16\r
 . committed to svn (and littleneo git as usual)\r
 . corrected a bug about referenced token parenting\r
 . corrected a bug about non parented meshes\r
index d6bfb53d5ff8b04a4e6867a001680509886b8eb6..df1cd05ab2d64777da56ce3bf7013e4828414948 100644 (file)
@@ -3,7 +3,7 @@ bl_info = {
     "name": "DirectX Importer",
     "description": "Import directX Model Format (.x)",
     "author": "Littleneo (Jerome Mahieux)",
-    "version": (0, 16),
+    "version": (0, 17),
     "blender": (2, 6, 1),
     "location": "File > Import > DirectX (.x)",
     "warning": "",
@@ -40,8 +40,14 @@ class DisplayTree(bpy.types.Operator) :
 
     def execute(self,context) :
 '''
-    
-    
+
+def hide_templates(self,context) :
+    if self.use_templates == False : self.show_templates = False
+
+def not_parented(self,context) :
+    self.parented = False
+    self.use_templates = False
+
 class ImportX(bpy.types.Operator, ImportHelper):
     '''Load a Direct x File'''
     bl_idname = "import_scene.x"
@@ -60,7 +66,7 @@ class ImportX(bpy.types.Operator, ImportHelper):
             )
     show_templates = BoolProperty(
             name="Show x templates",
-            description="display templates defined in the .x file",
+            description="display any token structure definition found in the .x file",
             default=False,
             )
     show_geninfo = BoolProperty(
@@ -73,6 +79,7 @@ class ImportX(bpy.types.Operator, ImportHelper):
             name="Quick mode",
             description="only retrieve mesh basics",
             default=False,
+            update=not_parented
             )
     
     parented = BoolProperty(
@@ -80,6 +87,13 @@ class ImportX(bpy.types.Operator, ImportHelper):
             description="import armatures, empties, rebuild parent-childs relations",
             default=True,
             )
+
+    use_templates = BoolProperty(
+            name="Use infile x templates",
+            description="parse any token structure definition found in the .x file, use it prior to standard ones",
+            default=False,
+            update=hide_templates
+            )
     
     bone_maxlength = FloatProperty(
             name="Bone length",
@@ -92,6 +106,8 @@ class ImportX(bpy.types.Operator, ImportHelper):
     chunksize = EnumProperty(
             name="Chunksize",
             items=(('0', "all", ""),
+                   ('16384', "16KB", ""),
+                   ('8192', "8KB", ""),
                    ('4096', "4KB", ""),
                    ('2048', "2KB", ""),
                    ('1024', "1KB", ""),
@@ -225,16 +241,15 @@ class ImportX(bpy.types.Operator, ImportHelper):
         col = box.column(align=True)
         col.label('Import Options :')  
         col.prop(self, "chunksize")
-        col.prop(self, "use_smooth_groups")
-        actif = not(self.quickmode)
+        col.prop(self, "use_smooth_groups")      
+        col.prop(self, "quickmode")
         row = col.row()
-        row.enabled = actif
+        row.enabled = not(self.quickmode)
         row.prop(self, "parented")
-        if self.parented :
-            row = col.row()
-            row.enabled = actif
-            row.prop(self, "bone_maxlength")      
-        col.prop(self, "quickmode")
+        #if self.parented :
+        row = col.row()
+        row.enabled = self.parented
+        row.prop(self, "bone_maxlength")
         
         # source orientation box
         box = layout.box()
@@ -254,8 +269,11 @@ class ImportX(bpy.types.Operator, ImportHelper):
         col = box.column(align=True)
         col.label('Info / Debug :')
         col.prop(self, "show_tree")
-        col.prop(self, "show_templates")
         col.prop(self, "show_geninfo")
+        col.prop(self, "use_templates")
+        row = col.row()
+        row.enabled = self.use_templates
+        row.prop(self, "show_templates")  
         
         #row = layout.row(align=True)
         #row.prop(self, "use_ngons")
index 6ef38f411ecba4a60ae94b460fcb969896dd4758..807ba95f003fd72dffb60cbb12cf0d1aaf409a31 100644 (file)
@@ -4,6 +4,7 @@ from .. import bel
 def write(me, uvs, matimage = False) :
     uvs, nest = bel.nested(uvs)
     newuvs = []
+    append = newuvs.append
     for uvi, uvlist in enumerate(uvs) :
 
         uv = me.uv_textures.new()
@@ -24,7 +25,7 @@ def write(me, uvs, matimage = False) :
             uv.data[uvfi].uv3 = Vector((uvface[4],uvface[5]))
             if len(uvface) == 8 :
                 uv.data[uvfi].uv4 = Vector((uvface[6],uvface[7]))
-        newuvs.append(uv)
+        append(uv)
     if nest : return newuvs
     else : return newuvs[0]
 
@@ -35,11 +36,12 @@ def write(me, uvs, matimage = False) :
 # normal default when face has been built
 def row(vertices,faces,normals=True) :
     uvs = []
+    append = uvs.append
     for face in faces :
         v0 = vertices[face[0]]
         v1 = vertices[face[1]]
         v2 = vertices[face[-1]]
-        print(v0,v1)
+        #print(v0,v1)
         lx = (v1 - v0).length
         ly = (v2 - v0).length
         # init uv
@@ -52,13 +54,14 @@ def row(vertices,faces,normals=True) :
         else :
             x = uvs[-1][0]
             y = uvs[-1][1]
-        if normals : uvs.append([x,y,x+lx,y,x+lx,y+ly,x,y+ly])
-        else : uvs.append([x+lx,y,x,y,x,y+ly,x+lx,y+ly])
+        if normals : append([x,y,x+lx,y,x+lx,y+ly,x,y+ly])
+        else : append([x+lx,y,x,y,x,y+ly,x+lx,y+ly])
     return uvs
 
 ## convert UV given as verts location to blender format
 # eg : [ [v0x,v0y] , [vnx , vny] ... ] -> [ [ v1x,v1y,v0x,v0y,v4x,v4y] ... ]
-# found in directx
+# this format is found in directx files
+'''
 def asVertsLocation(verts2d, faces) :
     uv = []
     for f in faces :
@@ -67,3 +70,12 @@ def asVertsLocation(verts2d, faces) :
             uvface.extend(verts2d[vi])
         uv.append(uvface)
     return uv
+'''
+def asVertsLocation(verts2d, idFaces) :
+    coFaces = []
+    uvBlender = []
+    conv0 = coFaces.extend
+    conv1 = uvBlender.extend
+    for f in idFaces : conv0([verts2d[vi] for vi in f])
+    for f in coFaces : conv1(f)
+    return uvBlender
\ No newline at end of file
index 7e92ddace3ea40f351319837e51f0f5adad6fcc3..24649dce4319cc7ba0c5d3506d4437467d1b3e93 100644 (file)
@@ -62,8 +62,9 @@ def load(operator, context, filepath,
          show_geninfo=False,
          quickmode=False,
          parented=False,
+         use_templates=False,
          bone_maxlength=1.0,
-         chunksize=False,
+         chunksize=2048,
          naming_method=0,
          use_ngons=True,
          use_edges=True,
@@ -214,7 +215,6 @@ BINARY FORMAT
         trunkated = False
         previouslvl = False
         while True :
-        #for l in data.readlines() :
             lines, trunkated = nextFileChunk(data,trunkated)
             if lines == None : break
             for l in lines :
@@ -248,7 +248,7 @@ BINARY FORMAT
                 
                 if quickmode == False :
                     ## look for templates
-                    if re.match(r_template,l) :
+                    if use_templates and re.match(r_template,l) :
                         tname = l.split(' ')[1]
                         templates[tname] = {'pointer' : ptr, 'line' : c}
                         continue
@@ -307,6 +307,7 @@ BINARY FORMAT
         if format == 'txt' :
             lines = chunk.decode('utf-8', errors='ignore')
             #if stream : return lines.replace('\r','').replace('\n','')
+            #lines = [ l + '\n' for l in lines.replace('\r','\n').split('\n') ]
             lines = lines.replace('\r','\n').split('\n')
             if trunkated : lines[0] = trunkated + lines[0]
             if len(lines) == 1 : 
@@ -402,10 +403,12 @@ BINARY FORMAT
     def dXtemplateData(tpl,block,ptr=0) :
         #print('dxTPL',block[ptr])
         pack = []
+        append = pack.append
+        namespace = locals()
         for member in tpl['members'] :
             #print(member)
-            dataname = member[-1]
             datatype = member[0].lower()
+            dataname = member[-1]
             if datatype ==  'array' :
                 datatype = member[1].lower()
                 s = dataname.index('[') + 1
@@ -423,8 +426,9 @@ BINARY FORMAT
             #if len(str(datavalue)) > 50 : dispvalue = str(datavalue[0:25]) + ' [...] ' + str(datavalue[-25:])
             #else : dispvalue = str(datavalue)
             #print('%s :  %s %s'%(dataname,dispvalue,type(datavalue)))
-            exec('%s = datavalue'%(dataname))
-            pack.append( datavalue )
+            #exec('%s = datavalue'%(dataname))
+            namespace[dataname] = datavalue
+            append( datavalue )
         return pack, ptr + 1
     
     def dXdata(block,datatype,length,s=0,eof=';') :
@@ -459,13 +463,14 @@ BINARY FORMAT
     def dXarray(block, datatype, length, s=0) :
         #print('dxARR',block[s])
         lst = []
+        append = lst.append
         if datatype in reserved_type :
             eoi=','
             for i in range(length) :
                 if i+1 == length : eoi = ';'
                 datavalue, s = dXdata(block,datatype,1,s,eoi)
-                lst.append( datavalue )
-            
+                append( datavalue )
+        
         else :
             eoi = ';,'
             for i in range(length) :
@@ -474,7 +479,7 @@ BINARY FORMAT
                 e = block.index(eoi,s)
                 #except : print(block,s) ; popo()
                 datavalue, na = dXdata(block[s:e+1],datatype,1)
-                lst.append( datavalue )
+                append( datavalue )
                 s = e + 2
         return lst, s
     
@@ -487,20 +492,19 @@ BINARY FORMAT
         line = templates[tpl_name]['line']
         #print('> %s at line %s (chr %s)'%(tpl_name,line,ptr))
         data.seek(ptr)
-        block = ''
+        lines = []
+        append = lines.append
         trunkated = False
         go = True
         while go :
-            lines, trunkated = nextFileChunk(data,trunkated,chunksize) # stream ?
-            if lines == None : 
-                break
-            for l in lines :
-                #l = data.readline().decode().strip()
-                block += l.strip()
+            rawlines, trunkated = nextFileChunk(data,trunkated,chunksize) # stream ?
+            if rawlines == None : break
+            for l in rawlines :
+                append(l.strip())
                 if '}' in l :
                     go = False
                     break
-        
+        block = ''.join(lines)
         uuid = re.search(r'<.+>',block).group()
         templates[tpl_name]['uuid'] = uuid.lower()
         templates[tpl_name]['members'] = []
@@ -540,36 +544,42 @@ BINARY FORMAT
                     #            print('  %s'%str(member)[1:-1].replace(',',' ').replace("'",''))
                 else :
                     print('MATCHES BUILTIN TEMPLATE')
-    
-            
+
     ##  read any kind of token data block
     # by default the block is cleaned from inline comment space etc to allow data parsing
     # useclean = False (retrieve all bytes) if you need to compute a file byte pointer
-    # to mimic the file.tell() function and use it with file.seek()
+    # to mimic the file.tell() function and use it with file.seek() later
     def readBlock(data,token, clean=True) :
-        ptr = token['pointer']
-        data.seek(ptr)
-        block = ''
-        #lvl = 0
-        trunkated = False
+        data.seek(token['pointer'])
+        lines = []
+        append = lines.append
+        strip = str.strip
         go = True
+        init = True
+        
+        def cleanLine(l):
+            if '//' in l : l = l[0:l.index('//')]
+            if '#' in l : l = l[0:l.index('#')]
+            return l.strip().replace(' ','').replace('\t','')
+            
         while go :
-            lines, trunkated = nextFileChunk(data,trunkated,chunksize)
-            if lines == None : break
-            for l in lines :
-                #eol = len(l) + 1
-                l = l.strip()
-                #c += 1
-                block += l+'\n'
-                if re.match(r_endsection,l) :
+            chunk = data.read(512).decode('utf-8', errors='ignore')
+            chunk = chunk.replace('\r','\n').split('\n')
+            for l in map(cleanLine, chunk) :
+                if l == '' : continue
+                if init :
+                    l = l[l.index('{')+1:]
+                    init = False
+                if '}' in l :
+                    append(l[0:l.index('}')])
                     go = False
                     break
-        s = block.index('{') + 1
-        e = block.index('}')
-        block = block[s:e]
-        if clean : block = cleanBlock(block)
+                append(l)
+        
+        block = ''.join(lines)
         return block
-    
+
+
     def getChilds(tokenname) :
         childs = []
         # '*' in childname means it's a reference. always perform this test
@@ -932,8 +942,7 @@ BINARY FORMAT
                 walk_dXtree(tokens.keys())
             
             ## DATA IMPORTATION
-            if show_geninfo : 
-                print(tokens)
+            if show_geninfo :
                 print('Root frames :\n %s'%rootTokens)
             if parented :
                 import_dXtree(rootTokens)
@@ -964,4 +973,4 @@ BINARY FORMAT
 
 
         return {'FINISHED'}
-        
+        
\ No newline at end of file