| @@ -1,43 +0,0 @@ | |||
| import bpy | |||
| 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"] | |||
| selected = bpy.context.selected_objects[0] | |||
| data = {} | |||
| data["name"] = selected.name | |||
| data["place"] = ["Vancouver"] | |||
| data["views"] = {} | |||
| 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) | |||
| @@ -1,144 +0,0 @@ | |||
| import bpy | |||
| from mathutils import Vector, Euler | |||
| from math import pi | |||
| import json | |||
| import os | |||
| import subprocess | |||
| import xml.etree.ElementTree as ET | |||
| c = bpy.data.objects["cam"] | |||
| selected = bpy.context.selected_objects[0] | |||
| bpy.ops.object.transform_apply( rotation = True ) | |||
| data = {} | |||
| b = selected | |||
| FRONT = [0, 1, 2, "Front"] | |||
| FRONT_CORNER = [0.5, 1, 2, "Front Corner"] | |||
| SIDE = [1, 1, 2, "Side"] | |||
| BACK_CORNER = [1.5, 1, 2, "Back Corner"] | |||
| BACK = [2, 1, 2, "Back"] | |||
| BOTTOM = [0, 2, 1, "Bottom"] | |||
| TOP = [2, 0, 1, "Top"] | |||
| sides = [FRONT, FRONT_CORNER, SIDE, BACK_CORNER, BACK, BOTTOM, TOP] | |||
| path = "/tmp/macrovision/" | |||
| media_path = "/home/crux/furry/macrovision/media/" | |||
| media_folder = "clothing/Boots/" | |||
| os.makedirs(path, exist_ok=True) | |||
| os.makedirs(os.path.join(media_path, media_folder), exist_ok=True) | |||
| ns = {"svg": "http://www.w3.org/2000/svg"} | |||
| ET.register_namespace("", ns["svg"]) | |||
| TEMPLATE = """ | |||
| {{ | |||
| name: "{0}", | |||
| sides: {{ | |||
| {1} | |||
| }} | |||
| }}""" | |||
| VIEW_TEMPLATE = ' "{0}": {{ height: math.unit({1}, "meters") }}' | |||
| for angles in sides: | |||
| 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, 100]) @ rot | |||
| data[angles[3]] = b.dimensions[angles[2]] | |||
| output_path = os.path.join(path, f"{b.name}-{angles[3]}") | |||
| bpy.context.scene.render.filepath = output_path | |||
| svg_path = output_path + "0001.svg" | |||
| bpy.ops.render.render(write_still = True) | |||
| os.rename(svg_path, output_path + ".svg") | |||
| subprocess.check_output([ | |||
| "potrace", | |||
| "-b", | |||
| "svg", | |||
| output_path + ".bmp", | |||
| "-o", | |||
| output_path + "-fill.svg" | |||
| ]) | |||
| line_xml = ET.parse(output_path + ".svg") | |||
| fill_xml = ET.parse(output_path + "-fill.svg") | |||
| style = None | |||
| for elem in line_xml.findall(".//svg:path", namespaces=ns): | |||
| if style is None: | |||
| style = {} | |||
| for key in elem.attrib: | |||
| if not key == "d": | |||
| style[key] = elem.attrib[key] | |||
| for key in style: | |||
| del elem.attrib[key] | |||
| parts = elem.attrib["d"].strip().split(" ") | |||
| if len(parts) > 6 and parts[1] == parts[3] == parts[5] and parts[2] == parts[4] == parts[6]: | |||
| elem.attrib["DELETEME"] = True | |||
| while True: | |||
| child = line_xml.find(".//svg:path[@DELETEME]", namespaces=ns) | |||
| parent = line_xml.find(".//svg:path[@DELETEME]...", namespaces=ns) | |||
| print(parent, child) | |||
| if parent is None: | |||
| break | |||
| parent.remove(child) | |||
| for key in style: | |||
| line_xml.find("./svg:g", namespaces=ns).attrib[key] = style[key] | |||
| line_xml.write(output_path + "-cleaned.svg") | |||
| subprocess.check_output([ | |||
| "inkscape", | |||
| output_path + "-cleaned.svg", | |||
| "--batch-process", | |||
| "--actions=EditSelectAll;SelectionSimplify;FileSave", | |||
| ]) | |||
| optimized = ET.parse(output_path + "-cleaned.svg") | |||
| lines = optimized.find("./svg:g", namespaces=ns) | |||
| fill_xml.find("svg:g[@fill='#000000']", namespaces=ns).attrib["fill"] = "#1a1a1a" | |||
| fill_xml.iter().__next__().append(lines) | |||
| fill_xml.write(output_path + "-combined.svg") | |||
| subprocess.check_output([ | |||
| "inkscape", | |||
| "--batch-process", | |||
| "--export-plain-svg=" + output_path + "-prepared.svg", | |||
| "--export-area-drawing", | |||
| output_path + "-combined.svg" | |||
| ]) | |||
| subprocess.check_output([ | |||
| "svgo", | |||
| output_path + "-prepared.svg", | |||
| "-o", | |||
| os.path.join(media_path, media_folder, f"{b.name}-{angles[3]}.svg") | |||
| ]) | |||
| lines = [] | |||
| for key, value in data.items(): | |||
| lines.append(VIEW_TEMPLATE.format(key, value)) | |||
| print(TEMPLATE.format(b.name, ",\n".join(lines))) | |||
| @@ -1,48 +0,0 @@ | |||
| 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) | |||
| @@ -1,46 +0,0 @@ | |||
| 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) | |||
| @@ -1,58 +0,0 @@ | |||
| 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) | |||
| @@ -1,46 +0,0 @@ | |||
| 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) | |||
| @@ -1,64 +0,0 @@ | |||
| import sys | |||
| import re | |||
| import json | |||
| import glob | |||
| import os | |||
| # here's the import workflow: | |||
| # 1. import buildings into blender | |||
| # 2. use the blender-building.py script in blender while selecting a building to export images | |||
| # 3. batch-trace and color the overlay images | |||
| # 4. batch-trace the base images | |||
| # 5. batch-expand all of the images | |||
| # 6. use this script to combine the images and record the building data | |||
| # 7. batch-crop the combined images | |||
| # this script smashes two svgs together in a way that is, | |||
| # to be frank, sacrilege | |||
| 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("<path.*?</svg>", base)[0][:-6] | |||
| highlight_data = highlight.replace("</defs>", "</defs>" + base_data) | |||
| with open(output_path, "w", encoding="utf-8") as f: | |||
| f.write(highlight_data) | |||
| if len(sys.argv) <= 1: | |||
| print(f"Usage: {sys.argv[0]} [location name]") | |||
| sys.exit(1) | |||
| sides = [ | |||
| "North", | |||
| "Northwest", | |||
| "West", | |||
| "North (Top)", | |||
| "West (Top)" | |||
| ] | |||
| template = """ results.push(makeRealBuilding( | |||
| "{0}", | |||
| [ | |||
| {1} | |||
| ] | |||
| )) | |||
| """ | |||
| side_strings = [] | |||
| os.mkdir("./combined/" + sys.argv[1]) | |||
| 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 sides: | |||
| base = name + "-" + side + "-base-01.svg" | |||
| highlight = name + "-" + side + "-highlight-01.svg" | |||
| result = "./combined/" + sys.argv[1] + "/" + data["name"] + "-" + side + ".svg" | |||
| combine(base, highlight, result) | |||
| side_strings.append(" [\"{0}\", {1}]".format(data["name"] + "-" + side, data["views"][side])) | |||
| print(template.format(sys.argv[1] + " Buildings", ",\n".join(side_strings))) | |||
| @@ -47,9 +47,9 @@ 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__() | |||
| base_lut = configdir.joinpath("luts").joinpath("base-lut.png").__str__() | |||
| highlight_lut = configdir.joinpath("luts").joinpath("highlight-lut.png").__str__() | |||
| vivid_lut = configdir.joinpath("luts").joinpath("vivid-lut.png").__str__() | |||
| for data in all_data["forms"]: | |||
| name = data["name"] | |||
| @@ -1,82 +0,0 @@ | |||
| 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) | |||
| @@ -1,98 +0,0 @@ | |||
| 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) | |||
| @@ -1,74 +0,0 @@ | |||
| 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) | |||