1#!/usr/bin/env python3 2# -*- Coding: UTF-8 -*- 3 4# --------------------------------------------------------------------------- 5# Open Asset Import Library (ASSIMP) 6# --------------------------------------------------------------------------- 7# 8# Copyright (c) 2006-2020, ASSIMP Development Team 9# 10# All rights reserved. 11# 12# Redistribution and use of this software in source and binary forms, 13# with or without modification, are permitted provided that the following 14# conditions are met: 15# 16# * Redistributions of source code must retain the above 17# copyright notice, this list of conditions and the 18# following disclaimer. 19# 20# * Redistributions in binary form must reproduce the above 21# copyright notice, this list of conditions and the 22# following disclaimer in the documentation and/or other 23# materials provided with the distribution. 24# 25# * Neither the name of the ASSIMP team, nor the names of its 26# contributors may be used to endorse or promote products 27# derived from this software without specific prior 28# written permission of the ASSIMP Development Team. 29# 30# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 31# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 32# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 33# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 34# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 35# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 36# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 37# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 38# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 39# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 40# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 41# --------------------------------------------------------------------------- 42 43""" 44Generate the regression database db.zip from the files in the <root>/test/models 45directory. Older databases are overwritten with no prompt but can be restored 46using Git as needed. 47 48Use --help for usage. 49 50On Windows, use ``py run.py <arguments>`` to make sure command line parameters 51are forwarded to the script. 52""" 53 54import sys 55import os 56import subprocess 57import zipfile 58 59import settings 60import utils 61 62usage = """gen_db [assimp_binary] [-i=...] [-e=...] [-p] [-n] 63 64The assimp_cmd (or assimp) binary to use is specified by the first 65command line argument and defaults to ``assimp``. 66 67To build, set ``ASSIMP_BUILD_ASSIMP_TOOLS=ON`` in CMake. If generating 68configs for an IDE, make sure to build the assimp_cmd project. 69 70-i,--include: List of file extensions to update dumps for. If omitted, 71 all file extensions are updated except those in `exclude`. 72 Example: -ixyz,abc 73 -i.xyz,.abc 74 --include=xyz,abc 75 76-e,--exclude: Merged with settings.exclude_extensions to produce a 77 list of all file extensions to ignore. If dumps exist, 78 they are not altered. If not, theu are not created. 79 80-p,--preview: Preview list of file extensions touched by the update. 81 Dont' change anything. 82 83-n,--nozip: Don't pack to ZIP archive. Keep all dumps in individual files. 84""" 85 86# ------------------------------------------------------------------------------- 87def process_dir(d, outfile, file_filter): 88 """ Generate small dump records for all files in 'd' """ 89 print("Processing directory " + d) 90 91 num = 0 92 for f in os.listdir(d): 93 fullp = os.path.join(d, f) 94 if os.path.isdir(fullp) and not f == ".svn": 95 num += process_dir(fullp, outfile, file_filter) 96 continue 97 98 if file_filter(f): 99 for pp in settings.pp_configs_to_test: 100 num += 1 101 print("DUMP " + fullp + "\n post-processing: " + pp) 102 outf = os.path.join(os.getcwd(), settings.database_name, 103 utils.hashing(fullp, pp)) 104 105 cmd = [ assimp_bin_path, "dump", fullp, outf, "-b", "-s", "-l" ] + pp.split() 106 outfile.write("assimp dump "+"-"*80+"\n") 107 outfile.flush() 108 if subprocess.call(cmd, stdout=outfile, stderr=outfile, shell=False): 109 print("Failure processing " + fullp) 110 111 # spit out an empty file to indicate that this failure is expected 112 with open(outf,'wb') as f: 113 pass 114 return num 115 116 117# ------------------------------------------------------------------------------- 118def make_zip(): 119 """Zip the contents of ./<settings.database_name> 120 to <settings.database_name>.zip using DEFLATE 121 compression to minimize the file size. """ 122 123 num = 0 124 zipout = zipfile.ZipFile(settings.database_name + ".zip", "w", zipfile.ZIP_DEFLATED) 125 for f in os.listdir(settings.database_name): 126 p = os.path.join(settings.database_name, f) 127 zipout.write(p, f) 128 if settings.remove_old: 129 os.remove(p) 130 131 num += 1 132 133 if settings.remove_old: 134 os.rmdir(settings.database_name) 135 136 bad = zipout.testzip() 137 assert bad is None 138 139 print("="*60) 140 print("Database contains {0} entries".format(num)) 141 142 143# ------------------------------------------------------------------------------- 144def extract_zip(): 145 """Unzip <settings.database_name>.zip to 146 ./<settings.database_name>""" 147 try: 148 zipout = zipfile.ZipFile(settings.database_name + ".zip", "r", 0) 149 zipout.extractall(path=settings.database_name) 150 except (RuntimeError,IOError) as r: 151 print(r) 152 print("failed to extract previous ZIP contents. "\ 153 "DB is generated from scratch.") 154 155 156# ------------------------------------------------------------------------------- 157def gen_db(ext_list,outfile): 158 """Generate the crash dump database in 159 ./<settings.database_name>""" 160 try: 161 os.mkdir(settings.database_name) 162 except OSError: 163 pass 164 165 num = 0 166 for tp in settings.model_directories: 167 num += process_dir(tp, outfile, 168 lambda x: os.path.splitext(x)[1].lower() in ext_list and not x in settings.files_to_ignore) 169 170 print("="*60) 171 print("Updated {0} entries".format(num)) 172 173 174# ------------------------------------------------------------------------------- 175if __name__ == "__main__": 176 def clean(f): 177 f = f.strip("* \'") 178 return "."+f if f[:1] != '.' else f 179 180 if len(sys.argv) <= 1 or sys.argv[1] == "--help" or sys.argv[1] == "-h": 181 print(usage) 182 sys.exit(0) 183 184 assimp_bin_path = sys.argv[1] 185 ext_list, preview, nozip = None, False, False 186 for m in sys.argv[2:]: 187 if m[:10]=="--exclude=": 188 settings.exclude_extensions += map(clean, m[10:].split(",")) 189 elif m[:2]=="-e": 190 settings.exclude_extensions += map(clean, m[2:].split(",")) 191 elif m[:10]=="--include=": 192 ext_list = m[10:].split(",") 193 elif m[:2]=="-i": 194 ext_list = m[2:].split(",") 195 elif m=="-p" or m == "--preview": 196 preview = True 197 elif m=="-n" or m == "--nozip": 198 nozip = True 199 else: 200 print("Unrecognized parameter: " + m) 201 sys.exit(-1) 202 203 outfile = open(os.path.join("..", "results", "gen_regression_db_output.txt"), "w") 204 if ext_list is None: 205 (ext_list, err) = subprocess.Popen([assimp_bin_path, "listext"], 206 stdout=subprocess.PIPE).communicate() 207 ext_list = str(ext_list.strip()).lower().split(";") 208 209 # todo: Fix for multi dot extensions like .skeleton.xml 210 ext_list = list(filter(lambda f: not f in settings.exclude_extensions, 211 map(clean, ext_list))) 212 print('File extensions processed: ' + ', '.join(ext_list)) 213 if preview: 214 sys.exit(1) 215 216 extract_zip() 217 gen_db(ext_list,outfile) 218 make_zip() 219 220 print("="*60) 221 input("Press any key to continue") 222 sys.exit(0) 223 224# vim: ai ts=4 sts=4 et sw=4 225 226