import os import sys import math import bpy import argparse parser = argparse.ArgumentParser() parser.add_argument("filepath", help="path to svg file") parser.add_argument("-rx", "--rotate-x", help="rotate x axis", type=float, default=0) parser.add_argument("-ry", "--rotate-y", help="rotate y axis", type=float, default=0) parser.add_argument("-rz", "--rotate-z", help="rotate z axis", type=float, default=0) parser.add_argument("-th", "--thickness", help="thickness of the icon", type=float, default=1) parser.add_argument( "-d", "--distance", help="distance of the camera", type=float, default=1) parser.add_argument( "-lx", "--light-x", help="x position of the light", type=float, default=0) parser.add_argument( "-ly", "--light-y", help="y position of the light", type=float, default=0) parser.add_argument( "-lz", "--light-z", help="z position of the light", type=float, default=0) parser.add_argument( "-ls", "--light-strength", help="strength of the light", type=float, default=1) parser.add_argument("-r", "--red", help="red color", type=float, default=-1) parser.add_argument("-g", "--green", help="green color", type=float, default=-1) parser.add_argument("-b", "--blue", help="blue color", type=float, default=-1) parser.add_argument( "-s", "--size", help="size of the image", type=int, default=2048) parser.add_argument( "--bevel", help="bevel depth of the icon", type=float, default=1 ) def main(): argv = sys.argv argv = argv[argv.index("--") + 1:] if "--" in argv else argv[1:] if len(argv) >= 1: args = parser.parse_args(argv) filepath = args.filepath rotate_x = args.rotate_x rotate_y = args.rotate_y rotate_z = args.rotate_z thickness = args.thickness distance = args.distance light_x = args.light_x light_y = args.light_y light_z = args.light_z light_strength = args.light_strength color_r = args.red color_g = args.green color_b = args.blue size = args.size bevel = args.bevel capture( filepath, rotate_x, rotate_y, rotate_z, thickness, bevel, distance, light_x, light_y, light_z, light_strength, color_r, color_g, color_b, size ) else: parser.print_help() def capture( filepath, rotate_x=0, rotate_y=0, rotate_z=0, thickness=1, bevel=1, distance=1, light_x=0, light_y=0, light_z=0, light_strength=1, color_r=-1, color_g=-1, color_b=-1, size=2048 ): reset() bpy.ops.import_curve.svg(filepath=filepath) collection = bpy.data.collections[os.path.basename(filepath)] x, y, z, min_x, min_y, min_z = collection_dimensions(collection) for obj in collection.objects: obj.select_set(True) # scale up the objects factor = 1 / max(x, y, z) bpy.ops.transform.resize(value=(factor, factor, factor)) # move the objects bpy.ops.transform.translate( value=(0, factor * (-0.5 * x - min_x), factor * (-0.5 * y - min_y))) # rotate the objects bpy.ops.transform.rotate(value=math.pi * -0.5 + deg_to_rad(rotate_x), orient_axis="X") bpy.ops.transform.rotate(value=deg_to_rad(rotate_y), orient_axis="Y") bpy.ops.transform.rotate(value=math.pi * -0.5 + deg_to_rad(rotate_z), orient_axis="Z") material = bpy.data.materials.new("Color") material.diffuse_color = ( color_r if color_r != -1 else 1, color_g if color_g != -1 else 1, color_b if color_b != -1 else 1, 1) for obj in collection.objects: obj.data.extrude = thickness * 0.0005 obj.data.bevel_depth = bevel * 0.0001 if color_r != -1 or color_g != -1 or color_b != -1: obj.active_material = material # add light bpy.ops.object.light_add( type="POINT", location=(light_x, light_y, light_z)) bpy.data.objects["Point"].data.energy = light_strength * 10 # add camera bpy.ops.object.camera_add( location=(distance * 3, 0, 0), rotation=(math.pi*0.5, 0, math.pi*0.5)) bpy.context.scene.camera = bpy.data.objects["Camera"] render(filepath.replace(".svg", ".png"), size) return def log(any): keys = dir(any) for key in keys: attr = getattr(any, key) if not callable(attr): print("prop:", key, attr) else: print("func:", key) def render(out=os.path.join(os.getcwd(), "out.png"), size=2048): bpy.context.scene.render.filepath = out bpy.context.scene.render.resolution_x = size bpy.context.scene.render.resolution_y = size bpy.context.scene.render.film_transparent = True bpy.ops.render.render(write_still=True) def collection_dimensions(collection): min_x = min_y = min_z = float("inf") max_x = max_y = max_z = float("-inf") for obj in collection.objects: min_x = min(min_x, obj.bound_box[0][0]) min_y = min(min_y, obj.bound_box[0][1]) min_z = min(min_z, obj.bound_box[0][2]) max_x = max(max_x, obj.bound_box[6][0]) max_y = max(max_y, obj.bound_box[6][1]) max_z = max(max_z, obj.bound_box[6][2]) x, y, z = max_x - min_x, max_y - min_y, max_z - min_z return x, y, z, min_x, min_y, min_z def deg_to_rad(deg): return deg * math.pi / 180 def reset(): for objs in ( bpy.data.objects, bpy.data.meshes, bpy.data.cameras, ): for obj in objs: objs.remove(obj) for collections in ( bpy.data.collections, ): for collection in collections: collections.remove(collection) if __name__ == "__main__": main()