Hi there, also ccing in @AldrinMathew, this is not an issue so much as a question. I've been writing an exporter for keymesh for use in Unity, and I've stumbled into a problem where I'm trying to get the list of materials names used each keyframe. The problem seems to be that this list isn't updated with all the materials when I iterate across it in the exporter. I'm not entirely sure how to solve this or even why it's happenening. The output is also currently dependent on what frame is selected in the scrubber.
Below is some of my exporter code:
class KeyframeMeshObjExport(bpy.types.Operator, ExportHelper):
bl_idname = "object.keyframe_mesh_obj"
bl_label = "Export Obj Sequence"
bl_options = {'REGISTER'}
filename_ext = ".obj"
@classmethod
def poll(cls, context):
# It's a Keymesh scene
for o in bpy.context.selected_objects:
if "km_datablock" and "km_id" in o:
return True
return False
def execute(self, context):
frame_end = -99999
frame_start = 99999
current_frame = bpy.context.scene.frame_current
obs = list(bpy.context.selected_objects)
objects = []
framerate = 11
# Get length of the current action
for o in obs:
framerate = o.users_scene[0].render.fps
this_end = o.users_scene[0].frame_end
this_start = o.users_scene[0].frame_start
if(this_end > frame_end):
frame_end = this_end
if(this_start < frame_start):
frame_start = this_start
file_path = Path(self.filepath)
folder_path = file_path.parent
materials = {}
bpy.ops.object.select_all(action='DESELECT')
for o in obs:
keyframes=[]
o.select_set(True)
object_material_slots={}
for i in range(frame_start, frame_end + 1):
bpy.context.scene.frame_current = i
km_frame_handler(0)
updateKeymesh(bpy.context.scene)
dirty = False
fcurves = o.animation_data.action.fcurves
for fcurve in fcurves:
if fcurve.data_path != '["km_datablock"]':
continue
for keyframe in fcurve.keyframe_points:
if i == int(keyframe.co.x):
dirty = True
break
if dirty:
frame_materials=[]
# The line in question that doesn't seem to be updating:
for mat in o.material_slots:
materials[mat.name] = True
object_material_slots[mat.name] = True
frame_materials.append(mat.name)
keyframes.append({"frame":i, "materials": list(frame_materials) })
filename = str(Path(str(folder_path.absolute()) +"/" + re.sub(r'\.obj$',"_",file_path.name) + o.name + "_" + str(i) + ".obj").absolute())
bpy.ops.export_scene.obj(filepath=filename, use_materials=True, use_selection=True, use_blen_objects=True, group_by_object=True)
o.select_set(False)
objects.append({
"name": o.name,
"keyframes": list(keyframes),
"materials": list(object_material_slots.keys())
})
json_data_filename = str(Path(str(folder_path.absolute()) +"/" + file_path.name + ".objseq").absolute())
with open(json_data_filename, 'w') as outfile:
json.dump({
"materials": list(materials.keys()),
"frame_start": frame_start,
"frame_end": frame_end,
"frame_rate": framerate,
"objects": list(objects)
}, outfile)
bpy.context.scene.frame_current = current_frame
km_frame_handler(0)
return {'FINISHED'}
This is the output of this script in an example project I'm working on. There should be five materials in frame 63, but only three show up. The actual exported obj has space for 5 materials:
Hi there, also ccing in @AldrinMathew, this is not an issue so much as a question. I've been writing an exporter for keymesh for use in Unity, and I've stumbled into a problem where I'm trying to get the list of materials names used each keyframe. The problem seems to be that this list isn't updated with all the materials when I iterate across it in the exporter. I'm not entirely sure how to solve this or even why it's happenening. The output is also currently dependent on what frame is selected in the scrubber.
Below is some of my exporter code:
This is the output of this script in an example project I'm working on. There should be five materials in frame 63, but only three show up. The actual exported obj has space for 5 materials: