1#!/usr/local/bin/python3.8 2 3# 4# This source file is part of appleseed. 5# Visit https://appleseedhq.net/ for additional information and resources. 6# 7# This software is released under the MIT license. 8# 9# Copyright (c) 2010-2013 Francois Beaune, Jupiter Jazz Limited 10# Copyright (c) 2014-2018 Francois Beaune, The appleseedhq Organization 11# 12# Permission is hereby granted, free of charge, to any person obtaining a copy 13# of this software and associated documentation files (the "Software"), to deal 14# in the Software without restriction, including without limitation the rights 15# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 16# copies of the Software, and to permit persons to whom the Software is 17# furnished to do so, subject to the following conditions: 18# 19# The above copyright notice and this permission notice shall be included in 20# all copies or substantial portions of the Software. 21# 22# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 26# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 27# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 28# THE SOFTWARE. 29# 30 31import argparse 32import datetime 33import fnmatch 34import os 35import subprocess 36 37 38# ------------------------------------------------------------------------------------------------- 39# Constants. 40# ------------------------------------------------------------------------------------------------- 41 42DEFAULT_TOOL_FILENAME = "convertmeshfile.exe" if os.name == "nt" else "convertmeshfile" 43 44 45# ------------------------------------------------------------------------------------------------- 46# Utility functions. 47# ------------------------------------------------------------------------------------------------- 48 49def walk(directory, recursive): 50 if recursive: 51 for dirpath, dirnames, filenames in os.walk(directory): 52 for filename in filenames: 53 yield os.path.join(dirpath, filename) 54 else: 55 dirpath, dirnames, filenames = os.walk(directory).next() 56 for filename in filenames: 57 yield os.path.join(dirpath, filename) 58 59 60# ------------------------------------------------------------------------------------------------- 61# Convert a given mesh file. 62# ------------------------------------------------------------------------------------------------- 63 64def convert_mesh_file(input_filepath, output_filepath, tool_path): 65 print("converting {0} to {1}...".format(input_filepath, output_filepath)) 66 subprocess.call([tool_path, input_filepath, output_filepath]) 67 68 69# ------------------------------------------------------------------------------------------------- 70# Convert all matching mesh files in a given directory (possibly recursively). 71# Returns the number of converted mesh files. 72# ------------------------------------------------------------------------------------------------- 73 74def convert_mesh_files(tool_path, directory, recursive, input_pattern, output_format, overwrite): 75 converted_file_count = 0 76 77 for filepath in walk(directory, recursive): 78 filename = os.path.basename(filepath) 79 if fnmatch.fnmatch(filename, input_pattern): 80 output_filepath = os.path.splitext(filepath)[0] + "." + output_format 81 if overwrite or not os.path.exists(output_filepath): 82 convert_mesh_file(filepath, output_filepath, tool_path) 83 converted_file_count += 1 84 85 return converted_file_count 86 87 88# ------------------------------------------------------------------------------------------------- 89# Entry point. 90# ------------------------------------------------------------------------------------------------- 91 92def main(): 93 parser = argparse.ArgumentParser(description="convert multiple mesh files from one format " 94 "to another.") 95 parser.add_argument("-t", "--tool-path", metavar="tool-path", 96 help="set the path to the convertmeshfile tool") 97 parser.add_argument("-r", "--recursive", action='store_true', dest='recursive', 98 help="scan the specified directory and all its subdirectories") 99 parser.add_argument("-n", "--no-overwrite", action='store_false', dest='overwrite', 100 help="do not overwrite destination files if they already exist.") 101 parser.add_argument("directory", help="directory to scan") 102 parser.add_argument("input_pattern", metavar="input-pattern", help="input files pattern (e.g. *.obj)") 103 parser.add_argument("output_format", metavar="output-format", help="output file format (e.g. abc, binarymesh)") 104 args = parser.parse_args() 105 106 # If no tool path is provided, search for the tool in the same directory as this script. 107 if args.tool_path is None: 108 script_directory = os.path.dirname(os.path.realpath(__file__)) 109 args.tool_path = os.path.join(script_directory, DEFAULT_TOOL_FILENAME) 110 print("setting tool path to {0}.".format(args.tool_path)) 111 112 start_time = datetime.datetime.now() 113 converted_file_count = convert_mesh_files(args.tool_path, args.directory, args.recursive, 114 args.input_pattern, args.output_format, 115 args.overwrite) 116 end_time = datetime.datetime.now() 117 118 print("converted {0} mesh file(s) in {1}.".format(converted_file_count, end_time - start_time)) 119 120 121if __name__ == "__main__": 122 main() 123