123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- #!/usr/bin/env python
- import os
- import re
- import struct
- # Reads all texture names from the specified directory.
- # Textures must end in jpg, png, or bmp.
- # Returns a directory with the texture name as key.
- def readAllTextures(dir, result):
- if type(dir)==type([]):
- for i in dir:
- readAllTextures(i,result)
- return
-
- re_is_texture = re.compile("^.*\.(jpg|png|bmp)$")
- for i in os.listdir(dir):
- if re_is_texture.match(i):
- result[i]=1
- # -----------------------------------------------------------------------------
- # Reads all texture names specified in a materials.xml file.
- def readMaterialsXML(filename):
- textures = {}
- f = open(filename, "r")
-
- # Crude RE instead of XML parsing
- re_texture_name = re.compile("^ *<material name=\"([^\"]*)\"")
- for i in f.readlines():
- g = re_texture_name.match(i)
- if g:
- textures[g.groups(1)[0]] = 1
- return textures
- # -----------------------------------------------------------------------------
- def getTexturesFromB3D(filename, textures):
- f = open(filename, "r")
- s = f.read(4)
- if s!="BB3D":
- print(filename,"is not a valid b3d file")
- f.close()
- return
- start_texs = 12
- f.seek(start_texs)
- s = f.read(4)
- if s!="TEXS":
- print("Can not handle '%s' b3d file - ignored."%filename)
- f.close()
- return
- n = struct.unpack("<i", f.read(4))[0] # Read end of section
- n = n - start_texs - 4 # number of bytes to read in tex section
- s = f.read(n)
- i = 0
- while i<n:
- tex_name=""
- while ord(s[i]):
- tex_name = tex_name+s[i]
- i=i+1
- textures[tex_name] = 1
- # Update the offst: add 1 byte string terminator,
- # and 7 int/float values
- i = i + 7*4 + 1
- f.close()
- return
- # -----------------------------------------------------------------------------
- # Reads all textures mentioned in a track.xml or kart.xml file (e.g. icons,
- # screenshots, shadows)
- def findTrackData(dir, textures, b3dfiles):
- f = open(dir+"track.xml", "r")
- if f:
- r_screenshot = re.compile("^ *screenshot *= \"(.*)\" *$")
-
- for i in f.readlines():
- g = r_screenshot.match(i)
- if g:
- textures[g.group(1)] = 1
- f.close()
- f = open(dir+"scene.xml", "r")
- if f:
- r_model = re.compile(" model=\"((.*)\.b3d.?)\"")
- for i in f.readlines():
- g = r_model.search(i)
- if g:
- b3dfiles[g.groups(1)[0]] = 1
- f.close()
-
- # -----------------------------------------------------------------------------
- def findKartData(dir, textures, b3dfiles):
- f = open(dir+"scene.xml", "r")
- if f:
- r_model = re.compile(" model=\"((.*)\.b3d.?)\"")
- for i in f.readlines():
- g = r_model.search(i)
- if g:
- b3dfiles[g.groups(1)[0]] = 1
- f.close()
- return
- else:
- f = open(dir+"scene.xml", "r")
- if not f: return
- print("WARNING")
- if 1:
- print("WARNING - kart.xml not done yet")
- f = open(dir+"kart.xml", "r")
- if not f: return
- r_screenshot = re.compile("^ *screenshot *= \"(.*)\" *$")
- for i in f.readlines():
- g = r_screenshot.match(i)
- if g:
- textures[g.group(1)] = 1
- f.close()
- return
-
-
- # -----------------------------------------------------------------------------
- # Checks if all textures for a specified track- or kart-directory
- # are actually used.
- def checkDir(dir, shared_textures):
- # First read all *png/jpg/bmp files
- # ---------------------------------
- existing_textures = {}
- readAllTextures(dir, existing_textures)
- # Find all b3d files in the directory (print warnings for b3dz)
- # -------------------------------------------------------------
- b3d_files_in_dir = {}
- for i in os.listdir(dir):
- if i[-4:]==".b3d":
- b3d_files_in_dir[i] = 1
- elif i[-5:]==".b3dz":
- print("Can't handle file '%s'."%i)
-
- # Find all textures listed in materials.xml
- # -----------------------------------------
- materials = readMaterialsXML(dir+"/materials.xml")
- # Find all textures in track.xml and kart.xml files
- # -------------------------------------------------
- used_textures = {}
- used_b3d_files = {}
- findTrackData(dir, used_textures, used_b3d_files)
- #findKartData(dir, used_textures, used_b3d_files)
- # 1) Check if there are any missing b3d files
- # ===========================================
- for i in used_b3d_files.keys():
- if not b3d_files_in_dir.get(i):
- print("File '%s' is missing."%(dir+i))
-
- # 2) Check if there are any unnecessary b3d files
- # ===============================================
- for i in b3d_files_in_dir:
- if not used_b3d_files.get(i):
- print("File '%s' is not used."%i)
- continue
- del used_b3d_files[i]
- # Load all textures used in this b3d file
- getTexturesFromB3D(dir+i, used_textures)
-
- # 3) Check if all textures used can be found
- # ==========================================
- for i in used_textures:
- if not existing_textures.get(i)==1:
- if not shared_textures.get(i):
- print("Cannot find texture '%s'."%i)
- continue
- else:
- del existing_textures[i]
-
- for i in existing_textures:
- print("Texture '%s' is not used anywhere."%(dir+i))
-
- # Now check that all entries in materials.xml are indeed used and exist
- # =============================================================================
- if __name__=="__main__":
- assets = "../stk-assets/"
- shared_textures = {}
- readAllTextures([assets+"textures",
- assets+"/textures/deprecated"],
- shared_textures)
-
- for i in os.listdir(assets+"tracks"):
- checkDir(assets+"tracks/"+i+"/", shared_textures)
- break
- #for i in os.listdir(assets+"karts"):
- # checkDir(assets+"karts/"+i+"/", shared_textures)
|