Exemplo n.º 1
0
static int type_toggle_exec(bContext *C, wmOperator *op)
{

	Object *cObject = ED_object_context(C);
	Scene *scene = CTX_data_scene(C);
	DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)modifiers_findByType(cObject, eModifierType_DynamicPaint);
	int type = RNA_enum_get(op->ptr, "type");

	if (!pmd) return OPERATOR_CANCELLED;

	/* if type is already enabled, toggle it off */
	if (type == MOD_DYNAMICPAINT_TYPE_CANVAS && pmd->canvas) {
			dynamicPaint_freeCanvas(pmd);
	}
	else if (type == MOD_DYNAMICPAINT_TYPE_BRUSH && pmd->brush) {
			dynamicPaint_freeBrush(pmd);
	}
	/* else create a new type */
	else {
		if (!dynamicPaint_createType(pmd, type, scene))
			return OPERATOR_CANCELLED;
	}
	
	/* update dependency */
	DAG_id_tag_update(&cObject->id, OB_RECALC_DATA);
	DAG_relations_tag_update(CTX_data_main(C));
	WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, cObject);

	return OPERATOR_FINISHED;
}
Exemplo n.º 2
0
static int outliner_animdata_operation_exec(bContext *C, wmOperator *op)
{
	SpaceOops *soops = CTX_wm_space_outliner(C);
	int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
	eOutliner_AnimDataOps event;
	short updateDeps = 0;
	
	/* check for invalid states */
	if (soops == NULL)
		return OPERATOR_CANCELLED;
	
	event = RNA_enum_get(op->ptr, "type");
	set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel);
	
	if (datalevel != TSE_ANIM_DATA)
		return OPERATOR_CANCELLED;
	
	/* perform the core operation */
	switch (event) {
		case OUTLINER_ANIMOP_SET_ACT:
			/* delegate once again... */
			WM_operator_name_call(C, "OUTLINER_OT_action_set", WM_OP_INVOKE_REGION_WIN, NULL);
			break;
		
		case OUTLINER_ANIMOP_CLEAR_ACT:
			/* clear active action - using standard rules */
			outliner_do_data_operation(soops, datalevel, event, &soops->tree, unlinkact_animdata_cb, NULL);
			
			WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL);
			ED_undo_push(C, "Unlink action");
			break;
			
		case OUTLINER_ANIMOP_REFRESH_DRV:
			outliner_do_data_operation(soops, datalevel, event, &soops->tree, refreshdrivers_animdata_cb, NULL);
			
			WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN, NULL);
			//ED_undo_push(C, "Refresh Drivers"); /* no undo needed - shouldn't have any impact? */
			updateDeps = 1;
			break;
			
		case OUTLINER_ANIMOP_CLEAR_DRV:
			outliner_do_data_operation(soops, datalevel, event, &soops->tree, cleardrivers_animdata_cb, NULL);
			
			WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN, NULL);
			ED_undo_push(C, "Clear Drivers");
			updateDeps = 1;
			break;
			
		default: // invalid
			break;
	}
	
	/* update dependencies */
	if (updateDeps) {
		/* rebuild depsgraph for the new deps */
		DAG_relations_tag_update(CTX_data_main(C));
	}
	
	return OPERATOR_FINISHED;
}
Exemplo n.º 3
0
static int rule_del_exec(bContext *C, wmOperator *UNUSED(op))
{
	Main *bmain = CTX_data_main(C);
	PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_settings", &RNA_ParticleSettings);
	ParticleSettings *part = ptr.data;
	BoidRule *rule;
	BoidState *state;

	if (!part || part->phystype != PART_PHYS_BOIDS)
		return OPERATOR_CANCELLED;

	state = boid_get_current_state(part->boids);

	for (rule=state->rules.first; rule; rule=rule->next) {
		if (rule->flag & BOIDRULE_CURRENT) {
			BLI_remlink(&state->rules, rule);
			MEM_freeN(rule);
			break;
		}
	}
	rule = state->rules.first;

	if (rule)
		rule->flag |= BOIDRULE_CURRENT;

	DAG_relations_tag_update(bmain);
	DAG_id_tag_update(&part->id, OB_RECALC_DATA|PSYS_RECALC_RESET);

	return OPERATOR_FINISHED;
}
static int new_particle_target_exec(bContext *C, wmOperator *UNUSED(op))
{
	Main *bmain = CTX_data_main(C);
	PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
	ParticleSystem *psys= ptr.data;
	Object *ob = ptr.id.data;

	ParticleTarget *pt;

	if (!psys)
		return OPERATOR_CANCELLED;

	pt = psys->targets.first;
	for (; pt; pt=pt->next)
		pt->flag &= ~PTARGET_CURRENT;

	pt = MEM_callocN(sizeof(ParticleTarget), "keyed particle target");

	pt->flag |= PTARGET_CURRENT;
	pt->psys = 1;

	BLI_addtail(&psys->targets, pt);

	DAG_relations_tag_update(bmain);
	DAG_id_tag_update(&ob->id, OB_RECALC_DATA);

	WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob);
	
	return OPERATOR_FINISHED;
}
static int remove_particle_target_exec(bContext *C, wmOperator *UNUSED(op))
{
	Main *bmain = CTX_data_main(C);
	PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
	ParticleSystem *psys= ptr.data;
	Object *ob = ptr.id.data;

	ParticleTarget *pt;

	if (!psys)
		return OPERATOR_CANCELLED;

	pt = psys->targets.first;
	for (; pt; pt=pt->next) {
		if (pt->flag & PTARGET_CURRENT) {
			BLI_remlink(&psys->targets, pt);
			MEM_freeN(pt);
			break;
		}

	}
	pt = psys->targets.last;

	if (pt)
		pt->flag |= PTARGET_CURRENT;

	DAG_relations_tag_update(bmain);
	DAG_id_tag_update(&ob->id, OB_RECALC_DATA);

	WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob);
	
	return OPERATOR_FINISHED;
}
Exemplo n.º 6
0
static int remove_driver_button_exec(bContext *C, wmOperator *op)
{
	PointerRNA ptr = {{NULL}};
	PropertyRNA *prop = NULL;
	short success = 0;
	int index;
	const bool all = RNA_boolean_get(op->ptr, "all");
	
	/* try to find driver using property retrieved from UI */
	UI_context_active_but_prop_get(C, &ptr, &prop, &index);
	
	if (all)
		index = -1;
	
	if (ptr.id.data && ptr.data && prop) {
		char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL);
		
		if (path) {
			success = ANIM_remove_driver(op->reports, ptr.id.data, path, index, 0);

			MEM_freeN(path);
		}
	}
	
	if (success) {
		/* send updates */
		UI_context_update_anim_flag(C);
		DAG_relations_tag_update(CTX_data_main(C));
		WM_event_add_notifier(C, NC_ANIMATION | ND_FCURVES_ORDER, NULL);  // XXX
	}
	
	return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
