diff --git a/addon/ops/arduino_export.py b/addon/ops/arduino_export.py index 6009a35..b5eee70 100644 --- a/addon/ops/arduino_export.py +++ b/addon/ops/arduino_export.py @@ -44,7 +44,7 @@ class ArduinoExport(Operator, BaseExport, ExportHelper): ) ) - def export(self, positions, context): + def export(self, positions, filepath, context): variable_type = 'int' if self.precision == 0 else 'float' fps, frames, seconds = self.get_time_meta(context.scene) filename = self.get_blend_filename() @@ -93,4 +93,5 @@ def export(self, positions, context): if self.namespace: content += f"\n}} // namespace {context.scene.name}\n" - return content + with open(filepath, 'w', encoding='utf-8') as file: + file.write(content) diff --git a/addon/ops/base_export.py b/addon/ops/base_export.py index 86915cb..6b0b0a8 100644 --- a/addon/ops/base_export.py +++ b/addon/ops/base_export.py @@ -6,6 +6,9 @@ class BaseExport: + COMMAND_START = 0x3C + COMMAND_END = 0x3E + precision: bpy.props.IntProperty( name="Precision", description="The number of decimal digits to round to", @@ -33,7 +36,7 @@ def execute(self, context): try: positions = calculate_positions(context, self.precision) - content = self.export(positions, context) + self.export(positions, self.filepath, context) except RuntimeError as error: self.report({'ERROR'}, str(error)) @@ -44,9 +47,6 @@ def execute(self, context): if original_live_mode is True: bpy.ops.servo_animation.start_live_mode('INVOKE_DEFAULT') - with open(self.filepath, 'w', encoding='utf-8') as file: - file.write(content) - end = time.time() duration = round(end - start) self.report( @@ -54,6 +54,14 @@ def execute(self, context): return {'FINISHED'} + @classmethod + def get_command(cls, servo_id, position): + command = [cls.COMMAND_START, servo_id] + command += position.to_bytes(2, 'big') + command += [cls.COMMAND_END] + + return command + @staticmethod def get_time_meta(scene): fps = scene.render.fps diff --git a/addon/ops/json_export.py b/addon/ops/json_export.py index a4a7169..5705f7c 100644 --- a/addon/ops/json_export.py +++ b/addon/ops/json_export.py @@ -20,7 +20,7 @@ class JsonExport(Operator, BaseExport, ExportHelper): maxlen=255 ) - def export(self, positions, context): + def export(self, positions, filepath, context): fps, frames, seconds = self.get_time_meta(context.scene) filename = self.get_blend_filename() @@ -45,4 +45,7 @@ def export(self, positions, context): "servos": servos } - return json.dumps(data, indent=4) + content = json.dumps(data, indent=4) + + with open(filepath, 'w', encoding='utf-8') as file: + file.write(content) diff --git a/addon/ops/servoanim_export.py b/addon/ops/servoanim_export.py index 6752545..10689ff 100644 --- a/addon/ops/servoanim_export.py +++ b/addon/ops/servoanim_export.py @@ -18,19 +18,19 @@ class ServoanimExport(Operator, BaseExport, ExportHelper): maxlen=255 ) - def export(self, positions, context): - fps, frames, seconds = self.get_time_meta(context.scene) - positions_keys = list(positions.keys()) - ids = ",".join(str(x) for x in positions_keys) + LINE_BREAK = 10 - content = f"fps:{fps} frames:{frames} seconds:{seconds} ids:{ids}\n\n" + def export(self, positions, filepath, context): + _fps, frames, _seconds = self.get_time_meta(context.scene) + content = [] for frame in range(frames): for servo_id in range(255): if servo_id not in positions: continue - pos = positions[servo_id][frame] - content += str(pos) + " " - content = content[:-1] + "\n" + position = positions[servo_id][frame] + content += self.get_command(servo_id, position) + content.append(self.LINE_BREAK) - return content + with open(filepath, 'wb') as file: + file.write(bytes(content)) diff --git a/examples/IK/ik.servoanim b/examples/IK/ik.servoanim index c1ad172..ce7cd57 100644 Binary files a/examples/IK/ik.servoanim and b/examples/IK/ik.servoanim differ