def create_conncection_for_both_conditions(d, layers_rods, indices, mask, windows_num, norm_fac, T, radius): N = len(indices) parent_obj = bpy.data.objects[PARENT_OBJ] print('Create connections for both conditions') now = time.time() for run, (ind, conn_name, (i, j)) in enumerate(zip(indices, d.con_names[mask], d.con_indices[mask])): mu.time_to_go(now, run, N, runs_num_to_print=10) if d.con_colors.ndim == 3: con_color = np.hstack((d.con_colors[ind, 0, :], [0.])) else: con_color = np.hstack((d.con_colors[ind, :], [0.])) p1, p2 = d.locations[i, :] * 0.1, d.locations[j, :] * 0.1 mu.cylinder_between(p1, p2, radius, layers_rods) # mu.create_material('{}_mat'.format(conn_name), (0, 0, 1, 1), 1) mu.create_material('{}_mat'.format(conn_name), con_color, 1) cur_obj = bpy.context.active_object cur_obj.name = conn_name cur_obj.parent = parent_obj # cur_obj.animation_data_clear() if windows_num == 1: continue for cond_id, cond in enumerate(d.conditions): # insert_frame_keyframes(cur_obj, '{}-{}'.format(conn_name, cond), d.con_values[ind, -1, cond_id], T) for t in range(windows_num): extra_time_points = 0 if norm_fac ==1 else 2 timepoint = t * norm_fac + extra_time_points mu.insert_keyframe_to_custom_prop(cur_obj, '{}-{}'.format(conn_name, cond), d.con_values[ind, t, cond_id], timepoint) finalize_fcurves(cur_obj)
def create_conncection_per_condition(d, layers_rods, indices, mask, windows_num, norm_fac, T, radius): N = len(indices) parent_obj = bpy.data.objects[get_connections_parent_name()] print('Create connections for both conditions') con_color = (1, 1, 1, 1) now = time.time() for run, (ind, conn_name, (i, j)) in enumerate(zip(indices, d.con_names[mask], d.con_indices[mask])): mu.time_to_go(now, run, N, runs_num_to_print=10) p1, p2 = d.locations[i, :] * 0.1, d.locations[j, :] * 0.1 mu.cylinder_between(p1, p2, radius, layers_rods) mu.create_material('{}_mat'.format(conn_name), con_color, 1) cur_obj = bpy.context.active_object cur_obj.name = conn_name cur_obj.parent = parent_obj # cur_obj.animation_data_clear() if windows_num == 1: continue for cond_id, cond in enumerate(d.conditions): # insert_frame_keyframes(cur_obj, '{}-{}'.format(conn_name, cond), d.con_values[ind, -1, cond_id], T) for t in range(windows_num): extra_time_points = 0 if norm_fac == 1 else 2 timepoint = t * norm_fac + extra_time_points mu.insert_keyframe_to_custom_prop(cur_obj, '{}-{}'.format(conn_name, cond), d.con_values[ind, t, cond_id], timepoint) fcurve = cur_obj.animation_data.action.fcurves[cond_id] fcurve.keyframe_points[0].co[1] = 0 fcurve.keyframe_points[-1].co[1] = 0 finalize_fcurves(cur_obj) mu.change_fcurves_colors(parent_obj.children)
def create_keyframes_for_parent_obj(d, indices, mask, windows_num, norm_fac, T, stat=STAT_DIFF): # Create keyframes for the parent obj (conditions diff) if windows_num == 1: return if stat not in [STAT_DIFF, STAT_AVG]: print("Wrong type of stat!") return parent_obj = bpy.data.objects[get_connections_parent_name()] stat_data = calc_stat_data(d.con_values, stat) N = len(indices) now = time.time() for run, (ind, conn_name) in enumerate(zip(indices, d.con_names[mask])): mu.time_to_go(now, run, N, runs_num_to_print=100) # insert_frame_keyframes(parent_obj, conn_name, stat_data[ind, -1], T) for t in range(windows_num): extra_time_points = 0 if norm_fac == 1 else 2 timepoint = t * norm_fac + extra_time_points mu.insert_keyframe_to_custom_prop(parent_obj, conn_name, stat_data[ind, t], timepoint) fcurve = parent_obj.animation_data.action.fcurves[run] fcurve.keyframe_points[0].co[1] = 0 fcurve.keyframe_points[-1].co[1] = 0 finalize_fcurves(parent_obj) finalize_objects_creations()
def add_data_to_electrodes_parent_obj(parent_obj, all_data, meta, stat=STAT_DIFF, window_len=None): # todo: merge with add_data_to_brain_parent_obj, same code parent_obj.animation_data_clear() sources = {} # for obj_name, data in zip(f['names'], f['data']): all_data_stat = meta['stat'] if 'stat' in meta else [None] * len(meta['names']) T = all_data.shape[1] if window_len is None or 'dt' not in meta else int(window_len / meta['dt']) for obj_name, data, data_stat in zip(meta['names'], all_data, all_data_stat): obj_name = obj_name.astype(str) if data_stat is None: if stat == STAT_AVG or data.shape[1] == 1: data_stat = np.squeeze(np.mean(data, axis=1)) elif stat == STAT_DIFF: data_stat = np.squeeze(np.diff(data, axis=1)) sources[obj_name] = data_stat sources_names = sorted(list(sources.keys())) N = len(sources_names) # T = DataMakerPanel.addon.get_max_time_steps() # len(sources[sources_names[0]]) + 2 now = time.time() for obj_counter, source_name in enumerate(sources_names): mu.time_to_go(now, obj_counter, N, runs_num_to_print=10) data = sources[source_name] mu.insert_keyframe_to_custom_prop(parent_obj, source_name, 0, 1) mu.insert_keyframe_to_custom_prop(parent_obj, source_name, 0, T + 2) for ind in range(T): mu.insert_keyframe_to_custom_prop(parent_obj, source_name, data[ind], ind + 2) fcurves = parent_obj.animation_data.action.fcurves[obj_counter] mod = fcurves.modifiers.new(type='LIMITS') print('Finished keyframing {}!!'.format(parent_obj.name))
def create_conncection_for_both_conditions(d, layers_rods, indices, mask, windows_num, norm_fac, T, radius): N = len(indices) parent_obj = bpy.data.objects[PARENT_OBJ] print('Create connections for both conditions') now = time.time() for run, (ind, conn_name, (i, j)) in enumerate( zip(indices, d.con_names[mask], d.con_indices[mask])): mu.time_to_go(now, run, N, runs_num_to_print=10) if d.con_colors.ndim == 3: con_color = np.hstack((d.con_colors[ind, 0, :], [0.])) else: con_color = np.hstack((d.con_colors[ind, :], [0.])) p1, p2 = d.locations[i, :] * 0.1, d.locations[j, :] * 0.1 mu.cylinder_between(p1, p2, radius, layers_rods) # mu.create_material('{}_mat'.format(conn_name), (0, 0, 1, 1), 1) mu.create_material('{}_mat'.format(conn_name), con_color, 1) cur_obj = bpy.context.active_object cur_obj.name = conn_name cur_obj.parent = parent_obj # cur_obj.animation_data_clear() if windows_num == 1: continue for cond_id, cond in enumerate(d.conditions): # insert_frame_keyframes(cur_obj, '{}-{}'.format(conn_name, cond), d.con_values[ind, -1, cond_id], T) for t in range(windows_num): extra_time_points = 0 if norm_fac == 1 else 2 timepoint = t * norm_fac + extra_time_points mu.insert_keyframe_to_custom_prop( cur_obj, '{}-{}'.format(conn_name, cond), d.con_values[ind, t, cond_id], timepoint) finalize_fcurves(cur_obj)
def add_data_to_electrodes(all_data, meta_data, window_len=None): print('Adding data to Electrodes') now = time.time() N = len(meta_data['names']) T = all_data.shape[1] if window_len is None or not 'dt' in meta_data else int(window_len / meta_data['dt']) for obj_counter, (obj_name, data) in enumerate(zip(meta_data['names'], all_data)): mu.time_to_go(now, obj_counter, N, runs_num_to_print=10) obj_name = obj_name.astype(str) # print(obj_name) if bpy.data.objects.get(obj_name, None) is None: print("{} doesn't exist!".format(obj_name)) continue cur_obj = bpy.data.objects[obj_name] for cond_ind, cond_str in enumerate(meta_data['conditions']): cond_str = cond_str.astype(str) # Set the values to zeros in the first and last frame for current object(current label) mu.insert_keyframe_to_custom_prop(cur_obj, obj_name + '_' + cond_str, 0, 1) mu.insert_keyframe_to_custom_prop(cur_obj, obj_name + '_' + cond_str, 0, T + 2) print('keyframing ' + obj_name + ' object in condition ' + cond_str) # For every time point insert keyframe to current object for ind, timepoint in enumerate(data[:T, cond_ind]): mu.insert_keyframe_to_custom_prop(cur_obj, obj_name + '_' + str(cond_str), timepoint, ind + 2) # remove the orange keyframe sign in the fcurves window fcurves = bpy.data.objects[obj_name].animation_data.action.fcurves[cond_ind] mod = fcurves.modifiers.new(type='LIMITS') conditions = meta_data['conditions'] print('Finished keyframing!!') return conditions
def add_data_to_electrodes(source_files): print('Adding data to Electrodes') conditions = [] for input_file in source_files: # todo: we don't need to load this twice (also in add_data_to_electrodes_obj f = np.load(input_file) print('{} loaded'.format(input_file)) now = time.time() N = len(f['names']) for obj_counter, (obj_name, data) in enumerate(zip(f['names'], f['data'])): mu.time_to_go(now, obj_counter, N, runs_num_to_print=10) obj_name = obj_name.astype(str) # print(obj_name) if bpy.data.objects.get(obj_name, None) is None: print("{} doesn't exist!".format(obj_name)) continue cur_obj = bpy.data.objects[obj_name] for cond_ind, cond_str in enumerate(f['conditions']): cond_str = cond_str.astype(str) # Set the values to zeros in the first and last frame for current object(current label) mu.insert_keyframe_to_custom_prop(cur_obj, obj_name + '_' + cond_str, 0, 1) mu.insert_keyframe_to_custom_prop(cur_obj, obj_name + '_' + cond_str, 0, len(f['data'][0]) + 2) print('keyframing ' + obj_name + ' object in condition ' + cond_str) # For every time point insert keyframe to current object for ind, timepoint in enumerate(data[:, cond_ind]): mu.insert_keyframe_to_custom_prop(cur_obj, obj_name + '_' + str(cond_str), timepoint, ind + 2) # remove the orange keyframe sign in the fcurves window fcurves = bpy.data.objects[obj_name].animation_data.action.fcurves[cond_ind] mod = fcurves.modifiers.new(type='LIMITS') conditions.extend(f['conditions']) print('Finished keyframing!!') return conditions
def import_hemis_for_functional_maps(base_path): mu.change_layer(_addon().BRAIN_EMPTY_LAYER) layers_array = bpy.context.scene.layers emptys_names = [ 'Functional maps', 'Subcortical_meg_activity_map', 'Subcortical_fmri_activity_map' ] for name in emptys_names: create_empty_if_doesnt_exists(name, _addon().BRAIN_EMPTY_LAYER, layers_array, 'Functional maps') # for ii in range(len(bpy.context.scene.layers)): # bpy.context.scene.layers[ii] = (ii == brain_layer) print("importing Hemispheres") # # for cur_val in bpy.context.scene.layers: # # print(cur_val) # print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~") now = time.time() ply_files = glob.glob(op.join(base_path, 'surf', '*.ply')) N = len(ply_files) for ind, ply_fname in enumerate(ply_files): mu.time_to_go(now, ind, N, 10) bpy.ops.object.select_all(action='DESELECT') obj_name = mu.namebase(ply_fname).split(sep='.')[0] surf_name = mu.namebase(ply_fname).split(sep='.')[1] if surf_name == 'inflated': obj_name = '{}_{}'.format(surf_name, obj_name) mu.change_layer(_addon().INFLATED_ACTIVITY_LAYER) elif surf_name == 'pial': mu.change_layer(_addon().ACTIVITY_LAYER) else: raise Exception( 'The surface type {} is not supported!'.format(surf_name)) if bpy.data.objects.get(obj_name) is None: bpy.ops.import_mesh.ply( filepath=op.join(base_path, 'surf', ply_fname)) cur_obj = bpy.context.selected_objects[0] cur_obj.select = True bpy.ops.object.shade_smooth() cur_obj.scale = [0.1] * 3 cur_obj.hide = False cur_obj.name = obj_name if surf_name == 'inflated': cur_obj.active_material = bpy.data.materials[ 'Inflated_Activity_map_mat'] cur_obj.location[ 0] += 5.5 if obj_name == 'inflated_rh' else -5.5 else: cur_obj.active_material = bpy.data.materials[ 'Activity_map_mat'] cur_obj.parent = bpy.data.objects["Functional maps"] cur_obj.hide_select = True cur_obj.data.vertex_colors.new() else: print('{} already exists'.format(ply_fname)) _addon().create_inflated_curv_coloring() bpy.ops.object.select_all(action='DESELECT')
def add_data_to_parent_obj(parent_obj, source_files, stat, self=None): sources = {} parent_obj.animation_data_clear() for input_file in source_files: if not op.isfile(input_file): print(self, "Can't load file {}!".format(input_file)) continue print('loading {}'.format(input_file)) f = np.load(input_file) for obj_name, data in zip(f['names'], f['data']): obj_name = obj_name.astype(str) # Check if there is only one condition if data.shape[1] == 1: stat = STAT_AVG if bpy.data.objects.get(obj_name) is None: if obj_name.startswith('rh') or obj_name.startswith('lh'): obj_name = obj_name[3:] if bpy.data.objects.get(obj_name) is None: continue if not bpy.context.scene.import_unknown and 'unkown' in obj_name: continue if stat == STAT_AVG: data_stat = np.squeeze(np.mean(data, axis=1)) elif stat == STAT_DIFF: data_stat = np.squeeze(np.diff(data, axis=1)) else: data_stat = data sources[obj_name] = data_stat if len(sources) == 0: print('No sources in {}'.format(source_files)) return sources_names = sorted(list(sources.keys())) N = len(sources_names) T = len(sources[sources_names[0]]) + 2 now = time.time() for obj_counter, source_name in enumerate(sources_names): mu.time_to_go(now, obj_counter, N, runs_num_to_print=10) data = sources[source_name] # Set the values to zeros in the first and last frame for Brain object mu.insert_keyframe_to_custom_prop(parent_obj, source_name, 0, 1) mu.insert_keyframe_to_custom_prop(parent_obj, source_name, 0, T) # For every time point insert keyframe to the main Brain object # If you want to delete prints make sure no sleep is needed # print('keyframing Brain object {}'.format(obj_name)) for ind in range(data.shape[0]): # if len(data[ind]) == 2: # print('keyframing Brain object') mu.insert_keyframe_to_custom_prop(parent_obj, source_name, data[ind], ind + 2) # print('keyframed') # remove the orange keyframe sign in the fcurves window fcurves = parent_obj.animation_data.action.fcurves[obj_counter] mod = fcurves.modifiers.new(type='LIMITS') if bpy.data.objects.get(' '): bpy.context.scene.objects.active = bpy.data.objects[' '] print('Finished keyframing the brain parent obj!!')
def import_hemis_for_functional_maps(base_path): mu.change_layer(_addon().BRAIN_EMPTY_LAYER) layers_array = bpy.context.scene.layers emptys_names = ['Functional maps', 'Subcortical_meg_activity_map', 'Subcortical_fmri_activity_map'] for name in emptys_names: create_empty_if_doesnt_exists(name, _addon().BRAIN_EMPTY_LAYER, layers_array, 'Functional maps') # for ii in range(len(bpy.context.scene.layers)): # bpy.context.scene.layers[ii] = (ii == brain_layer) print("importing Hemispheres") # # for cur_val in bpy.context.scene.layers: # # print(cur_val) # print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~") now = time.time() ply_files = glob.glob(op.join(base_path, 'surf', '*.ply')) N = len(ply_files) for ind, ply_fname in enumerate(ply_files): try: mu.time_to_go(now, ind, N, 10) bpy.ops.object.select_all(action='DESELECT') obj_name = mu.namebase(ply_fname).split(sep='.')[0] surf_name = mu.namebase(ply_fname).split(sep='.')[1] if surf_name == 'inflated': obj_name = '{}_{}'.format(surf_name, obj_name) mu.change_layer(_addon().INFLATED_ACTIVITY_LAYER) elif surf_name == 'pial': mu.change_layer(_addon().ACTIVITY_LAYER) else: raise Exception('The surface type {} is not supported!'.format(surf_name)) if bpy.data.objects.get(obj_name) is None: bpy.ops.import_mesh.ply(filepath=op.join(base_path, 'surf', ply_fname)) cur_obj = bpy.context.selected_objects[0] cur_obj.select = True bpy.ops.object.shade_smooth() cur_obj.scale = [0.1] * 3 cur_obj.hide = False cur_obj.name = obj_name if surf_name == 'inflated': cur_obj.active_material = bpy.data.materials['Inflated_Activity_map_mat'] cur_obj.location[0] += 5.5 if obj_name == 'inflated_rh' else -5.5 else: cur_obj.active_material = bpy.data.materials['Activity_map_mat'] cur_obj.parent = bpy.data.objects["Functional maps"] cur_obj.hide_select = True cur_obj.data.vertex_colors.new() # else: # print('{} already exists'.format(ply_fname)) except: print('Error in importing {}'.format(ply_fname)) _addon().create_inflated_curv_coloring() bpy.ops.object.select_all(action='DESELECT')
def init_electrodes_animation(window_length=2500): parent_obj = bpy.data.objects['Deep_electrodes'] # T = _addon().get_max_time_steps() N = len(parent_obj.children) now = time.time() for obj_counter, source_obj in enumerate(parent_obj.children): mu.time_to_go(now, obj_counter, N, runs_num_to_print=10) source_name = source_obj.name mu.insert_keyframe_to_custom_prop(parent_obj, source_name, 0, 1) mu.insert_keyframe_to_custom_prop(parent_obj, source_name, 0, window_length + 2) for ind in range(window_length): mu.insert_keyframe_to_custom_prop(parent_obj, source_name, 0.1, ind + 2) fcurves = parent_obj.animation_data.action.fcurves[obj_counter] mod = fcurves.modifiers.new(type='LIMITS')
def plot_pathway(self, context, layers_dti, pathway_name, pathway_type): if pathway_type == TRACULA: pkl_fname = op.join(SUBJECT_DTI_FOL, TRACULA, '{}{}.pkl'.format(pathway_name, TRACULA_POSTFIX)) mu.create_empty_if_doesnt_exists(pathway_name, DTIPanel.addon.CONNECTIONS_LAYER, None, PARENT_OBJ) parent_obj = bpy.data.objects[pathway_name] tracks = mu.load(pkl_fname) N = len(tracks) now = time.time() for ind, track in enumerate(tracks[:1000]): mu.time_to_go(now, ind, N, 100) track = track * 0.1 # pprint(track) cur_obj = mu.create_spline(track, layers_dti, bevel_depth=0.01) # cur_obj.scale = [0.1] * 3 cur_obj.name = '{}_{}'.format(pathway_name, ind) cur_obj.parent = parent_obj
def add_data_to_electrodes_parent_obj(parent_obj, input_file, meta_file=None, stat=STAT_DIFF): # todo: merge with add_data_to_brain_parent_obj, same code parent_obj.animation_data_clear() sources = {} if not op.isfile(input_file): raise Exception("Can't load file {}!".format(input_file)) print('loading {}'.format(input_file)) if meta_file is None: f = np.load(input_file) data = f['data'] else: f = np.load(meta_file) data = np.load(input_file) # for obj_name, data in zip(f['names'], f['data']): all_data_stat = f['stat'] if 'stat' in f else [None] * len(f['names']) for obj_name, data, data_stat in zip(f['names'], data, all_data_stat): obj_name = obj_name.astype(str) if data_stat is None: if stat == STAT_AVG: data_stat = np.squeeze(np.mean(data, axis=1)) elif stat == STAT_DIFF: data_stat = np.squeeze(np.diff(data, axis=1)) sources[obj_name] = data_stat sources_names = sorted(list(sources.keys())) N = len(sources_names) T = DataMakerPanel.addon.get_max_time_steps( ) # len(sources[sources_names[0]]) + 2 now = time.time() for obj_counter, source_name in enumerate(sources_names): mu.time_to_go(now, obj_counter, N, runs_num_to_print=10) data = sources[source_name] mu.insert_keyframe_to_custom_prop(parent_obj, source_name, 0, 1) mu.insert_keyframe_to_custom_prop(parent_obj, source_name, 0, T + 2) for ind in range(data.shape[0]): mu.insert_keyframe_to_custom_prop(parent_obj, source_name, data[ind], ind + 2) fcurves = parent_obj.animation_data.action.fcurves[obj_counter] mod = fcurves.modifiers.new(type='LIMITS') print('Finished keyframing {}!!'.format(parent_obj.name))
def add_data_to_electrodes(input_file, meta_file=None): print('Adding data to Electrodes') conditions = [] # todo: we don't need to load this twice (also in add_data_to_electrodes_obj if meta_file is None: f = np.load(input_file) data = f['data'] else: data = np.load(input_file) f = np.load(meta_file) print('{} loaded'.format(input_file)) now = time.time() N = len(f['names']) for obj_counter, (obj_name, data) in enumerate(zip(f['names'], data)): mu.time_to_go(now, obj_counter, N, runs_num_to_print=10) obj_name = obj_name.astype(str) # print(obj_name) if bpy.data.objects.get(obj_name, None) is None: print("{} doesn't exist!".format(obj_name)) continue cur_obj = bpy.data.objects[obj_name] for cond_ind, cond_str in enumerate(f['conditions']): cond_str = cond_str.astype(str) # Set the values to zeros in the first and last frame for current object(current label) mu.insert_keyframe_to_custom_prop(cur_obj, obj_name + '_' + cond_str, 0, 1) mu.insert_keyframe_to_custom_prop(cur_obj, obj_name + '_' + cond_str, 0, len(data[0]) + 2) print('keyframing ' + obj_name + ' object in condition ' + cond_str) # For every time point insert keyframe to current object for ind, timepoint in enumerate(data[:, cond_ind]): mu.insert_keyframe_to_custom_prop( cur_obj, obj_name + '_' + str(cond_str), timepoint, ind + 2) # remove the orange keyframe sign in the fcurves window fcurves = bpy.data.objects[obj_name].animation_data.action.fcurves[ cond_ind] mod = fcurves.modifiers.new(type='LIMITS') conditions = f['conditions'] print('Finished keyframing!!') return conditions
def create_keyframes_for_parent_obj(d, indices, mask, windows_num, norm_fac, T, stat=STAT_DIFF): # Create keyframes for the parent obj (conditions diff) if windows_num == 1: return if stat not in [STAT_DIFF, STAT_AVG]: print("Wrong type of stat!") return parent_obj = bpy.data.objects[PARENT_OBJ] stat_data = calc_stat_data(d.con_values, stat) N = len(indices) now = time.time() for run, (ind, conn_name) in enumerate(zip(indices, d.con_names[mask])): mu.time_to_go(now, run, N, runs_num_to_print=100) # insert_frame_keyframes(parent_obj, conn_name, stat_data[ind, -1], T) for t in range(windows_num): extra_time_points = 0 if norm_fac ==1 else 2 timepoint = t * norm_fac + extra_time_points mu.insert_keyframe_to_custom_prop(parent_obj, conn_name, stat_data[ind, t], timepoint) finalize_fcurves(parent_obj) finalize_objects_creations()
def add_data_to_electrodes_parent_obj(self, parent_obj, source_files, stat): # todo: merge with add_data_to_brain_parent_obj, same code parent_obj.animation_data_clear() sources = {} for input_file in source_files: if not op.isfile(input_file): self.report({'ERROR'}, "Can't load file {}!".format(input_file)) continue print('loading {}'.format(input_file)) f = np.load(input_file) # for obj_name, data in zip(f['names'], f['data']): all_data_stat = f['stat'] if 'stat' in f else [None] * len(f['names']) for obj_name, data, data_stat in zip(f['names'], f['data'], all_data_stat): obj_name = obj_name.astype(str) if data_stat is None: if stat == STAT_AVG: data_stat = np.squeeze(np.mean(data, axis=1)) elif stat == STAT_DIFF: data_stat = np.squeeze(np.diff(data, axis=1)) sources[obj_name] = data_stat sources_names = sorted(list(sources.keys())) N = len(sources_names) T = DataMakerPanel.addon.get_max_time_steps() # len(sources[sources_names[0]]) + 2 now = time.time() for obj_counter, source_name in enumerate(sources_names): mu.time_to_go(now, obj_counter, N, runs_num_to_print=10) data = sources[source_name] mu.insert_keyframe_to_custom_prop(parent_obj, source_name, 0, 1) mu.insert_keyframe_to_custom_prop(parent_obj, source_name, 0, T + 2) for ind in range(data.shape[0]): mu.insert_keyframe_to_custom_prop(parent_obj, source_name, data[ind], ind + 2) fcurves = parent_obj.animation_data.action.fcurves[obj_counter] mod = fcurves.modifiers.new(type='LIMITS') print('Finished keyframing {}!!'.format(parent_obj.name))