I also significantly rewrote the process-potrace-model-forms.py script, as well as the blender-model.py script. Most of the other scripts are old; I removed some personal info from them, so they don't work properly now.master
| @@ -1,3 +1,3 @@ | |||
| config.json | |||
| /*.py | |||
| misc-data/ | |||
| misc-data/ | |||
| *.csv | |||
| @@ -3,6 +3,8 @@ from mathutils import Vector, Euler | |||
| from math import pi | |||
| import json | |||
| PREFIX = "PREFIX" | |||
| buildings = bpy.data.objects["map"].children | |||
| c = bpy.data.objects["cam"] | |||
| #s = bpy.data.objects["sun"] | |||
| @@ -34,8 +36,8 @@ for angles in [[0, 1, 2, "North"], [0.5, 1, 2, "Northwest"], [1, 1, 2, "West"], | |||
| c.location = c.location + Vector([0, 0, 10000]) @ rot | |||
| data["views"][angles[3]] = b.dimensions[angles[2]] | |||
| #s.rotation_euler = c.rotation_euler | |||
| bpy.context.scene.render.filepath = f"C:/Users/hausss/Desktop/osm/{data['name']}-{angles[3]}.png" | |||
| bpy.context.scene.render.filepath = f"{PREFIX}/Desktop/osm/{data['name']}-{angles[3]}.png" | |||
| bpy.ops.render.render(write_still = True) | |||
| with open(f"C:/Users/hausss/Desktop/osm/{data['name']}-data.json", "w") as file: | |||
| with open(f"{PREFIX}/Desktop/osm/{data['name']}-data.json", "w") as file: | |||
| json.dump(data, file) | |||
| @@ -0,0 +1,81 @@ | |||
| import bpy | |||
| from mathutils import Vector, Euler | |||
| from math import pi | |||
| import json | |||
| import os | |||
| import pathlib | |||
| GROUP_NAME = "Test" | |||
| GROUP_KIND = "objects" | |||
| path_info = pathlib.Path(bpy.data.filepath).parent.joinpath("macrovision-directory.txt") | |||
| config_path = pathlib.Path(open(path_info).read()) | |||
| json_path = config_path.joinpath("config.json") | |||
| config = json.load(open(json_path.resolve(), encoding="utf-8")) | |||
| parent_workdir = config["work-directory"] | |||
| workdir = pathlib.Path(parent_workdir).joinpath(GROUP_NAME) | |||
| c = bpy.data.objects["cam"] | |||
| c.data.type = "ORTHO" | |||
| bpy.data.scenes["Scene"].render.resolution_x = 1000 | |||
| bpy.data.scenes["Scene"].render.resolution_y = 1000 | |||
| bpy.data.scenes["Scene"].render.film_transparent = True | |||
| bpy.data.scenes["Scene"].view_settings.view_transform = "Raw" | |||
| bpy.data.worlds["World"].node_tree.nodes["Background"].inputs[1].default_value = 0 | |||
| a | |||
| objects = [] | |||
| for object in bpy.data.collections["Macrovision"].objects: | |||
| if object.type == "MESH": | |||
| objects.append(object) | |||
| all_data = {} | |||
| all_data["name"] = GROUP_NAME | |||
| all_data["kind"] = GROUP_KIND | |||
| all_data["forms"] = [] | |||
| os.makedirs(workdir, exist_ok=True) | |||
| for selected in objects: | |||
| for object in bpy.data.collections["Macrovision"].objects: | |||
| object.hide_render = True | |||
| selected.hide_render = False | |||
| bpy.ops.object.transform_apply( rotation = True ) | |||
| data = {} | |||
| data["name"] = selected.name | |||
| data["views"] = [] | |||
| b = selected | |||
| for angles in [[0, 1, 2, "Front"], [1, 1, 2, "Side"], [0, 0, 1, "Top"]]: | |||
| local_bbox_center = 0.125 * sum((Vector(box) for box in b.bound_box), Vector()) | |||
| global_bbox_center = b.matrix_world @ local_bbox_center | |||
| c.location = global_bbox_center | |||
| c.data.ortho_scale = max(b.dimensions) * 1.1 | |||
| c.rotation_euler = Euler([angles[1] * pi / 2, 0, angles[0] * pi / 2]) | |||
| rot = c.rotation_euler.to_matrix() | |||
| rot.invert() | |||
| c.location = c.location + Vector([0, 0, 3]) @ rot | |||
| data["views"].append({ | |||
| "name": angles[3], | |||
| "height": b.dimensions[angles[2]] | |||
| }) | |||
| #s.rotation_euler = c.rotation_euler | |||
| filename = f"{b.name}-{angles[3]}.png" | |||
| bpy.context.scene.render.filepath = workdir.joinpath(filename).resolve().__str__() | |||
| bpy.ops.render.render(write_still = True) | |||
| all_data["forms"].append(data) | |||
| with open(workdir.joinpath("data.json"), "w") as file: | |||
| json.dump(all_data, file) | |||
| @@ -0,0 +1,48 @@ | |||
| import bpy | |||
| from mathutils import Vector, Euler | |||
| from math import pi | |||
| import math | |||
| import json | |||
| import bmesh | |||
| PREFIX = "PREFIX" | |||
| c = bpy.data.objects["cam"] | |||
| #s = bpy.data.objects["sun"] | |||
| selected = bpy.context.selected_objects[0] | |||
| data = {} | |||
| data["name"] = selected.name | |||
| data["place"] = ["Mountains"] | |||
| data["views"] = {} | |||
| b = selected | |||
| if True: | |||
| bpy.ops.object.mode_set( mode = 'EDIT' ) | |||
| bpy.ops.mesh.select_mode( type = 'FACE' ) | |||
| bpy.ops.mesh.select_all( action = 'SELECT' ) | |||
| bpy.ops.mesh.extrude_region_move( | |||
| TRANSFORM_OT_translate={"value":(0, 0, -100)} | |||
| ) | |||
| bpy.ops.transform.transform(mode='RESIZE', value=[1, 1, 0, 1], center_override=[0, 0, 0]) | |||
| for angles in [[0, 1, 2, "North"], [0.5, 1, 2, "Northwest"], [1, 1, 2, "West"]]: | |||
| local_bbox_center = 0.125 * sum((Vector(box) for box in b.bound_box), Vector()) | |||
| global_bbox_center = b.matrix_world @ local_bbox_center | |||
| c.location = global_bbox_center | |||
| c.data.ortho_scale = max(b.dimensions) * 1.1 * math.sqrt(2) | |||
| c.rotation_euler = Euler([angles[1] * pi / 2, 0, angles[0] * pi / 2]) | |||
| rot = c.rotation_euler.to_matrix() | |||
| rot.invert() | |||
| c.location = c.location + Vector([0, 0, 20000]) @ rot | |||
| data["views"][angles[3]] = b.dimensions[angles[2]] | |||
| #s.rotation_euler = c.rotation_euler | |||
| bpy.context.scene.render.filepath = f"{PREFIX}/Desktop/osm/{data['name']}-{angles[3]}.png" | |||
| bpy.ops.render.render(write_still = True) | |||
| with open(f"{PREFIX}/Desktop/osm/{data['name']}-data.json", "w") as file: | |||
| json.dump(data, file) | |||
| @@ -0,0 +1,46 @@ | |||
| import bpy | |||
| from mathutils import Vector, Euler | |||
| from math import pi | |||
| import json | |||
| PREFIX = "PREFIX" | |||
| c = bpy.data.objects["cam"] | |||
| #s = bpy.data.objects["sun"] | |||
| selected = bpy.context.selected_objects[0] | |||
| data = {} | |||
| data["name"] = selected.name | |||
| data["place"] = ["Mountains"] | |||
| data["views"] = {} | |||
| one_object = True | |||
| if not one_object: | |||
| buildings = bpy.data.objects["map"].children | |||
| for b in buildings: | |||
| pick = b.name == data["name"] | |||
| if not pick: | |||
| b.hide_render = True | |||
| else: | |||
| b.hide_render = False | |||
| b = selected | |||
| for angles in [[0, 1, 2, "North"], [0.5, 1, 2, "Northwest"], [1, 1, 2, "West"], [0, 0, 1, "North (Top)"], [1, 0, 0, "West (Top)"]]: | |||
| local_bbox_center = 0.125 * sum((Vector(box) for box in b.bound_box), Vector()) | |||
| global_bbox_center = b.matrix_world @ local_bbox_center | |||
| c.location = global_bbox_center | |||
| c.data.ortho_scale = max(b.dimensions) * 1.1 | |||
| c.rotation_euler = Euler([angles[1] * pi / 2, 0, angles[0] * pi / 2]) | |||
| rot = c.rotation_euler.to_matrix() | |||
| rot.invert() | |||
| c.location = c.location + Vector([0, 0, 10000]) @ rot | |||
| data["views"][angles[3]] = b.dimensions[angles[2]] | |||
| #s.rotation_euler = c.rotation_euler | |||
| bpy.context.scene.render.filepath = f"{PREFIX}/Desktop/osm/{data['name']}-{angles[3]}.png" | |||
| bpy.ops.render.render(write_still = True) | |||
| with open(f"{PREFIX}/Desktop/osm/{data['name']}-data.json", "w") as file: | |||
| json.dump(data, file) | |||
| @@ -0,0 +1,58 @@ | |||
| import bpy | |||
| from mathutils import Vector, Euler | |||
| from math import pi | |||
| import math | |||
| import json | |||
| import bmesh | |||
| PREFIX = "PREFIX" | |||
| c = bpy.data.objects["cam"] | |||
| #s = bpy.data.objects["sun"] | |||
| selected = bpy.context.selected_objects[0] | |||
| data = {} | |||
| data["name"] = selected.name | |||
| data["place"] = ["V"] | |||
| data["views"] = {} | |||
| b = selected | |||
| lowest = math.inf | |||
| for v in b.data.vertices: | |||
| if v.co[2] < lowest: | |||
| lowest = v.co[2] | |||
| if True: | |||
| bpy.ops.object.mode_set( mode = 'EDIT' ) | |||
| bpy.ops.mesh.select_mode( type = 'FACE' ) | |||
| bpy.ops.mesh.select_all( action = 'SELECT' ) | |||
| bpy.ops.transform.translate(value=[0, 0, -lowest]) | |||
| dims = b.object.dimensions | |||
| bpy.ops.transform.translate(value=[-dims[0]/2, -dims[1]/2, -lowest]) | |||
| bpy.ops.mesh.extrude_region_move( | |||
| TRANSFORM_OT_translate={"value":(0,0, -100)} | |||
| ) | |||
| bpy.ops.transform.transform(mode='RESIZE', value=[1, 1, 0, 1], center_override=[0, 0, 0]) | |||
| bpy.ops.mesh.select_all( action = 'SELECT' ) | |||
| for angles in [[0, 1, 2, "North"], [0.5, 1, 2, "Northwest"], [1, 1, 2, "West"]]: | |||
| local_bbox_center = 0.125 * sum((Vector(box) for box in b.bound_box), Vector()) | |||
| global_bbox_center = b.matrix_world @ local_bbox_center | |||
| c.location = global_bbox_center | |||
| c.data.ortho_scale = max(b.dimensions) * 1.1 * math.sqrt(2) | |||
| c.rotation_euler = Euler([angles[1] * pi / 2, 0, angles[0] * pi / 2]) | |||
| rot = c.rotation_euler.to_matrix() | |||
| rot.invert() | |||
| c.location = c.location + Vector([0, 0, 20000]) @ rot | |||
| data["views"][angles[3]] = b.dimensions[angles[2]] | |||
| #s.rotation_euler = c.rotation_euler | |||
| bpy.context.scene.render.filepath = f"{PREFIX}/Desktop/osm/{data['name']}-{angles[3]}.png" | |||
| bpy.ops.render.render(write_still = True) | |||
| with open(f"{PREFIX}/Desktop/osm/{data['name']}-data.json", "w") as file: | |||
| json.dump(data, file) | |||
| @@ -0,0 +1,46 @@ | |||
| import bpy | |||
| from mathutils import Vector, Euler | |||
| from math import pi | |||
| import json | |||
| PREFIX = "PREFIX" | |||
| c = bpy.data.objects["cam"] | |||
| #s = bpy.data.objects["sun"] | |||
| selected = bpy.context.selected_objects[0] | |||
| data = {} | |||
| data["name"] = selected.name | |||
| data["place"] = ["Mountains"] | |||
| data["views"] = {} | |||
| one_object = True | |||
| if not one_object: | |||
| buildings = bpy.data.objects["map"].children | |||
| for b in buildings: | |||
| pick = b.name == data["name"] | |||
| if not pick: | |||
| b.hide_render = True | |||
| else: | |||
| b.hide_render = False | |||
| b = selected | |||
| for angles in [[0, 1, 2, "North"], [0.5, 1, 2, "Northwest"], [1, 1, 2, "West"]]: | |||
| local_bbox_center = 0.125 * sum((Vector(box) for box in b.bound_box), Vector()) | |||
| global_bbox_center = b.matrix_world @ local_bbox_center | |||
| c.location = global_bbox_center | |||
| c.data.ortho_scale = max(b.dimensions) * 1.1 | |||
| c.rotation_euler = Euler([angles[1] * pi / 2, 0, angles[0] * pi / 2]) | |||
| rot = c.rotation_euler.to_matrix() | |||
| rot.invert() | |||
| c.location = c.location + Vector([0, 0, 10000]) @ rot | |||
| data["views"][angles[3]] = b.dimensions[angles[2]] | |||
| #s.rotation_euler = c.rotation_euler | |||
| bpy.context.scene.render.filepath = f"{PREFIX}/Desktop/osm/{data['name']}-{angles[3]}.png" | |||
| bpy.ops.render.render(write_still = True) | |||
| with open(f"{PREFIX}/Desktop/osm/{data['name']}-data.json", "w") as file: | |||
| json.dump(data, file) | |||
| @@ -0,0 +1,5 @@ | |||
| for commit in $(git log --pretty="format:%h"); do | |||
| git show -s --format="%cd" --date=short $commit | tr -d "\n" >> svgs.csv | |||
| echo -n , >> svgs.csv | |||
| expr $(git ls-tree -r $commit ../media/ | wc -l) >> svgs.csv | |||
| done | |||
| @@ -0,0 +1,10 @@ | |||
| import sys | |||
| size = 500 | |||
| od = float(sys.argv[1]) | |||
| id = float(sys.argv[2]) | |||
| thickness = (od - id) / 2 | |||
| print("{0:2f}".format(thickness * size / od)) | |||
| @@ -0,0 +1,12 @@ | |||
| # calculates the diameter in pixels for the inner part of a pipe | |||
| import sys | |||
| size = 500 | |||
| od = float(sys.argv[1]) | |||
| id = float(sys.argv[2]) | |||
| thickness = (od - id) / 2 | |||
| print("{0:2f}".format(thickness * size / od)) | |||
| @@ -0,0 +1,82 @@ | |||
| import sys | |||
| import re | |||
| import json | |||
| import glob | |||
| import os | |||
| import subprocess | |||
| import pathlib | |||
| # an affront to god | |||
| def combine(base_path, highlight_path, vivid_path, output_path): | |||
| base = open(base_path, "r", encoding="utf-8").read() | |||
| highlight = open(highlight_path, "r", encoding="utf-8").read() | |||
| vivid = open(vivid_path, "r", encoding="utf-8").read() | |||
| base_data = re.search("<g.*", base, flags=re.DOTALL)[0][:-7] | |||
| highlight_data = re.search("<g.*", highlight, flags=re.DOTALL)[0][:-7] | |||
| vivid_data = vivid.replace("</metadata>", "</metadata>" + base_data + "\n" + highlight_data) | |||
| with open(output_path, "w", encoding="utf-8") as f: | |||
| f.write(vivid_data) | |||
| subprocess.run([INKSCAPE, "--without-gui", "--export-plain-svg=" + output_path.resolve().__str__(), "--export-area-drawing", output_path], shell=True) | |||
| configdir = pathlib.Path(__file__).parent | |||
| configpath = configdir.joinpath("config.json") | |||
| config = json.load(open(configpath, encoding="utf-8")) | |||
| workdir = pathlib.Path(config["work-directory"]) | |||
| sourcedir = workdir.joinpath(sys.argv[1]) | |||
| macrodir = pathlib.Path(config["macrovision-directory"]) | |||
| print(sourcedir, macrodir) | |||
| side_strings = [] | |||
| POTRACE = config["potrace"] | |||
| INKSCAPE = config["inkscape"] | |||
| output = {} | |||
| with open(sourcedir.joinpath("data.json"), "r", encoding="utf-8") as file: | |||
| all_data = json.load(file) | |||
| group_name = all_data["name"] | |||
| category = all_data["kind"] | |||
| outputdir = macrodir.joinpath("media").joinpath(category).joinpath(group_name) | |||
| os.makedirs(outputdir, exist_ok=True) | |||
| base_lut = configdir.joinpath("base-lut.png").__str__() | |||
| highlight_lut = configdir.joinpath("highlight-lut.png").__str__() | |||
| vivid_lut = configdir.joinpath("vivid-lut.png").__str__() | |||
| for data in all_data["forms"]: | |||
| name = data["name"] | |||
| for view in data["views"]: | |||
| view_name = view["name"] | |||
| input = sourcedir.joinpath(name + "-" + view_name + ".png") | |||
| result = outputdir.joinpath(name + "-" + view_name + ".svg") | |||
| print(result) | |||
| if os.path.exists(result) and os.path.getmtime(input) < os.path.getmtime(result): | |||
| print("Skipping ", input) | |||
| # continue | |||
| input_base = sourcedir.joinpath(name + "-" + view_name + "-base.bmp") | |||
| input_highlight = sourcedir.joinpath(name + "-" + view_name + "-highlight.bmp") | |||
| input_vivid = sourcedir.joinpath(name + "-" + view_name + "-vivid.bmp") | |||
| subprocess.run(["convert", input, base_lut, "-channel", "RGB", "-clut", "-background", "#FFFFFF", "-flatten", input_base], shell=True) | |||
| subprocess.run(["convert", input, highlight_lut, "-channel", "RGB", "-clut", "-background", "#FFFFFF", "-flatten", input_highlight], shell=True) | |||
| subprocess.run(["convert", input, vivid_lut, "-channel", "RGB", "-clut", "-background", "#FFFFFF", "-flatten", input_vivid], shell=True) | |||
| output_base = sourcedir.joinpath(name + "-" + view_name + "-base.svg") | |||
| output_highlight = sourcedir.joinpath(name + "-" + view_name + "-highlight.svg") | |||
| output_vivid = sourcedir.joinpath(name + "-" + view_name + "-vivid.svg") | |||
| subprocess.run([POTRACE, input_base, "-b", "svg", "-o", output_base], shell=True) | |||
| subprocess.run([POTRACE, input_highlight, "-b", "svg", "-C", "#1a1a1a", "-o", output_highlight], shell=True) | |||
| subprocess.run([POTRACE, input_vivid, "-b", "svg", "-C", "#333333", "-o", output_vivid], shell=True) | |||
| combine(output_base, output_highlight, output_vivid, result) | |||
| # os.unlink(input_base) | |||
| # os.unlink(input_highlight) | |||
| @@ -0,0 +1,82 @@ | |||
| import sys | |||
| import re | |||
| import json | |||
| import glob | |||
| import os | |||
| import subprocess | |||
| PREFIX = "PREFIX" | |||
| def combine(base_path, highlight_path, output_path): | |||
| base = open(base_path, "r", encoding="utf-8").read() | |||
| highlight = open(highlight_path, "r", encoding="utf-8").read() | |||
| base_data = re.search("<g.*", base, flags=re.DOTALL)[0][:-7] | |||
| highlight_data = highlight.replace("</metadata>", "</metadata>" + base_data) | |||
| with open(output_path, "w", encoding="utf-8") as f: | |||
| f.write(highlight_data) | |||
| subprocess.run([INKSCAPE, "--without-gui", "--export-plain-svg=" + output_path, "--export-area-drawing", output_path], shell=True) | |||
| if len(sys.argv) <= 1: | |||
| print(f"Usage: {sys.argv[0]} [location name]") | |||
| sys.exit(1) | |||
| template = """ | |||
| {{ | |||
| name: "{0}", | |||
| sides: {{ | |||
| "Side": {{ height: math.unit({1}, "meters") }}, | |||
| "Front": {{ height: math.unit({2}, "meters") }}, | |||
| "Top": {{ height: math.unit({3}, "meters") }}, | |||
| }} | |||
| }}""" | |||
| path = os.path.dirname(sys.argv[0]) | |||
| config = json.load(open(os.path.join(path, "config.json"), "r", encoding="utf-8")) | |||
| side_strings = [] | |||
| os.makedirs("./combined/" + sys.argv[1], exist_ok=True) | |||
| target_file = "vehicles" | |||
| os.makedirs(f"{PREFIX}/furry/macrovision/media/" + target_file + "/" + sys.argv[1] + "/", exist_ok=True) | |||
| POTRACE = config["potrace"] | |||
| INKSCAPE = config["inkscape"] | |||
| output = [] | |||
| for path in glob.glob("*.json"): | |||
| with open(path, "r") as f: | |||
| data = json.load(f) | |||
| name = os.path.splitext(os.path.basename(path))[0] | |||
| for side in data.keys(): | |||
| input = name + "-" + side | |||
| result = "f{PREFIX}/furry/macrovision/media/" + target_file + "/" + sys.argv[1] + "/" + name + "-" + side + ".svg" | |||
| side_strings.append(" [\"{0}\", {1}]".format(name + "-" + side, data[side])) | |||
| if os.path.exists(result) and os.path.getmtime(input + ".png") < os.path.getmtime(result): | |||
| print("Skipping " + input) | |||
| continue | |||
| input_base = input + "-base.bmp" | |||
| input_highlight = input + "-highlight.bmp" | |||
| subprocess.run(["convert", input + ".png", "xc:#000000", "-channel", "RGB", "-clut", "-background", "#ffffff", "-flatten", input_base], shell=True) | |||
| subprocess.run(["convert", input + ".png", "-background", "#ffffff", "-flatten", input_highlight], shell=True) | |||
| base = name + "-" + side + "-base.svg" | |||
| subprocess.run([POTRACE, input_base, "-b", "svg", "-o", base], shell=True) | |||
| highlight = name + "-" + side + "-highlight.svg" | |||
| subprocess.run([POTRACE, input_highlight, "-b", "svg", "-C", "#1a1a1a", "-o", highlight], shell=True) | |||
| combine(base, highlight, result) | |||
| os.unlink(input_base) | |||
| os.unlink(input_highlight) | |||
| output.append(template.format(name, data["Side"], data["Front"], data["Top"])) | |||
| with open(f"{PREFIX}/furry/macrovision/presets/" + target_file + ".js", "r", encoding="utf-8") as file: | |||
| file_data = file.read() | |||
| templated = "[" + ",".join(output) + "\n ];" | |||
| file_data = re.sub("const data" + sys.argv[1].replace(" ", "") + " =.*?];", "const data" + sys.argv[1].replace(" ", "") + " = " + templated, file_data, flags=re.DOTALL) | |||
| with open(f"{PREFIX}/furry/macrovision/presets/" + target_file + ".js", "w", encoding="utf-8") as file: | |||
| file.write(file_data) | |||
| @@ -0,0 +1,98 @@ | |||
| import sys | |||
| import re | |||
| import json | |||
| import glob | |||
| import os | |||
| import subprocess | |||
| PREFIX = "PREFIX" | |||
| def combine(base_path, highlight_path, output_path): | |||
| base = open(base_path, "r", encoding="utf-8").read() | |||
| highlight = open(highlight_path, "r", encoding="utf-8").read() | |||
| base_data = re.search("<g.*", base, flags=re.DOTALL)[0][:-7] | |||
| highlight_data = highlight.replace("</metadata>", "</metadata>" + base_data) | |||
| with open(output_path, "w", encoding="utf-8") as f: | |||
| f.write(highlight_data) | |||
| subprocess.run([INKSCAPE, "--without-gui", "--export-plain-svg=" + output_path, "--export-area-drawing", output_path], shell=True) | |||
| if len(sys.argv) <= 1: | |||
| print(f"Usage: {sys.argv[0]} [location name]") | |||
| sys.exit(1) | |||
| template = """ | |||
| {{ | |||
| name: "{0}", | |||
| sides: {{ | |||
| "Side": {{ height: math.unit({1}, "meters") }}, | |||
| "Front": {{ height: math.unit({2}, "meters") }}, | |||
| "Top": {{ height: math.unit({3}, "meters") }}, | |||
| }} | |||
| }}""" | |||
| path = os.path.dirname(sys.argv[0]) | |||
| config = json.load(open(os.path.join(path, "config.json"), "r", encoding="utf-8")) | |||
| output = [] | |||
| os.makedirs("./combined/" + sys.argv[1], exist_ok=True) | |||
| target_file = "vehicles" | |||
| os.makedirs(f"{PREFIX}/furry/macrovision/media/" + target_file + "/" + sys.argv[1] + "/", exist_ok=True) | |||
| POTRACE = config["potrace"] | |||
| INKSCAPE = config["inkscape"] | |||
| METERS_PER_UNIT = 0.03048 * 0.97681253/ 1.9898 | |||
| if sys.argv[1] == "Tanks": | |||
| METERS_PER_UNIT /= 1.50811320755 | |||
| for path in glob.glob("*.json"): | |||
| base_name = os.path.splitext(os.path.basename(path))[0] | |||
| data = json.load(open(path, "r", encoding="utf-8")) | |||
| sizes = {} | |||
| for view, scale in data.items(): | |||
| name = base_name + "-" + view | |||
| result = f"{PREFIX}/furry/macrovision/media/vehicles/" + sys.argv[1] + "/" + name + ".svg" | |||
| if view == "Top": | |||
| height = int(subprocess.check_output(["convert", name + ".png", "-trim", "-rotate", "270", "-format", "%[h]", "info:"], shell=True).decode("utf-8")) | |||
| else: | |||
| height = int(subprocess.check_output(["convert", name + ".png", "-trim", "-format", "%[h]", "info:"], shell=True).decode("utf-8")) | |||
| sizes[view] = height / scale * METERS_PER_UNIT | |||
| if os.path.exists(result) and os.path.getmtime(name + ".png") < os.path.getmtime(result): | |||
| print("Skipping " + name) | |||
| continue | |||
| input_base = "base.bmp" | |||
| input_highlight = "highlight.bmp" | |||
| subprocess.run(["convert", name + ".png", "xc:#000000", "-channel", "RGB", "-clut", "-background", "#ffffff", "-flatten", input_base], shell=True) | |||
| subprocess.run(["convert", name + ".png", "-background", "#ffffff", "-flatten", input_highlight], shell=True) | |||
| # rotate the top view, since I capture it horizontally | |||
| if view == "Top": | |||
| subprocess.run(["mogrify", "-rotate", "270", input_base], shell=True) | |||
| subprocess.run(["mogrify", "-rotate", "270", input_highlight], shell=True) | |||
| base = "base.svg" | |||
| subprocess.run([POTRACE, input_base, "-b", "svg", "-o", base], shell=True) | |||
| highlight = "highlight.svg" | |||
| subprocess.run([POTRACE, input_highlight, "-b", "svg", "-C", "#1a1a1a", "-o", highlight], shell=True) | |||
| combine(base, highlight, result) | |||
| os.unlink(input_base) | |||
| os.unlink(input_highlight) | |||
| output.append(template.format(base_name, sizes["Side"], sizes["Front"], sizes["Top"])) | |||
| with open(f"{PREFIX}/furry/macrovision/presets/vehicles.js", "r", encoding="utf-8") as file: | |||
| file_data = file.read() | |||
| templated = "[" + ",".join(output) + "\n ];" | |||
| file_data = re.sub("const data" + sys.argv[1] + " =.*?];", "const data" + sys.argv[1] + " = " + templated, file_data, flags=re.DOTALL) | |||
| with open(f"{PREFIX}/furry/macrovision/presets/vehicles.js", "w", encoding="utf-8") as file: | |||
| file.write(file_data) | |||
| @@ -0,0 +1,74 @@ | |||
| import sys | |||
| import re | |||
| import json | |||
| import glob | |||
| import os | |||
| import subprocess | |||
| PREFIX = "PREFIX" | |||
| def combine(base_path, highlight_path, output_path): | |||
| base = open(base_path, "r", encoding="utf-8").read() | |||
| highlight = open(highlight_path, "r", encoding="utf-8").read() | |||
| base_data = re.search("<g.*", base, flags=re.DOTALL)[0][:-7] | |||
| highlight_data = highlight.replace("</metadata>", "</metadata>" + base_data) | |||
| with open(output_path, "w", encoding="utf-8") as f: | |||
| f.write(highlight_data) | |||
| subprocess.run([INKSCAPE, "--without-gui", "--export-plain-svg=" + output_path, "--export-area-drawing", output_path], shell=True) | |||
| if len(sys.argv) <= 1: | |||
| print(f"Usage: {sys.argv[0]} [location name]") | |||
| sys.exit(1) | |||
| template = """[ | |||
| {1} | |||
| ];""" | |||
| path = os.path.dirname(sys.argv[0]) | |||
| config = json.load(open(os.path.join(path, "config.json"), "r", encoding="utf-8")) | |||
| side_strings = [] | |||
| os.makedirs("./combined/" + sys.argv[1], exist_ok=True) | |||
| if sys.argv[1] in ["Mountains"]: | |||
| target_file = "real-terrain" | |||
| else: | |||
| target_file = "real-buildings" | |||
| os.makedirs(f"{PREFIX}/furry/macrovision/media/" + target_file + "/" + sys.argv[1] + "/", exist_ok=True) | |||
| POTRACE = config["potrace"] | |||
| INKSCAPE = config["inkscape"] | |||
| for path in glob.glob("*.json"): | |||
| with open(path, "r") as f: | |||
| data = json.load(f) | |||
| if data["place"] == [sys.argv[1]]: | |||
| name = "./svgs/" + data["name"] | |||
| for side in data["views"].keys(): | |||
| input = data["name"] + "-" + side | |||
| result = f"{PREFIX}/furry/macrovision/media/" + target_file + "/" + data["place"][0] + "/" + data["name"] + "-" + side + ".svg" | |||
| side_strings.append(" [\"{0}\", {1}]".format(data["name"] + "-" + side, data["views"][side])) | |||
| if os.path.exists(result) and os.path.getmtime(input + ".png") < os.path.getmtime(result): | |||
| print("Skipping " + input) | |||
| continue | |||
| input_base = input + "-base.bmp" | |||
| input_highlight = input + "-highlight.bmp" | |||
| subprocess.run(["convert", input + ".png", "xc:#000000", "-channel", "RGB", "-clut", "-background", "#ffffff", "-flatten", input_base], shell=True) | |||
| subprocess.run(["convert", input + ".png", "-background", "#ffffff", "-flatten", input_highlight], shell=True) | |||
| base = name + "-" + side + "-base.svg" | |||
| subprocess.run([POTRACE, input_base, "-b", "svg", "-o", base], shell=True) | |||
| highlight = name + "-" + side + "-highlight.svg" | |||
| subprocess.run([POTRACE, input_highlight, "-b", "svg", "-C", "#1a1a1a", "-o", highlight], shell=True) | |||
| combine(base, highlight, result) | |||
| os.unlink(input_base) | |||
| os.unlink(input_highlight) | |||
| with open(f"{PREFIX}/furry/macrovision/presets/" + target_file + ".js", "r", encoding="utf-8") as file: | |||
| file_data = file.read() | |||
| templated = template.format(sys.argv[1], ",\n".join(side_strings)) | |||
| file_data = re.sub("const data" + sys.argv[1] + " =.*?];", "const data" + sys.argv[1] + " = " + templated, file_data, flags=re.DOTALL) | |||
| with open(f"{PREFIX}/furry/macrovision/presets/" + target_file + ".js", "w", encoding="utf-8") as file: | |||
| file.write(file_data) | |||