Spaces:
Runtime error
Runtime error
| 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() | |