2016-11-10 20:06:06 -05:00
|
|
|
#!/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":
|
2020-02-15 01:33:25 -05:00
|
|
|
print(filename,"is not a valid b3d file")
|
2016-11-10 20:06:06 -05:00
|
|
|
f.close()
|
|
|
|
return
|
|
|
|
start_texs = 12
|
|
|
|
f.seek(start_texs)
|
|
|
|
s = f.read(4)
|
|
|
|
if s!="TEXS":
|
2020-02-15 01:33:25 -05:00
|
|
|
print("Can not handle '%s' b3d file - ignored."%filename)
|
2016-11-10 20:06:06 -05:00
|
|
|
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
|
2020-02-15 01:33:25 -05:00
|
|
|
print("WARNING")
|
2016-11-10 20:06:06 -05:00
|
|
|
if 1:
|
2020-02-15 01:33:25 -05:00
|
|
|
print("WARNING - kart.xml not done yet")
|
2016-11-10 20:06:06 -05:00
|
|
|
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":
|
2020-02-15 01:33:25 -05:00
|
|
|
print("Can't handle file '%s'."%i)
|
2016-11-10 20:06:06 -05:00
|
|
|
|
|
|
|
# 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):
|
2020-02-15 01:33:25 -05:00
|
|
|
print("File '%s' is missing."%(dir+i))
|
2016-11-10 20:06:06 -05:00
|
|
|
|
|
|
|
# 2) Check if there are any unnecessary b3d files
|
|
|
|
# ===============================================
|
|
|
|
for i in b3d_files_in_dir:
|
|
|
|
if not used_b3d_files.get(i):
|
2020-02-15 01:33:25 -05:00
|
|
|
print("File '%s' is not used."%i)
|
2016-11-10 20:06:06 -05:00
|
|
|
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):
|
2020-02-15 01:33:25 -05:00
|
|
|
print("Cannot find texture '%s'."%i)
|
2016-11-10 20:06:06 -05:00
|
|
|
continue
|
|
|
|
else:
|
|
|
|
del existing_textures[i]
|
|
|
|
|
|
|
|
|
|
|
|
for i in existing_textures:
|
2020-02-15 01:33:25 -05:00
|
|
|
print("Texture '%s' is not used anywhere."%(dir+i))
|
2016-11-10 20:06:06 -05:00
|
|
|
|
|
|
|
# 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)
|