diff --git a/blender-addon/clever-show-addon-src/__init__.py b/blender-addon/clever-show-addon-src/__init__.py index 3be9144..ad8385b 100644 --- a/blender-addon/clever-show-addon-src/__init__.py +++ b/blender-addon/clever-show-addon-src/__init__.py @@ -5,12 +5,12 @@ from . operators.export import ExportSwarmAnimation from . operators.check import CheckSwarmAnimation bl_info = { - "name": "clever-show animation (.csv)", + "name": "clever-show animation (.anim)", "author": "Artem Vasiunik & Arthur Golubtsov", "version": (0, 6, 1), "blender": (2, 83, 0), - "location": "File > Export > clever-show animation (.csv)", - "description": "Export > clever-show animation (.csv)", + "location": "File > Export > clever-show animation (.anim)", + "description": "Export > clever-show animation (.anim)", "doc_url": "https://github.com/CopterExpress/clever-show/blob/master/blender-addon/README.md", "tracker_url": "https://github.com/CopterExpress/clever-show/issues", "category": "Import-Export" @@ -21,7 +21,6 @@ bl_info = { class CleverShowProperties(PropertyGroup): filter_obj: EnumProperty( name="Filter objects:", - description="", items=[('all', "No filter (all objects)", ""), ('selected', "Only selected", ""), ('name', "By object name", ""), @@ -52,13 +51,35 @@ class CleverShowProperties(PropertyGroup): ) -classes = (CleverShowProperties, +class CleverDroneProperties(PropertyGroup): + is_drone: BoolProperty(name="Is drone") + + +class CleverLedProperties(PropertyGroup): + is_led: BoolProperty( + name="Is LED color",) + effect: EnumProperty( + name="LED effect", + items=[('fill', 'Fill', ""), + ('blink', 'Blink', ""), + ('blink_fast', 'Blink fast', ""), + ('fade', 'Fade', ""), + ('wipe', 'Wipe', ""), + ('flash', 'Flash', ""), + ('rainbow', 'Rainbow', ""), + ('rainbow_fill', 'Rainbow fill', ""), + ], + defaul="fill" + ) + + +classes = (CleverShowProperties, CleverDroneProperties, CleverLedProperties, ExportSwarmAnimation, CheckSwarmAnimation) def menu_func(self, context): self.layout.operator( ExportSwarmAnimation.bl_idname, - text="clever-show animation (.csv)" + text="clever-show animation (.anim)" ) @@ -69,6 +90,8 @@ def register(): register_class(cls) bpy.types.Scene.clever_show = PointerProperty(type=CleverShowProperties) + bpy.types.Object.drone = PointerProperty(type=CleverDroneProperties) + bpy.types.Material.led = PointerProperty(type=CleverLedProperties) bpy.types.TOPBAR_MT_file_export.append(menu_func) @@ -78,7 +101,10 @@ def unregister(): for cls in reversed(classes): unregister_class(cls) + del bpy.types.Scene.clever_show + del bpy.types.Object.drone + del bpy.types.Material.led bpy.types.TOPBAR_MT_file_export.remove(menu_func) diff --git a/blender-addon/clever-show-addon-src/operators/export.py b/blender-addon/clever-show-addon-src/operators/export.py index 31c4f96..3f247b2 100644 --- a/blender-addon/clever-show-addon-src/operators/export.py +++ b/blender-addon/clever-show-addon-src/operators/export.py @@ -9,9 +9,44 @@ from bpy.types import Operator from bpy.props import StringProperty, BoolProperty, FloatProperty, IntProperty +def create_dir(folder_path): + if os.path.isdir(folder_path): + return + os.mkdir(folder_path) + + +def get_rgb(drone_obj): + try: + slot = next(filter(lambda x: "led_color" in x.name.lower(), drone_obj.material_slots)) + except StopIteration: + raise RuntimeError("No matching slots") + + try: + material = slot.material + if material.use_nodes: + value = get_node_color(material) + else: + value = material.diffuse_color + + alpha = value[3] + return [int(value[component] * alpha * 255) for component in range(3)] + except AttributeError: + raise RuntimeError("Missing attributes") + + +def get_node_color(material): + try: + node = next(filter(lambda x: x.type in ('EMISSION', 'BSDF_DIFFUSE', "Principled BSDF"), + material.node_tree.nodes)) + except StopIteration: + raise RuntimeError("Missing attributes") + else: + return node.inputs[0].default_value + + class ExportSwarmAnimation(Operator, ExportHelper): bl_idname = "clever_show.export" - bl_label = "clever-show animation (.csv)" + bl_label = "clever-show animation (.anim)" filename_ext = '' use_filter_folder = True @@ -23,6 +58,40 @@ class ExportSwarmAnimation(Operator, ExportHelper): default="" ) - def execute(self, context): - pass + def _get_drone_objects(self, context): + clever_show = context.scene.clever_show + return context.visible_objects + + def execute(self, context): + create_dir() + + drone_objects = self._get_drone_objects(context) + + for drone_obj in drone_objects: + + self._export_drone(drone_obj, context) + + def _export_drone(self, drone_obj, context): + animation = [] + + scene = context.scene + + frame_start = context.scene.frame_start + frame_end = context.scene.frame_end + + for frame_num in range(frame_start, frame_end + 1): + scene.frame_set(frame_start) + position = drone_obj.matrix_world.to_translation() + yaw = drone_obj.matrix_world.to_euler('XYZ')[2] + frame = {"fly": list(position), "yaw": yaw, } + + try: + led_color = get_rgb(drone_obj) + frame.update({"led_color": led_color}) + except RuntimeError: + pass + + animation.append(frame) + +