static int new_particle_settings_exec(bContext *C, wmOperator *UNUSED(op))
{
	Main *bmain= CTX_data_main(C);
	ParticleSystem *psys;
	ParticleSettings *part = NULL;
	Object *ob;
	PointerRNA ptr;

	ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);

	psys = ptr.data;

	/* add or copy particle setting */
	if (psys->part)
		part= BKE_particlesettings_copy(psys->part);
	else
		part= psys_new_settings("ParticleSettings", bmain);

	ob= ptr.id.data;

	if (psys->part)
		psys->part->id.us--;

	psys->part = part;

	psys_check_boid_data(psys);

	DAG_relations_tag_update(bmain);
	DAG_id_tag_update(&ob->id, OB_RECALC_DATA);

	WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE, ob);
	
	return OPERATOR_FINISHED;
}
Exemplo n.º 8
0
/* Wrapper for creating a driver without knowing what the targets will be yet (i.e. "manual/add later") */
static int add_driver_button_none(bContext *C, wmOperator *op, short mapping_type)
{
	PointerRNA ptr = {{NULL}};
	PropertyRNA *prop = NULL;
	int index;
	int success = 0;
	
	UI_context_active_but_prop_get(C, &ptr, &prop, &index);
	
	if (mapping_type == CREATEDRIVER_MAPPING_NONE_ALL)
		index = -1;
	
	if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
		char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL);
		short flags = CREATEDRIVER_WITH_DEFAULT_DVAR;
		
		if (path) {
			success += ANIM_add_driver(op->reports, ptr.id.data, path, index, flags, DRIVER_TYPE_PYTHON);
			MEM_freeN(path);
		}
	}
	
	if (success) {
		/* send updates */
		UI_context_update_anim_flag(C);
		DAG_relations_tag_update(CTX_data_main(C));
		WM_event_add_notifier(C, NC_ANIMATION | ND_FCURVES_ORDER, NULL);  // XXX
		
		return OPERATOR_FINISHED;
	}
	else {
		return OPERATOR_CANCELLED;
	}
}
Exemplo n.º 9
0
static int state_del_exec(bContext *C, wmOperator *UNUSED(op))
{
	Main *bmain = CTX_data_main(C);
	PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_settings", &RNA_ParticleSettings);
	ParticleSettings *part = ptr.data;
	BoidState *state;

	if (!part || part->phystype != PART_PHYS_BOIDS)
		return OPERATOR_CANCELLED;

	for (state=part->boids->states.first; state; state=state->next) {
		if (state->flag & BOIDSTATE_CURRENT) {
			BLI_remlink(&part->boids->states, state);
			MEM_freeN(state);
			break;
		}
	}

	/* there must be at least one state */
	if (!part->boids->states.first) {
		state = boid_new_state(part->boids);
		BLI_addtail(&part->boids->states, state);
	}
	else
		state = part->boids->states.first;

	state->flag |= BOIDSTATE_CURRENT;

	DAG_relations_tag_update(bmain);
	DAG_id_tag_update(&part->id, OB_RECALC_DATA|PSYS_RECALC_RESET);
	
	return OPERATOR_FINISHED;
}
Exemplo n.º 10
0
/* Tag pose for recalc. Also tag all related data to be recalc. */
void BKE_pose_tag_recalc(Main *bmain, bPose *pose)
{
	pose->flag |= POSE_RECALC;
	/* Depsgraph components depends on actual pose state,
	 * if pose was changed depsgraph is to be updated as well.
	 */
	DAG_relations_tag_update(bmain);
}
Exemplo n.º 11
0
static void rna_Depsgraph_debug_rebuild(Depsgraph *UNUSED(graph), Main *bmain)
{
	Scene *sce;
	DAG_relations_tag_update(bmain);
	for (sce = bmain->scene.first; sce; sce = sce->id.next) {
		DAG_scene_relations_rebuild(bmain, sce);
		DEG_graph_on_visible_update(bmain, sce);
	}
}
void ED_rigidbody_object_remove(Main *bmain, Scene *scene, Object *ob)
{
	RigidBodyWorld *rbw = BKE_rigidbody_get_world(scene);

	BKE_rigidbody_remove_object(scene, ob);
	if (rbw)
		BKE_group_object_unlink(rbw->group, ob, scene, NULL);

	DAG_relations_tag_update(bmain);
	DAG_id_tag_update(&ob->id, OB_RECALC_OB);
}
Exemplo n.º 13
0
static int shape_key_add_exec(bContext *C, wmOperator *op)
{
	Object *ob = ED_object_context(C);
	const bool from_mix = RNA_boolean_get(op->ptr, "from_mix");

	ED_object_shape_key_add(C, ob, from_mix);

	DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
	DAG_relations_tag_update(CTX_data_main(C));

	return OPERATOR_FINISHED;
}
Exemplo n.º 14
0
static int outliner_group_operation_exec(bContext *C, wmOperator *op)
{
	Scene *scene = CTX_data_scene(C);
	SpaceOops *soops = CTX_wm_space_outliner(C);
	int event;
	
	/* check for invalid states */
	if (soops == NULL)
		return OPERATOR_CANCELLED;
	
	event = RNA_enum_get(op->ptr, "type");

	switch (event) {
		case OL_GROUPOP_UNLINK:
			outliner_do_libdata_operation(C, scene, soops, &soops->tree, unlink_group_cb);
			break;
		case OL_GROUPOP_LOCAL:
			outliner_do_libdata_operation(C, scene, soops, &soops->tree, id_local_cb);
			break;
		case OL_GROUPOP_LINK:
			outliner_do_libdata_operation(C, scene, soops, &soops->tree, group_linkobs2scene_cb);
			break;
		case OL_GROUPOP_INSTANCE:
			outliner_do_libdata_operation(C, scene, soops, &soops->tree, group_instance_cb);
			break;
		case OL_GROUPOP_TOGVIS:
			outliner_do_libdata_operation(C, scene, soops, &soops->tree, group_toggle_visibility_cb);
			break;
		case OL_GROUPOP_TOGSEL:
			outliner_do_libdata_operation(C, scene, soops, &soops->tree, group_toggle_selectability_cb);
			break;
		case OL_GROUPOP_TOGREN:
			outliner_do_libdata_operation(C, scene, soops, &soops->tree, group_toggle_renderability_cb);
			break;
		case OL_GROUPOP_RENAME:
			outliner_do_libdata_operation(C, scene, soops, &soops->tree, item_rename_cb);
			break;
		default:
			BLI_assert(0);
	}

	if (event == 3) { /* instance */
		/* works without this except if you try render right after, see: 22027 */
		DAG_relations_tag_update(CTX_data_main(C));
	}

	ED_undo_push(C, prop_group_op_types[event - 1].name);
	WM_event_add_notifier(C, NC_GROUP, NULL);

	return OPERATOR_FINISHED;
}
Exemplo n.º 15
0
static int objects_add_active_exec(bContext *C, wmOperator *op)
{
	Object *ob = ED_object_context(C);
	Main *bmain = CTX_data_main(C);
	Scene *scene = CTX_data_scene(C);
	int single_group_index = RNA_enum_get(op->ptr, "group");
	Group *single_group = group_object_active_find_index(ob, single_group_index);
	Group *group;
	bool is_cycle = false;
	bool updated = false;

	if (ob == NULL)
		return OPERATOR_CANCELLED;

	/* now add all selected objects to the group(s) */
	for (group = bmain->group.first; group; group = group->id.next) {
		if (single_group && group != single_group)
			continue;
		if (!BKE_group_object_exists(group, ob))
			continue;

		/* for recursive check */
		BKE_main_id_tag_listbase(&bmain->group, true);

		CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
		{
			if (group_link_early_exit_check(group, base->object))
				continue;

			if (base->object->dup_group != group && !check_group_contains_object_recursive(group, base->object)) {
				BKE_group_object_add(group, base->object, scene, base);
				updated = true;
			}
			else {
				is_cycle = true;
			}
		}
		CTX_DATA_END;
	}

	if (is_cycle)
		BKE_report(op->reports, RPT_WARNING, "Skipped some groups because of cycle detected");

	if (!updated)
		return OPERATOR_CANCELLED;

	DAG_relations_tag_update(bmain);
	WM_event_add_notifier(C, NC_GROUP | NA_EDITED, NULL);

	return OPERATOR_FINISHED;
}
Exemplo n.º 16
0
/* return success (1) */
int BKE_copybuffer_paste(bContext *C, const char *libname, const short flag, ReportList *reports)
{
	Main *bmain = CTX_data_main(C);
	Scene *scene = CTX_data_scene(C);
	View3D *v3d = CTX_wm_view3d(C);
	Main *mainl = NULL;
	Library *lib;
	BlendHandle *bh;
		
	bh = BLO_blendhandle_from_file(libname, reports);
	
	if (bh == NULL) {
		/* error reports will have been made by BLO_blendhandle_from_file() */
		return 0;
	}

	BKE_scene_base_deselect_all(scene);
	
	/* tag everything, all untagged data can be made local
	 * its also generally useful to know what is new
	 *
	 * take extra care BKE_main_id_flag_all(bmain, LIB_TAG_PRE_EXISTING, false) is called after! */
	BKE_main_id_flag_all(bmain, LIB_TAG_PRE_EXISTING, true);
	
	/* here appending/linking starts */
	mainl = BLO_library_link_begin(bmain, &bh, libname);
	
	BLO_library_link_all(mainl, bh, flag, scene, v3d);

	BLO_library_link_end(mainl, &bh, flag, scene, v3d);
	
	/* mark all library linked objects to be updated */
	BKE_main_lib_objects_recalc_all(bmain);
	IMB_colormanagement_check_file_config(bmain);
	
	/* append, rather than linking */
	lib = BLI_findstring(&bmain->library, libname, offsetof(Library, filepath));
	BKE_library_make_local(bmain, lib, true, false);
	
	/* important we unset, otherwise these object wont
	 * link into other scenes from this blend file */
	BKE_main_id_flag_all(bmain, LIB_TAG_PRE_EXISTING, false);
	
	/* recreate dependency graph to include new objects */
	DAG_relations_tag_update(bmain);
	
	BLO_blendhandle_close(bh);
	/* remove library... */
	
	return 1;
}
Exemplo n.º 17
0
static void rna_Boids_reset_deps(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
{
    if (ptr->type == &RNA_ParticleSystem) {
        ParticleSystem *psys = (ParticleSystem *)ptr->data;

        psys->recalc = PSYS_RECALC_RESET;

        DAG_id_tag_update(ptr->id.data, OB_RECALC_DATA);
    }
    else
        DAG_id_tag_update(ptr->id.data, OB_RECALC_DATA | PSYS_RECALC_RESET);

    DAG_relations_tag_update(bmain);

    WM_main_add_notifier(NC_OBJECT | ND_PARTICLE | NA_EDITED, NULL);
}
Exemplo n.º 18
0
static void do_graph_region_driver_buttons(bContext *C, void *UNUSED(arg), int event)
{
	Main *bmain = CTX_data_main(C);
	Scene *scene = CTX_data_scene(C);
	
	switch (event) {
		case B_IPO_DEPCHANGE:
		{
			/* rebuild depsgraph for the new deps */
			DAG_relations_tag_update(bmain);
			break;
		}
	}
	
	/* default for now */
	WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); // XXX could use better notifier
}
Exemplo n.º 19
0
static void driverdropper_sample(bContext *C, wmOperator *op, const wmEvent *event)
{
	DriverDropper *ddr = (DriverDropper *)op->customdata;
	uiBut *but = eyedropper_get_property_button_under_mouse(C, event);
	
	short mapping_type = RNA_enum_get(op->ptr, "mapping_type");
	short flag = 0;
	
	/* we can only add a driver if we know what RNA property it corresponds to */
	if (but == NULL) {
		return;
	}
	else {
		/* Get paths for src... */
		PointerRNA *target_ptr = &but->rnapoin;
		PropertyRNA *target_prop = but->rnaprop;
		int target_index = but->rnaindex;
		
		char *target_path = RNA_path_from_ID_to_property(target_ptr, target_prop);
		
		/* ... and destination */
		char *dst_path    = BKE_animdata_driver_path_hack(C, &ddr->ptr, ddr->prop, NULL);
		
		/* Now create driver(s) */
		if (target_path && dst_path) {
			int success = ANIM_add_driver_with_target(op->reports,
			                                          ddr->ptr.id.data, dst_path, ddr->index,
			                                          target_ptr->id.data, target_path, target_index,
			                                          flag, DRIVER_TYPE_PYTHON, mapping_type);
			
			if (success) {
				/* send updates */
				UI_context_update_anim_flag(C);
				DAG_relations_tag_update(CTX_data_main(C));
				DAG_id_tag_update(ddr->ptr.id.data, OB_RECALC_OB | OB_RECALC_DATA);
				WM_event_add_notifier(C, NC_ANIMATION | ND_FCURVES_ORDER, NULL);  // XXX
			}
		}
		
		/* cleanup */
		if (target_path)
			MEM_freeN(target_path);
		if (dst_path)
			MEM_freeN(dst_path);
	}
}
Exemplo n.º 20
0
static int objects_add_active_exec(bContext *C, wmOperator *op)
{
	Object *ob = ED_object_context(C);
	Main *bmain = CTX_data_main(C);
	Scene *scene = CTX_data_scene(C);
	int group_object_index = RNA_enum_get(op->ptr, "group");
	int is_cycle = FALSE;

	if (ob) {
		Group *group = group_object_active_find_index(ob, group_object_index);

		/* now add all selected objects from the group */
		if (group) {

			/* for recursive check */
			tag_main_lb(&bmain->group, TRUE);

			CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases)
			{
				if (group_link_early_exit_check(group, base->object))
					continue;

				if (base->object->dup_group != group && !check_group_contains_object_recursive(group, base->object)) {
					BKE_group_object_add(group, base->object, scene, base);
				}
				else {
					is_cycle = TRUE;
				}
			}
			CTX_DATA_END;

			if (is_cycle) {
				BKE_report(op->reports, RPT_WARNING, "Skipped some groups because of cycle detected");
			}

			DAG_relations_tag_update(bmain);
			WM_event_add_notifier(C, NC_GROUP | NA_EDITED, NULL);

			return OPERATOR_FINISHED;
		}
	}

	return OPERATOR_CANCELLED;
}
Exemplo n.º 21
0
// a shortened version of parent_set_exec()
// if is_parent_space is true then ob->obmat will be multiplied by par->obmat before parenting
int bc_set_parent(Object *ob, Object *par, bContext *C, bool is_parent_space)
{
	Object workob;
	Scene *sce = CTX_data_scene(C);
	
	if (!par || bc_test_parent_loop(par, ob))
		return false;

	ob->parent = par;
	ob->partype = PAROBJECT;

	ob->parsubstr[0] = 0;

	if (is_parent_space) {
		float mat[4][4];
		// calc par->obmat
		BKE_object_where_is_calc(sce, par);

		// move child obmat into world space
		mul_m4_m4m4(mat, par->obmat, ob->obmat);
		copy_m4_m4(ob->obmat, mat);
	}
	
	// apply child obmat (i.e. decompose it into rot/loc/size)
	BKE_object_apply_mat4(ob, ob->obmat, 0, 0);

	// compute parentinv
	BKE_object_workob_calc_parent(sce, ob, &workob);
	invert_m4_m4(ob->parentinv, workob.obmat);

	DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA);
	DAG_id_tag_update(&par->id, OB_RECALC_OB);

	/** done once after import */
