Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Montagne <montagne29@wanadoo.fr>2015-01-11 20:29:14 +0300
committerBastien Montagne <montagne29@wanadoo.fr>2015-01-11 20:32:25 +0300
commita628a8240ed151326001a106d784823ae4276175 (patch)
treee14622b937ceaf927443f98665c5fe24ea82e3c1 /source/blender/editors
parent599c8a2c8e4cf1f904c5422916ebfd8d12eebe69 (diff)
Data transfer: make operator able to work 'reversed' (i.e. transfer from selected objects to active).
Needed to replace weight transfer modifier in WeightPaint mode... Note this is not exposed to users in UI, shall remain technical intern parameter imho. Esp. since behavior when several sources is a bit 'random' (merely uses each source in selection order...). Also, this correct a bug, where 'lib' linked objects/meshes could not be used as source...
Diffstat (limited to 'source/blender/editors')
-rw-r--r--source/blender/editors/object/object_data_transfer.c47
1 files changed, 39 insertions, 8 deletions
diff --git a/source/blender/editors/object/object_data_transfer.c b/source/blender/editors/object/object_data_transfer.c
index 86f2824deb4..71ad73ac420 100644
--- a/source/blender/editors/object/object_data_transfer.c
+++ b/source/blender/editors/object/object_data_transfer.c
@@ -262,11 +262,16 @@ static bool data_transfer_check(bContext *UNUSED(C), wmOperator *op)
}
/* Helper, used by both data_transfer_exec and datalayout_transfer_exec. */
-static void data_transfer_exec_preprocess_objects(bContext *C, wmOperator *op, Object *ob_src, ListBase *ctx_objects)
+static void data_transfer_exec_preprocess_objects(
+ bContext *C, wmOperator *op, Object *ob_src, ListBase *ctx_objects, const bool reverse_transfer)
{
CollectionPointerLink *ctx_ob;
CTX_data_selected_editable_objects(C, ctx_objects);
+ if (reverse_transfer) {
+ return; /* Nothing else to do in this case... */
+ }
+
for (ctx_ob = ctx_objects->first; ctx_ob; ctx_ob = ctx_ob->next) {
Object *ob = ctx_ob->ptr.data;
Mesh *me;
@@ -288,13 +293,18 @@ static void data_transfer_exec_preprocess_objects(bContext *C, wmOperator *op, O
}
/* Helper, used by both data_transfer_exec and datalayout_transfer_exec. */
-static bool data_transfer_exec_is_object_valid(wmOperator *op, Object *ob_src, Object *ob_dst)
+static bool data_transfer_exec_is_object_valid(
+ wmOperator *op, Object *ob_src, Object *ob_dst, const bool reverse_transfer)
{
Mesh *me;
- if ((ob_dst == ob_src) || (ob_dst->type != OB_MESH)) {
+ if ((ob_dst == ob_src) || !ELEM(OB_MESH, ob_src->type, ob_dst->type)) {
return false;
}
+ if (reverse_transfer) {
+ return true;
+ }
+
me = ob_dst->data;
if (me->id.flag & LIB_DOIT) {
me->id.flag &= ~LIB_DOIT;
@@ -320,6 +330,8 @@ static int data_transfer_exec(bContext *C, wmOperator *op)
bool changed = false;
+ const bool reverse_transfer = RNA_boolean_get(op->ptr, "use_reverse_transfer");
+
const int data_type = RNA_enum_get(op->ptr, "data_type");
const bool use_create = RNA_boolean_get(op->ptr, "use_create");
@@ -346,16 +358,26 @@ static int data_transfer_exec(bContext *C, wmOperator *op)
SpaceTransform space_transform_data;
SpaceTransform *space_transform = use_object_transform ? &space_transform_data : NULL;
+ if (reverse_transfer && ((ID *)(ob_src->data))->lib) {
+ /* Do not transfer to linked data, not supported. */
+ return OPERATOR_CANCELLED;
+ }
+
if (fromto_idx != DT_MULTILAYER_INDEX_INVALID) {
layers_select_src[fromto_idx] = layers_src;
layers_select_dst[fromto_idx] = layers_dst;
}
- data_transfer_exec_preprocess_objects(C, op, ob_src, &ctx_objects);
+ data_transfer_exec_preprocess_objects(C, op, ob_src, &ctx_objects, reverse_transfer);
for (ctx_ob_dst = ctx_objects.first; ctx_ob_dst; ctx_ob_dst = ctx_ob_dst->next) {
Object *ob_dst = ctx_ob_dst->ptr.data;
- if (data_transfer_exec_is_object_valid(op, ob_src, ob_dst)) {
+
+ if (reverse_transfer) {
+ SWAP(Object *, ob_src, ob_dst);
+ }
+
+ if (data_transfer_exec_is_object_valid(op, ob_src, ob_dst, reverse_transfer)) {
if (space_transform) {
BLI_SPACE_TRANSFORM_SETUP(space_transform, ob_dst, ob_src);
}
@@ -370,6 +392,10 @@ static int data_transfer_exec(bContext *C, wmOperator *op)
changed = true;
}
}
+
+ if (reverse_transfer) {
+ SWAP(Object *, ob_src, ob_dst);
+ }
}
BLI_freelistN(&ctx_objects);
@@ -384,11 +410,12 @@ static int data_transfer_exec(bContext *C, wmOperator *op)
}
/* Used by both OBJECT_OT_data_transfer and OBJECT_OT_datalayout_transfer */
+/* Note this context poll is only really partial, it cannot check for all possible invalid cases. */
static int data_transfer_poll(bContext *C)
{
Object *ob = ED_object_context(C);
ID *data = (ob) ? ob->data : NULL;
- return (ob && !ob->id.lib && ob->type == OB_MESH && data && !data->lib);
+ return (ob && ob->type == OB_MESH && data);
}
/* Used by both OBJECT_OT_data_transfer and OBJECT_OT_datalayout_transfer */
@@ -481,6 +508,10 @@ void OBJECT_OT_data_transfer(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* Properties.*/
+ prop = RNA_def_boolean(ot->srna, "use_reverse_transfer", false, "Reverse Transfer",
+ "Transfer from selected objects to active one");
+ RNA_def_property_flag(prop, PROP_HIDDEN);
+
/* Data type to transfer. */
ot->prop = RNA_def_enum(ot->srna, "data_type", DT_layer_items, 0, "Data Type", "Which data to transfer");
RNA_def_boolean(ot->srna, "use_create", true, "Create Data", "Add data layers on destination meshes if needed");
@@ -582,11 +613,11 @@ static int datalayout_transfer_exec(bContext *C, wmOperator *op)
layers_select_dst[fromto_idx] = layers_dst;
}
- data_transfer_exec_preprocess_objects(C, op, ob_src, &ctx_objects);
+ data_transfer_exec_preprocess_objects(C, op, ob_src, &ctx_objects, false);
for (ctx_ob_dst = ctx_objects.first; ctx_ob_dst; ctx_ob_dst = ctx_ob_dst->next) {
Object *ob_dst = ctx_ob_dst->ptr.data;
- if (data_transfer_exec_is_object_valid(op, ob_src, ob_dst)) {
+ if (data_transfer_exec_is_object_valid(op, ob_src, ob_dst, false)) {
BKE_object_data_transfer_layout(scene, ob_src, ob_dst, data_type, use_delete,
layers_select_src, layers_select_dst);
}