Esempio n. 1
0
static bool check_group_contains_object_recursive(Group *group, Object *object)
{
	GroupObject *group_object;

	if ((group->id.flag & LIB_DOIT) == 0) {
		/* Cycle already exists in groups, let's prevent further crappyness */
		return true;
	}

	group->id.flag &= ~LIB_DOIT;

	for (group_object = group->gobject.first; group_object; group_object = group_object->next) {
		Object *current_object = group_object->ob;

		if (current_object == object) {
			return true;
		}

		if (current_object->dup_group) {
			if (check_group_contains_object_recursive(current_object->dup_group, object)) {
				return true;
			}
		}
	}

	group->id.flag |= LIB_DOIT;

	return false;
}
Esempio n. 2
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;
}
Esempio n. 3
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;
}