#if 0
	DAG_relations_tag_update(bmain);
	WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
#endif

	return true;
}
bool ED_rigidbody_object_add(Main *bmain, Scene *scene, Object *ob, int type, ReportList *reports)
{
	RigidBodyWorld *rbw = BKE_rigidbody_get_world(scene);

	if (ob->type != OB_MESH) {
		BKE_report(reports, RPT_ERROR, "Can't add Rigid Body to non mesh object");
		return false;
	}

	/* Add rigid body world and group if they don't exist for convenience */
	if (rbw == NULL) {
		rbw = BKE_rigidbody_create_world(scene);
		if (rbw == NULL) {
			BKE_report(reports, RPT_ERROR, "Can't create Rigid Body world");
			return false;
		}
		BKE_rigidbody_validate_sim_world(scene, rbw, false);
		scene->rigidbody_world = rbw;
	}
	if (rbw->group == NULL) {
		rbw->group = BKE_group_add(bmain, "RigidBodyWorld");
	}

	/* make rigidbody object settings */
	if (ob->rigidbody_object == NULL) {
		ob->rigidbody_object = BKE_rigidbody_create_object(scene, ob, type);
	}
	ob->rigidbody_object->type = type;
	ob->rigidbody_object->flag |= RBO_FLAG_NEEDS_VALIDATE;

	/* add object to rigid body group */
	BKE_group_object_add(rbw->group, ob, scene, NULL);

	DAG_relations_tag_update(bmain);
	DAG_id_tag_update(&ob->id, OB_RECALC_OB);

	return true;
}
Exemplo n.º 23
0
static int shape_key_remove_exec(bContext *C, wmOperator *op)
{
	Main *bmain = CTX_data_main(C);
	Object *ob = ED_object_context(C);
	bool changed = false;

	if (RNA_boolean_get(op->ptr, "all")) {
		changed = BKE_object_shapekey_free(bmain, ob);
	}
	else {
		changed = object_shapekey_remove(bmain, ob);
	}

	if (changed) {
		DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
		DAG_relations_tag_update(CTX_data_main(C));
		WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);

		return OPERATOR_FINISHED;
	}
	else {
		return OPERATOR_CANCELLED;
	}
}
Exemplo n.º 24
0
/**
 * Replace all references in given Main to \a old_id by \a new_id
 * (if \a new_id is NULL, it unlinks \a old_id).
 */
void BKE_libblock_remap_locked(
        Main *bmain, void *old_idv, void *new_idv,
        const short remap_flags)
{
	IDRemap id_remap_data;
	ID *old_id = old_idv;
	ID *new_id = new_idv;
	int skipped_direct, skipped_refcounted;

	BLI_assert(old_id != NULL);
	BLI_assert((new_id == NULL) || GS(old_id->name) == GS(new_id->name));
	BLI_assert(old_id != new_id);

	libblock_remap_data(bmain, NULL, old_id, new_id, remap_flags, &id_remap_data);

	if (free_notifier_reference_cb) {
		free_notifier_reference_cb(old_id);
	}

	/* We assume editors do not hold references to their IDs... This is false in some cases
	 * (Image is especially tricky here), editors' code is to handle refcount (id->us) itself then. */
	if (remap_editor_id_reference_cb) {
		remap_editor_id_reference_cb(old_id, new_id);
	}

	skipped_direct = id_remap_data.skipped_direct;
	skipped_refcounted = id_remap_data.skipped_refcounted;

	/* If old_id was used by some ugly 'user_one' stuff (like Image or Clip editors...), and user count has actually
	 * been incremented for that, we have to decrease once more its user count... unless we had to skip
	 * some 'user_one' cases. */
	if ((old_id->tag & LIB_TAG_EXTRAUSER_SET) && !(id_remap_data.status & ID_REMAP_IS_USER_ONE_SKIPPED)) {
		id_us_min(old_id);
		old_id->tag &= ~LIB_TAG_EXTRAUSER_SET;
	}

	BLI_assert(old_id->us - skipped_refcounted >= 0);
	UNUSED_VARS_NDEBUG(skipped_refcounted);

	if (skipped_direct == 0) {
		/* old_id is assumed to not be used directly anymore... */
		if (old_id->lib && (old_id->tag & LIB_TAG_EXTERN)) {
			old_id->tag &= ~LIB_TAG_EXTERN;
			old_id->tag |= LIB_TAG_INDIRECT;
		}
	}

	/* Some after-process updates.
	 * This is a bit ugly, but cannot see a way to avoid it. Maybe we should do a per-ID callback for this instead?
	 */
	switch (GS(old_id->name)) {
		case ID_OB:
			libblock_remap_data_postprocess_object_fromgroup_update(bmain, (Object *)old_id, (Object *)new_id);
			break;
		case ID_GR:
			if (!new_id) {  /* Only affects us in case group was unlinked. */
				for (Scene *sce = bmain->scene.first; sce; sce = sce->id.next) {
					libblock_remap_data_postprocess_group_scene_unlink(bmain, sce, old_id);
				}
			}
			break;
		case ID_ME:
		case ID_CU:
		case ID_MB:
			if (new_id) {  /* Only affects us in case obdata was relinked (changed). */
				for (Object *ob = bmain->object.first; ob; ob = ob->id.next) {
					libblock_remap_data_postprocess_obdata_relink(bmain, ob, new_id);
				}
			}
			break;
		default:
			break;
	}

	/* Full rebuild of DAG! */
	DAG_relations_tag_update(bmain);
}
Exemplo n.º 25
0
static int outliner_object_operation_exec(bContext *C, wmOperator *op)
{
	Main *bmain = CTX_data_main(C);
	Scene *scene = CTX_data_scene(C);
	SpaceOops *soops = CTX_wm_space_outliner(C);
	int event;
	const char *str = NULL;
	
	/* check for invalid states */
	if (soops == NULL)
		return OPERATOR_CANCELLED;
	
	event = RNA_enum_get(op->ptr, "type");

	if (event == OL_OP_SELECT) {
		Scene *sce = scene;  // to be able to delete, scenes are set...
		outliner_do_object_operation(C, scene, soops, &soops->tree, object_select_cb);
		if (scene != sce) {
			ED_screen_set_scene(C, CTX_wm_screen(C), sce);
		}
		
		str = "Select Objects";
		WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
	}
	else if (event == OL_OP_SELECT_HIERARCHY) {
		Scene *sce = scene;  // to be able to delete, scenes are set...
		outliner_do_object_operation(C, scene, soops, &soops->tree, object_select_hierarchy_cb);
		if (scene != sce) {
			ED_screen_set_scene(C, CTX_wm_screen(C), sce);
		}	
		str = "Select Object Hierarchy";
		WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
	}
	else if (event == OL_OP_DESELECT) {
		outliner_do_object_operation(C, scene, soops, &soops->tree, object_deselect_cb);
		str = "Deselect Objects";
		WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
	}
	else if (event == OL_OP_DELETE) {
		outliner_do_object_operation(C, scene, soops, &soops->tree, object_delete_cb);

		/* XXX: tree management normally happens from draw_outliner(), but when
		 *      you're clicking to fast on Delete object from context menu in
		 *      outliner several mouse events can be handled in one cycle without
		 *      handling notifiers/redraw which leads to deleting the same object twice.
		 *      cleanup tree here to prevent such cases. */
		outliner_cleanup_tree(soops);

		DAG_relations_tag_update(bmain);
		str = "Delete Objects";
		WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
	}
	else if (event == OL_OP_LOCALIZED) {    /* disabled, see above enum (ton) */
		outliner_do_object_operation(C, scene, soops, &soops->tree, id_local_cb);
		str = "Localized Objects";
	}
	else if (event == OL_OP_TOGVIS) {
		outliner_do_object_operation(C, scene, soops, &soops->tree, object_toggle_visibility_cb);
		str = "Toggle Visibility";
		WM_event_add_notifier(C, NC_SCENE | ND_OB_VISIBLE, scene);
	}
	else if (event == OL_OP_TOGSEL) {
		outliner_do_object_operation(C, scene, soops, &soops->tree, object_toggle_selectability_cb);
		str = "Toggle Selectability";
		WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
	}
	else if (event == OL_OP_TOGREN) {
		outliner_do_object_operation(C, scene, soops, &soops->tree, object_toggle_renderability_cb);
		str = "Toggle Renderability";
		WM_event_add_notifier(C, NC_SCENE | ND_OB_RENDER, scene);
	}
	else if (event == OL_OP_RENAME) {
		outliner_do_object_operation(C, scene, soops, &soops->tree, item_rename_cb);
		str = "Rename Object";
	}

	ED_undo_push(C, str);
	
	return OPERATOR_FINISHED;
}
Exemplo n.º 26
0
/* separate selected bones into their armature */
static int separate_armature_exec(bContext *C, wmOperator *UNUSED(op))
{
	Main *bmain = CTX_data_main(C);
	Scene *scene = CTX_data_scene(C);
	Object *obedit = CTX_data_edit_object(C);
	Object *oldob, *newob;
	Base *oldbase, *newbase;
	
	/* sanity checks */
	if (obedit == NULL)
		return OPERATOR_CANCELLED;
	
	/* set wait cursor in case this takes a while */
	WM_cursor_wait(1);
	
	/* we are going to do this as follows (unlike every other instance of separate):
	 *	1. exit editmode +posemode for active armature/base. Take note of what this is.
	 *	2. duplicate base - BASACT is the new one now
	 *	3. for each of the two armatures, enter editmode -> remove appropriate bones -> exit editmode + recalc
	 *	4. fix constraint links
	 *	5. make original armature active and enter editmode
	 */

	/* 1) only edit-base selected */
	/* TODO: use context iterators for this? */
	CTX_DATA_BEGIN(C, Base *, base, visible_bases)
	{
		if (base->object == obedit) base->flag |= 1;
		else base->flag &= ~1;
	}
	CTX_DATA_END;
	
	/* 1) store starting settings and exit editmode */
	oldob = obedit;
	oldbase = BASACT;
	oldob->mode &= ~OB_MODE_POSE;
	//oldbase->flag &= ~OB_POSEMODE;
	
	ED_armature_from_edit(obedit);
	ED_armature_edit_free(obedit);
	
	/* 2) duplicate base */
	newbase = ED_object_add_duplicate(bmain, scene, oldbase, USER_DUP_ARM); /* only duplicate linked armature */
	DAG_relations_tag_update(bmain);

	newob = newbase->object;
	newbase->flag &= ~SELECT;
	
	
	/* 3) remove bones that shouldn't still be around on both armatures */
	separate_armature_bones(oldob, 1);
	separate_armature_bones(newob, 0);
	
	
	/* 4) fix links before depsgraph flushes */ // err... or after?
	separated_armature_fix_links(oldob, newob);
	
	DAG_id_tag_update(&oldob->id, OB_RECALC_DATA);  /* this is the original one */
	DAG_id_tag_update(&newob->id, OB_RECALC_DATA);  /* this is the separated one */
	
	
	/* 5) restore original conditions */
	obedit = oldob;
	
	ED_armature_to_edit(obedit);
	
	/* note, notifier might evolve */
	WM_event_add_notifier(C, NC_OBJECT | ND_POSE, obedit);
	
	/* recalc/redraw + cleanup */
	WM_cursor_wait(0);
	
	return OPERATOR_FINISHED;
}
Exemplo n.º 27
0
/* join armature exec is exported for use in object->join objects operator... */
int join_armature_exec(bContext *C, wmOperator *UNUSED(op))
{
	Main *bmain = CTX_data_main(C);
	Scene *scene = CTX_data_scene(C);
	Object  *ob = CTX_data_active_object(C);
	bArmature *arm = (ob) ? ob->data : NULL;
	bPose *pose, *opose;
	bPoseChannel *pchan, *pchann;
	EditBone *curbone;
	float mat[4][4], oimat[4][4];
	
	/*	Ensure we're not in editmode and that the active object is an armature*/
	if (!ob || ob->type != OB_ARMATURE)
		return OPERATOR_CANCELLED;
	if (!arm || arm->edbo)
		return OPERATOR_CANCELLED;
	
	/* Get editbones of active armature to add editbones to */
	ED_armature_to_edit(ob);
	
	/* get pose of active object and move it out of posemode */
	pose = ob->pose;
	ob->mode &= ~OB_MODE_POSE;

	CTX_DATA_BEGIN(C, Base *, base, selected_editable_bases)
	{
		if ((base->object->type == OB_ARMATURE) && (base->object != ob)) {
			bArmature *curarm = base->object->data;
			
			/* Make a list of editbones in current armature */
			ED_armature_to_edit(base->object);
			
			/* Get Pose of current armature */
			opose = base->object->pose;
			base->object->mode &= ~OB_MODE_POSE;
			//BASACT->flag &= ~OB_MODE_POSE;
			
			/* Find the difference matrix */
			invert_m4_m4(oimat, ob->obmat);
			mult_m4_m4m4(mat, oimat, base->object->obmat);
			
			/* Copy bones and posechannels from the object to the edit armature */
			for (pchan = opose->chanbase.first; pchan; pchan = pchann) {
				pchann = pchan->next;
				curbone = editbone_name_exists(curarm->edbo, pchan->name);
				
				/* Get new name */
				unique_editbone_name(arm->edbo, curbone->name, NULL);
				
				/* Transform the bone */
				{
					float premat[4][4];
					float postmat[4][4];
					float difmat[4][4];
					float imat[4][4];
					float temp[3][3];
					float delta[3];
					
					/* Get the premat */
					sub_v3_v3v3(delta, curbone->tail, curbone->head);
					vec_roll_to_mat3(delta, curbone->roll, temp);
					
					unit_m4(premat); /* Mat4MulMat34 only sets 3x3 part */
					mul_m4_m3m4(premat, temp, mat);
					
					mul_m4_v3(mat, curbone->head);
					mul_m4_v3(mat, curbone->tail);
					
					/* Get the postmat */
					sub_v3_v3v3(delta, curbone->tail, curbone->head);
					vec_roll_to_mat3(delta, curbone->roll, temp);
					copy_m4_m3(postmat, temp);
					
					/* Find the roll */
					invert_m4_m4(imat, premat);
					mult_m4_m4m4(difmat, imat, postmat);
					
					curbone->roll -= (float)atan2(difmat[2][0], difmat[2][2]);
				}
				
				/* Fix Constraints and Other Links to this Bone and Armature */
				joined_armature_fix_links(ob, base->object, pchan, curbone);
				
				/* Rename pchan */
				BLI_strncpy(pchan->name, curbone->name, sizeof(pchan->name));
				
				/* Jump Ship! */
				BLI_remlink(curarm->edbo, curbone);
				BLI_addtail(arm->edbo, curbone);
				
				BLI_remlink(&opose->chanbase, pchan);
				BLI_addtail(&pose->chanbase, pchan);
				BKE_pose_channels_hash_free(opose);
				BKE_pose_channels_hash_free(pose);
			}
			
			ED_base_object_free_and_unlink(bmain, scene, base);
		}
	}
	CTX_DATA_END;
	
	DAG_relations_tag_update(bmain);  /* because we removed object(s) */

	ED_armature_from_edit(ob);
	ED_armature_edit_free(ob);

	WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene);
	
	return OPERATOR_FINISHED;
}
Exemplo n.º 28
0
void DocumentImporter::finish()
{
	if (mImportStage != General)
		return;

	Main *bmain = CTX_data_main(mContext);
	// TODO: create a new scene except the selected <visual_scene> - use current blender scene for it
	Scene *sce = CTX_data_scene(mContext);
	unit_converter.calculate_scale(*sce);

	std::vector<Object *> *objects_to_scale = new std::vector<Object *>();

	/** TODO Break up and put into 2-pass parsing of DAE */
	std::vector<const COLLADAFW::VisualScene *>::iterator it;
	for (it = vscenes.begin(); it != vscenes.end(); it++) {
		PointerRNA sceneptr, unit_settings;
		PropertyRNA *system, *scale;
		
		// for scene unit settings: system, scale_length

		RNA_id_pointer_create(&sce->id, &sceneptr);
		unit_settings = RNA_pointer_get(&sceneptr, "unit_settings");
		system = RNA_struct_find_property(&unit_settings, "system");
		scale = RNA_struct_find_property(&unit_settings, "scale_length");

		if (this->import_settings->import_units) {
			
			switch (unit_converter.isMetricSystem()) {
				case UnitConverter::Metric:
					RNA_property_enum_set(&unit_settings, system, USER_UNIT_METRIC);
					break;
				case UnitConverter::Imperial:
					RNA_property_enum_set(&unit_settings, system, USER_UNIT_IMPERIAL);
					break;
				default:
					RNA_property_enum_set(&unit_settings, system, USER_UNIT_NONE);
					break;
			}
			float unit_factor = unit_converter.getLinearMeter();
			RNA_property_float_set(&unit_settings, scale, unit_factor);
			fprintf(stdout, "Collada: Adjusting Blender units to Importset units: %f.\n", unit_factor);

		}

		// Write nodes to scene
		const COLLADAFW::NodePointerArray& roots = (*it)->getRootNodes();
		for (unsigned int i = 0; i < roots.getCount(); i++) {
			std::vector<Object *> *objects_done = write_node(roots[i], NULL, sce, NULL, false);
			objects_to_scale->insert(objects_to_scale->end(), objects_done->begin(), objects_done->end());
			delete objects_done;
		}

		// update scene
		DAG_relations_tag_update(bmain);
		WM_event_add_notifier(mContext, NC_OBJECT | ND_TRANSFORM, NULL);

	}


	mesh_importer.optimize_material_assignements();

	armature_importer.set_tags_map(this->uid_tags_map);
	armature_importer.make_armatures(mContext);
	armature_importer.make_shape_keys();
	DAG_relations_tag_update(bmain);

#if 0
	armature_importer.fix_animation();
#endif

	for (std::vector<const COLLADAFW::VisualScene *>::iterator it = vscenes.begin(); it != vscenes.end(); it++) {
		const COLLADAFW::NodePointerArray& roots = (*it)->getRootNodes();

		for (unsigned int i = 0; i < roots.getCount(); i++) {
			translate_anim_recursive(roots[i], NULL, NULL);
		}
	}

	if (libnode_ob.size()) {
		Scene *sce = CTX_data_scene(mContext);

		fprintf(stderr, "got %d library nodes to free\n", (int)libnode_ob.size());
		// free all library_nodes
		std::vector<Object *>::iterator it;
		for (it = libnode_ob.begin(); it != libnode_ob.end(); it++) {
			Object *ob = *it;

			Base *base = BKE_scene_base_find(sce, ob);
			if (base) {
				BLI_remlink(&sce->base, base);
				BKE_libblock_free_us(G.main, base->object);
				if (sce->basact == base)
					sce->basact = NULL;
				MEM_freeN(base);
			}
		}
		libnode_ob.clear();

		DAG_relations_tag_update(bmain);
	}
	
	bc_match_scale(objects_to_scale, unit_converter, !this->import_settings->import_units);

	delete objects_to_scale;
}
Exemplo n.º 29
0
static void rna_Smoke_dependency_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
	rna_Smoke_update(bmain, scene, ptr);
	DAG_relations_tag_update(bmain);
}
Exemplo n.º 30
0
static void rna_ID_animation_data_free(ID *id, Main *bmain)
{
	BKE_animdata_free(id);
	DAG_relations_tag_update(bmain);
}