Cleanup: use `rna_enum_` prefix for RNA enums
[blender.git] / source / blender / editors / object / object_data_transfer.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2014 by Blender Foundation.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): Bastien Montagne.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/editors/object/object_data_transfer.c
29  *  \ingroup edobj
30  */
31
32 #include "DNA_mesh_types.h"
33 #include "DNA_modifier_types.h"
34 #include "DNA_object_types.h"
35 #include "DNA_scene_types.h"
36
37 #include "BLI_math.h"
38 #include "BLI_blenlib.h"
39 #include "BLI_utildefines.h"
40
41 #include "BKE_context.h"
42 #include "BKE_data_transfer.h"
43 #include "BKE_depsgraph.h"
44 #include "BKE_DerivedMesh.h"
45 #include "BKE_mesh_mapping.h"
46 #include "BKE_mesh_remap.h"
47 #include "BKE_object.h"
48 #include "BKE_report.h"
49
50 #include "RNA_access.h"
51 #include "RNA_define.h"
52 #include "RNA_enum_types.h"
53
54 #include "WM_api.h"
55 #include "WM_types.h"
56
57 #include "ED_object.h"
58
59 #include "UI_interface.h"
60
61 #include "object_intern.h"
62
63 /* All possible data to transfer.
64  * Note some are 'fake' ones, i.e. they are not hold by real CDLayers. */
65 /* Not shared with modifier, since we use a usual enum here, not a multi-choice one. */
66 static EnumPropertyItem DT_layer_items[] = {
67         {0, "", 0, "Vertex Data", ""},
68         {DT_TYPE_MDEFORMVERT, "VGROUP_WEIGHTS", 0, "Vertex Group(s)", "Transfer active or all vertex groups"},
69 #if 0  /* XXX For now, would like to finish/merge work from 2014 gsoc first. */
70         {DT_TYPE_SHAPEKEY, "SHAPEKEYS", 0, "Shapekey(s)", "Transfer active or all shape keys"},
71 #endif
72 #if 0  /* XXX When SkinModifier is enabled, it seems to erase its own CD_MVERT_SKIN layer from final DM :( */
73         {DT_TYPE_SKIN, "SKIN", 0, "Skin Weight", "Transfer skin weights"},
74 #endif
75         {DT_TYPE_BWEIGHT_VERT, "BEVEL_WEIGHT_VERT", 0, "Bevel Weight", "Transfer bevel weights"},
76         {0, "", 0, "Edge Data", ""},
77         {DT_TYPE_SHARP_EDGE, "SHARP_EDGE", 0, "Sharp", "Transfer sharp mark"},
78         {DT_TYPE_SEAM, "SEAM", 0, "UV Seam", "Transfer UV seam mark"},
79         {DT_TYPE_CREASE, "CREASE", 0, "Subsurf Crease", "Transfer crease values"},
80         {DT_TYPE_BWEIGHT_EDGE, "BEVEL_WEIGHT_EDGE", 0, "Bevel Weight", "Transfer bevel weights"},
81         {DT_TYPE_FREESTYLE_EDGE, "FREESTYLE_EDGE", 0, "Freestyle Mark", "Transfer Freestyle edge mark"},
82         {0, "", 0, "Face Corner Data", ""},
83         {DT_TYPE_LNOR, "CUSTOM_NORMAL", 0, "Custom Normals", "Transfer custom normals"},
84         {DT_TYPE_VCOL, "VCOL", 0, "VCol", "Vertex (face corners) colors"},
85         {DT_TYPE_UV, "UV", 0, "UVs", "Transfer UV layers"},
86         {0, "", 0, "Face Data", ""},
87         {DT_TYPE_SHARP_FACE, "SMOOTH", 0, "Smooth", "Transfer flat/smooth mark"},
88         {DT_TYPE_FREESTYLE_FACE, "FREESTYLE_FACE", 0, "Freestyle Mark", "Transfer Freestyle face mark"},
89         {0, NULL, 0, NULL, NULL}
90 };
91
92 /* Note: rna_enum_dt_layers_select_src_items enum is from rna_modifier.c */
93 static EnumPropertyItem *dt_layers_select_src_itemf(
94         bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free)
95 {
96         EnumPropertyItem *item = NULL, tmp_item = {0};
97         int totitem = 0;
98
99         const int data_type = RNA_enum_get(ptr, "data_type");
100
101         if (!C) {  /* needed for docs and i18n tools */
102                 return rna_enum_dt_layers_select_src_items;
103         }
104
105         RNA_enum_items_add_value(&item, &totitem, rna_enum_dt_layers_select_src_items, DT_LAYERS_ACTIVE_SRC);
106         RNA_enum_items_add_value(&item, &totitem, rna_enum_dt_layers_select_src_items, DT_LAYERS_ALL_SRC);
107
108         if (data_type == DT_TYPE_MDEFORMVERT) {
109                 Object *ob_src = CTX_data_active_object(C);
110
111                 if (BKE_object_pose_armature_get(ob_src)) {
112                         RNA_enum_items_add_value(&item, &totitem, rna_enum_dt_layers_select_src_items, DT_LAYERS_VGROUP_SRC_BONE_SELECT);
113                         RNA_enum_items_add_value(&item, &totitem, rna_enum_dt_layers_select_src_items, DT_LAYERS_VGROUP_SRC_BONE_DEFORM);
114                 }
115
116                 if (ob_src) {
117                         bDeformGroup *dg;
118                         int i;
119
120                         RNA_enum_item_add_separator(&item, &totitem);
121
122                         for (i = 0, dg = ob_src->defbase.first; dg; i++, dg = dg->next) {
123                                 tmp_item.value = i;
124                                 tmp_item.identifier = tmp_item.name = dg->name;
125                                 RNA_enum_item_add(&item, &totitem, &tmp_item);
126                         }
127                 }
128         }
129         else if (data_type == DT_TYPE_SHAPEKEY) {
130                 /* TODO */
131         }
132         else if (data_type == DT_TYPE_UV) {
133                 Object *ob_src = CTX_data_active_object(C);
134                 Scene *scene = CTX_data_scene(C);
135
136                 if (ob_src) {
137                         DerivedMesh *dm_src;
138                         CustomData *pdata;
139                         int num_data, i;
140
141                         /* XXX Is this OK? */
142                         dm_src = mesh_get_derived_final(scene, ob_src, CD_MASK_BAREMESH | CD_MTEXPOLY);
143                         pdata = dm_src->getPolyDataLayout(dm_src);
144                         num_data = CustomData_number_of_layers(pdata, CD_MTEXPOLY);
145
146                         RNA_enum_item_add_separator(&item, &totitem);
147
148                         for (i = 0; i < num_data; i++) {
149                                 tmp_item.value = i;
150                                 tmp_item.identifier = tmp_item.name = CustomData_get_layer_name(pdata, CD_MTEXPOLY, i);
151                                 RNA_enum_item_add(&item, &totitem, &tmp_item);
152                         }
153                 }
154         }
155         else if (data_type == DT_TYPE_VCOL) {
156                 Object *ob_src = CTX_data_active_object(C);
157                 Scene *scene = CTX_data_scene(C);
158
159                 if (ob_src) {
160                         DerivedMesh *dm_src;
161                         CustomData *ldata;
162                         int num_data, i;
163
164                         /* XXX Is this OK? */
165                         dm_src = mesh_get_derived_final(scene, ob_src, CD_MASK_BAREMESH | CD_MLOOPCOL);
166                         ldata = dm_src->getLoopDataLayout(dm_src);
167                         num_data = CustomData_number_of_layers(ldata, CD_MLOOPCOL);
168
169                         RNA_enum_item_add_separator(&item, &totitem);
170
171                         for (i = 0; i < num_data; i++) {
172                                 tmp_item.value = i;
173                                 tmp_item.identifier = tmp_item.name = CustomData_get_layer_name(ldata, CD_MLOOPCOL, i);
174                                 RNA_enum_item_add(&item, &totitem, &tmp_item);
175                         }
176                 }
177         }
178
179         RNA_enum_item_end(&item, &totitem);
180         *r_free = true;
181
182         return item;
183 }
184
185 /* Note: rna_enum_dt_layers_select_dst_items enum is from rna_modifier.c */
186 static EnumPropertyItem *dt_layers_select_dst_itemf(
187         bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free)
188 {
189         EnumPropertyItem *item = NULL;
190         int totitem = 0;
191
192         const int layers_select_src = RNA_enum_get(ptr, "layers_select_src");
193
194         if (!C) {  /* needed for docs and i18n tools */
195                 return rna_enum_dt_layers_select_dst_items;
196         }
197
198         if (layers_select_src == DT_LAYERS_ACTIVE_SRC || layers_select_src >= 0) {
199                 RNA_enum_items_add_value(&item, &totitem, rna_enum_dt_layers_select_dst_items, DT_LAYERS_ACTIVE_DST);
200         }
201         RNA_enum_items_add_value(&item, &totitem, rna_enum_dt_layers_select_dst_items, DT_LAYERS_NAME_DST);
202         RNA_enum_items_add_value(&item, &totitem, rna_enum_dt_layers_select_dst_items, DT_LAYERS_INDEX_DST);
203
204         /* No 'specific' to-layers here, since we may transfer to several objects at once! */
205
206         RNA_enum_item_end(&item, &totitem);
207         *r_free = true;
208
209         return item;
210 }
211
212 static EnumPropertyItem *dt_layers_select_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *prop, bool *r_free)
213 {
214         const bool reverse_transfer = RNA_boolean_get(ptr, "use_reverse_transfer");
215
216         if (STREQ(RNA_property_identifier(prop), "layers_select_dst")) {
217                 if (reverse_transfer) {
218                         return dt_layers_select_src_itemf(C, ptr, prop, r_free);
219                 }
220                 else {
221                         return dt_layers_select_dst_itemf(C, ptr, prop, r_free);
222                 }
223         }
224         else if (reverse_transfer) {
225                 return dt_layers_select_dst_itemf(C, ptr, prop, r_free);
226         }
227         else {
228                 return dt_layers_select_src_itemf(C, ptr, prop, r_free);
229         }
230 }
231
232 /* Note: rna_enum_dt_mix_mode_items enum is from rna_modifier.c */
233 static EnumPropertyItem *dt_mix_mode_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free)
234 {
235         EnumPropertyItem *item = NULL;
236         int totitem = 0;
237
238         const int dtdata_type = RNA_enum_get(ptr, "data_type");
239         bool support_advanced_mixing, support_threshold;
240
241         if (!C) {  /* needed for docs and i18n tools */
242                 return rna_enum_dt_mix_mode_items;
243         }
244
245         RNA_enum_items_add_value(&item, &totitem, rna_enum_dt_mix_mode_items, CDT_MIX_TRANSFER);
246
247         BKE_object_data_transfer_get_dttypes_capacity(dtdata_type, &support_advanced_mixing, &support_threshold);
248
249         if (support_threshold) {
250                 RNA_enum_items_add_value(&item, &totitem, rna_enum_dt_mix_mode_items, CDT_MIX_REPLACE_ABOVE_THRESHOLD);
251                 RNA_enum_items_add_value(&item, &totitem, rna_enum_dt_mix_mode_items, CDT_MIX_REPLACE_BELOW_THRESHOLD);
252         }
253
254         if (support_advanced_mixing) {
255                 RNA_enum_item_add_separator(&item, &totitem);
256                 RNA_enum_items_add_value(&item, &totitem, rna_enum_dt_mix_mode_items, CDT_MIX_MIX);
257                 RNA_enum_items_add_value(&item, &totitem, rna_enum_dt_mix_mode_items, CDT_MIX_ADD);
258                 RNA_enum_items_add_value(&item, &totitem, rna_enum_dt_mix_mode_items, CDT_MIX_SUB);
259                 RNA_enum_items_add_value(&item, &totitem, rna_enum_dt_mix_mode_items, CDT_MIX_MUL);
260         }
261
262         RNA_enum_item_end(&item, &totitem);
263         *r_free = true;
264
265         return item;
266 }
267
268 static bool data_transfer_check(bContext *UNUSED(C), wmOperator *op)
269 {
270         const int layers_select_src = RNA_enum_get(op->ptr, "layers_select_src");
271         PropertyRNA *prop = RNA_struct_find_property(op->ptr, "layers_select_dst");
272         const int layers_select_dst = RNA_property_enum_get(op->ptr, prop);
273
274         /* TODO: check for invalid layers_src select modes too! */
275
276         if ((layers_select_src != DT_LAYERS_ACTIVE_SRC) && (layers_select_dst == DT_LAYERS_ACTIVE_DST)) {
277                 RNA_property_enum_set(op->ptr, prop, DT_LAYERS_NAME_DST);
278                 return true;
279         }
280
281         return false;
282 }
283
284 /* Helper, used by both data_transfer_exec and datalayout_transfer_exec. */
285 static void data_transfer_exec_preprocess_objects(
286         bContext *C, wmOperator *op, Object *ob_src, ListBase *ctx_objects, const bool reverse_transfer)
287 {
288         CollectionPointerLink *ctx_ob;
289         CTX_data_selected_editable_objects(C, ctx_objects);
290
291         if (reverse_transfer) {
292                 return;  /* Nothing else to do in this case... */
293         }
294
295         for (ctx_ob = ctx_objects->first; ctx_ob; ctx_ob = ctx_ob->next) {
296                 Object *ob = ctx_ob->ptr.data;
297                 Mesh *me;
298                 if ((ob == ob_src) || (ob->type != OB_MESH)) {
299                         continue;
300                 }
301
302                 me = ob->data;
303                 if (me->id.lib) {
304                         /* Do not transfer to linked data, not supported. */
305                         BKE_reportf(op->reports, RPT_WARNING, "Skipping object '%s', linked data '%s' cannot be modified",
306                                     ob->id.name + 2, me->id.name + 2);
307                         me->id.flag &= ~LIB_DOIT;
308                         continue;
309                 }
310
311                 me->id.flag |= LIB_DOIT;
312         }
313 }
314
315 /* Helper, used by both data_transfer_exec and datalayout_transfer_exec. */
316 static bool data_transfer_exec_is_object_valid(
317         wmOperator *op, Object *ob_src, Object *ob_dst, const bool reverse_transfer)
318 {
319         Mesh *me;
320         if ((ob_dst == ob_src) || (ob_src->type != OB_MESH) || (ob_dst->type != OB_MESH)) {
321                 return false;
322         }
323
324         if (reverse_transfer) {
325                 return true;
326         }
327
328         me = ob_dst->data;
329         if (me->id.flag & LIB_DOIT) {
330                 me->id.flag &= ~LIB_DOIT;
331                 return true;
332         }
333         else if (me->id.lib == NULL) {
334                 /* Do not transfer apply operation more than once. */
335                 /* XXX This is not nice regarding vgroups, which are half-Object data... :/ */
336                 BKE_reportf(op->reports, RPT_WARNING,
337                             "Skipping object '%s', data '%s' has already been processed with a previous object",
338                             ob_dst->id.name + 2, me->id.name + 2);
339         }
340         return false;
341 }
342
343 static int data_transfer_exec(bContext *C, wmOperator *op)
344 {
345         Scene *scene = CTX_data_scene(C);
346         Object *ob_src = ED_object_active_context(C);
347
348         ListBase ctx_objects;
349         CollectionPointerLink *ctx_ob_dst;
350
351         bool changed = false;
352
353         const bool is_frozen = RNA_boolean_get(op->ptr, "use_freeze");
354
355         const bool reverse_transfer = RNA_boolean_get(op->ptr, "use_reverse_transfer");
356
357         const int data_type = RNA_enum_get(op->ptr, "data_type");
358         const bool use_create = RNA_boolean_get(op->ptr, "use_create");
359
360         const int map_vert_mode = RNA_enum_get(op->ptr, "vert_mapping");
361         const int map_edge_mode = RNA_enum_get(op->ptr, "edge_mapping");
362         const int map_loop_mode = RNA_enum_get(op->ptr, "loop_mapping");
363         const int map_poly_mode = RNA_enum_get(op->ptr, "poly_mapping");
364
365         const bool use_auto_transform = RNA_boolean_get(op->ptr, "use_auto_transform");
366         const bool use_object_transform = RNA_boolean_get(op->ptr, "use_object_transform");
367         const bool use_max_distance = RNA_boolean_get(op->ptr, "use_max_distance");
368         const float max_distance = use_max_distance ? RNA_float_get(op->ptr, "max_distance") : FLT_MAX;
369         const float ray_radius = RNA_float_get(op->ptr, "ray_radius");
370         const float islands_precision = RNA_float_get(op->ptr, "islands_precision");
371
372         const int layers_src = RNA_enum_get(op->ptr, "layers_select_src");
373         const int layers_dst = RNA_enum_get(op->ptr, "layers_select_dst");
374         int layers_select_src[DT_MULTILAYER_INDEX_MAX] = {0};
375         int layers_select_dst[DT_MULTILAYER_INDEX_MAX] = {0};
376         const int fromto_idx = BKE_object_data_transfer_dttype_to_srcdst_index(data_type);
377
378         const int mix_mode = RNA_enum_get(op->ptr, "mix_mode");
379         const float mix_factor = RNA_float_get(op->ptr, "mix_factor");
380
381         SpaceTransform space_transform_data;
382         SpaceTransform *space_transform = (use_object_transform && !use_auto_transform) ? &space_transform_data : NULL;
383
384         if (is_frozen) {
385                 BKE_report(op->reports, RPT_INFO,
386                            "Operator is frozen, changes to its settings won't take effect until you unfreeze it");
387                 return OPERATOR_FINISHED;
388         }
389
390         if (reverse_transfer && ((ID *)(ob_src->data))->lib) {
391                 /* Do not transfer to linked data, not supported. */
392                 return OPERATOR_CANCELLED;
393         }
394
395         if (fromto_idx != DT_MULTILAYER_INDEX_INVALID) {
396                 layers_select_src[fromto_idx] = layers_src;
397                 layers_select_dst[fromto_idx] = layers_dst;
398         }
399
400         data_transfer_exec_preprocess_objects(C, op, ob_src, &ctx_objects, reverse_transfer);
401
402         for (ctx_ob_dst = ctx_objects.first; ctx_ob_dst; ctx_ob_dst = ctx_ob_dst->next) {
403                 Object *ob_dst = ctx_ob_dst->ptr.data;
404
405                 if (reverse_transfer) {
406                         SWAP(Object *, ob_src, ob_dst);
407                 }
408
409                 if (data_transfer_exec_is_object_valid(op, ob_src, ob_dst, reverse_transfer)) {
410                         if (space_transform) {
411                                 BLI_SPACE_TRANSFORM_SETUP(space_transform, ob_dst, ob_src);
412                         }
413
414                         if (BKE_object_data_transfer_mesh(
415                                 scene, ob_src, ob_dst, data_type, use_create,
416                                 map_vert_mode, map_edge_mode, map_loop_mode, map_poly_mode,
417                                 space_transform, use_auto_transform,
418                                 max_distance, ray_radius, islands_precision,
419                                 layers_select_src, layers_select_dst,
420                                 mix_mode, mix_factor, NULL, false, op->reports))
421                         {
422                                 changed = true;
423                         }
424                 }
425
426                 DAG_id_tag_update(&ob_dst->id, OB_RECALC_DATA);
427
428                 if (reverse_transfer) {
429                         SWAP(Object *, ob_src, ob_dst);
430                 }
431         }
432
433         BLI_freelistN(&ctx_objects);
434
435         WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, NULL);
436
437 #if 0  /* TODO */
438         /* Note: issue with that is that if canceled, operator cannot be redone... Nasty in our case. */
439         return changed ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
440 #else
441         (void)changed;
442         return OPERATOR_FINISHED;
443 #endif
444 }
445
446 /* Used by both OBJECT_OT_data_transfer and OBJECT_OT_datalayout_transfer */
447 /* Note this context poll is only really partial, it cannot check for all possible invalid cases. */
448 static int data_transfer_poll(bContext *C)
449 {
450         Object *ob = ED_object_active_context(C);
451         ID *data = (ob) ? ob->data : NULL;
452         return (ob && ob->type == OB_MESH && data);
453 }
454
455 /* Used by both OBJECT_OT_data_transfer and OBJECT_OT_datalayout_transfer */
456 static bool data_transfer_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop)
457 {
458         PropertyRNA *prop_other;
459
460         const char *prop_id = RNA_property_identifier(prop);
461         const int data_type = RNA_enum_get(ptr, "data_type");
462         bool use_auto_transform = false;
463         bool use_max_distance = false;
464         bool use_modifier = false;
465
466         if ((prop_other = RNA_struct_find_property(ptr, "use_auto_transform"))) {
467                 use_auto_transform = RNA_property_boolean_get(ptr, prop_other);
468         }
469         if ((prop_other = RNA_struct_find_property(ptr, "use_max_distance"))) {
470                 use_max_distance = RNA_property_boolean_get(ptr, prop_other);
471         }
472         if ((prop_other = RNA_struct_find_property(ptr, "modifier"))) {
473                 use_modifier = RNA_property_is_set(ptr, prop_other);
474         }
475
476         if (STREQ(prop_id, "modifier")) {
477                 return use_modifier;
478         }
479
480         if (use_modifier) {
481                 /* Hide everything but 'modifier' property, if set. */
482                 return false;
483         }
484
485         if (STREQ(prop_id, "use_object_transform") && use_auto_transform) {
486                 return false;
487         }
488         if (STREQ(prop_id, "max_distance") && !use_max_distance) {
489                 return false;
490         }
491         if (STREQ(prop_id, "islands_precision") && !DT_DATATYPE_IS_LOOP(data_type)) {
492                 return false;
493         }
494
495         if (STREQ(prop_id, "vert_mapping") && !DT_DATATYPE_IS_VERT(data_type)) {
496                 return false;
497         }
498         if (STREQ(prop_id, "edge_mapping") && !DT_DATATYPE_IS_EDGE(data_type)) {
499                 return false;
500         }
501         if (STREQ(prop_id, "loop_mapping") && !DT_DATATYPE_IS_LOOP(data_type)) {
502                 return false;
503         }
504         if (STREQ(prop_id, "poly_mapping") && !DT_DATATYPE_IS_POLY(data_type)) {
505                 return false;
506         }
507
508         if ((STREQ(prop_id, "layers_select_src") || STREQ(prop_id, "layers_select_dst")) &&
509             !DT_DATATYPE_IS_MULTILAYERS(data_type))
510         {
511                 return false;
512         }
513
514         /* Else, show it! */
515         return true;
516 }
517
518 /* Used by both OBJECT_OT_data_transfer and OBJECT_OT_datalayout_transfer */
519 static void data_transfer_ui(bContext *C, wmOperator *op)
520 {
521         uiLayout *layout = op->layout;
522         wmWindowManager *wm = CTX_wm_manager(C);
523         PointerRNA ptr;
524
525         RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
526
527         /* Main auto-draw call */
528         uiDefAutoButsRNA(layout, &ptr, data_transfer_draw_check_prop, '\0');
529 }
530
531 /* transfers weight from active to selected */
532 void OBJECT_OT_data_transfer(wmOperatorType *ot)
533 {
534         PropertyRNA *prop;
535
536         /* Identifiers.*/
537         ot->name = "Transfer Mesh Data";
538         ot->idname = "OBJECT_OT_data_transfer";
539         ot->description = "Transfer data layer(s) (weights, edge sharp, ...) from active to selected meshes";
540
541         /* API callbacks.*/
542         ot->poll = data_transfer_poll;
543         ot->invoke = WM_menu_invoke;
544         ot->exec = data_transfer_exec;
545         ot->check = data_transfer_check;
546         ot->ui = data_transfer_ui;
547
548         /* Flags.*/
549         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
550
551         /* Properties.*/
552         prop = RNA_def_boolean(ot->srna, "use_reverse_transfer", false, "Reverse Transfer",
553                                "Transfer from selected objects to active one");
554         RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
555
556         RNA_def_boolean(ot->srna, "use_freeze", false, "Freeze Operator",
557                         "Prevent changes to settings to re-run the operator, "
558                         "handy to change several things at once with heavy geometry");
559
560         /* Data type to transfer. */
561         ot->prop = RNA_def_enum(ot->srna, "data_type", DT_layer_items, 0, "Data Type", "Which data to transfer");
562         RNA_def_boolean(ot->srna, "use_create", true, "Create Data", "Add data layers on destination meshes if needed");
563
564         /* Mapping methods. */
565         RNA_def_enum(ot->srna, "vert_mapping", rna_enum_dt_method_vertex_items, MREMAP_MODE_VERT_NEAREST, "Vertex Mapping",
566                      "Method used to map source vertices to destination ones");
567         RNA_def_enum(ot->srna, "edge_mapping", rna_enum_dt_method_edge_items, MREMAP_MODE_EDGE_NEAREST, "Edge Mapping",
568                      "Method used to map source edges to destination ones");
569         RNA_def_enum(ot->srna, "loop_mapping", rna_enum_dt_method_loop_items, MREMAP_MODE_LOOP_NEAREST_POLYNOR,
570                      "Face Corner Mapping", "Method used to map source faces' corners to destination ones");
571         RNA_def_enum(ot->srna, "poly_mapping", rna_enum_dt_method_poly_items, MREMAP_MODE_POLY_NEAREST, "Face Mapping",
572                      "Method used to map source faces to destination ones");
573
574         /* Mapping options and filtering. */
575         RNA_def_boolean(ot->srna, "use_auto_transform", false, "Auto Transform",
576                         "Automatically compute transformation to get the best possible match between source and "
577                         "destination meshes (WARNING: results will never be as good as manual matching of objects)");
578         RNA_def_boolean(ot->srna, "use_object_transform", true, "Object Transform",
579                         "Evaluate source and destination meshes in global space");
580         RNA_def_boolean(ot->srna, "use_max_distance", false, "Only Neighbor Geometry",
581                         "Source elements must be closer than given distance from destination one");
582         prop = RNA_def_float(ot->srna, "max_distance", 1.0f, 0.0f, FLT_MAX, "Max Distance",
583                              "Maximum allowed distance between source and destination element, for non-topology mappings",
584                              0.0f, 100.0f);
585         RNA_def_property_subtype(prop, PROP_DISTANCE);
586         prop = RNA_def_float(ot->srna, "ray_radius", 0.0f, 0.0f, FLT_MAX, "Ray Radius",
587                              "'Width' of rays (especially useful when raycasting against vertices or edges)",
588                              0.0f, 10.0f);
589         RNA_def_property_subtype(prop, PROP_DISTANCE);
590         prop = RNA_def_float(ot->srna, "islands_precision", 0.1f, 0.0f, 10.0f, "Islands Precision",
591                              "Factor controlling precision of islands handling (the higher, the better the results)",
592                              0.0f, 1.0f);
593         RNA_def_property_subtype(prop, PROP_FACTOR);
594
595         /* How to handle multi-layers types of data. */
596         prop = RNA_def_enum(ot->srna, "layers_select_src", rna_enum_dt_layers_select_src_items, DT_LAYERS_ACTIVE_SRC,
597                             "Source Layers Selection", "Which layers to transfer, in case of multi-layers types");
598         RNA_def_property_enum_funcs_runtime(prop, NULL, NULL, dt_layers_select_itemf);
599
600         prop = RNA_def_enum(ot->srna, "layers_select_dst", rna_enum_dt_layers_select_dst_items, DT_LAYERS_ACTIVE_DST,
601                             "Destination Layers Matching", "How to match source and destination layers");
602         RNA_def_property_enum_funcs_runtime(prop, NULL, NULL, dt_layers_select_itemf);
603
604         prop = RNA_def_enum(ot->srna, "mix_mode", rna_enum_dt_mix_mode_items, CDT_MIX_TRANSFER, "Mix Mode",
605                            "How to affect destination elements with source values");
606         RNA_def_property_enum_funcs_runtime(prop, NULL, NULL, dt_mix_mode_itemf);
607         RNA_def_float(ot->srna, "mix_factor", 1.0f, 0.0f, 1.0f, "Mix Factor",
608                       "Factor to use when applying data to destination (exact behavior depends on mix mode)", 0.0f, 1.0f);
609 }
610
611 /******************************************************************************/
612 /* Note: This operator is hybrid, it can work as a usual standalone Object operator,
613  *       or as a DataTransfer modifier tool.
614  */
615
616 static int datalayout_transfer_poll(bContext *C)
617 {
618         return (edit_modifier_poll_generic(C, &RNA_DataTransferModifier, (1 << OB_MESH)) || data_transfer_poll(C));
619 }
620
621 static int datalayout_transfer_exec(bContext *C, wmOperator *op)
622 {
623         Scene *scene = CTX_data_scene(C);
624         Object *ob_act = ED_object_active_context(C);
625         DataTransferModifierData *dtmd;
626
627         dtmd = (DataTransferModifierData *)edit_modifier_property_get(op, ob_act, eModifierType_DataTransfer);
628
629         /* If we have a modifier, we transfer data layout from this modifier's source object to active one.
630          * Else, we transfer data layout from active object to all selected ones. */
631         if (dtmd) {
632                 Object *ob_src = dtmd->ob_source;
633                 Object *ob_dst = ob_act;
634
635                 const bool use_delete = false;  /* Never when used from modifier, for now. */
636
637                 if (!ob_src) {
638                         return OPERATOR_CANCELLED;
639                 }
640
641                 BKE_object_data_transfer_layout(scene, ob_src, ob_dst, dtmd->data_types, use_delete,
642                                                 dtmd->layers_select_src, dtmd->layers_select_dst);
643
644                 DAG_id_tag_update(&ob_dst->id, OB_RECALC_DATA);
645         }
646         else {
647                 Object *ob_src = ob_act;
648
649                 ListBase ctx_objects;
650                 CollectionPointerLink *ctx_ob_dst;
651
652                 const int data_type = RNA_enum_get(op->ptr, "data_type");
653                 const bool use_delete = RNA_boolean_get(op->ptr, "use_delete");
654
655                 const int layers_src = RNA_enum_get(op->ptr, "layers_select_src");
656                 const int layers_dst = RNA_enum_get(op->ptr, "layers_select_dst");
657                 int layers_select_src[DT_MULTILAYER_INDEX_MAX] = {0};
658                 int layers_select_dst[DT_MULTILAYER_INDEX_MAX] = {0};
659                 const int fromto_idx = BKE_object_data_transfer_dttype_to_srcdst_index(data_type);
660
661                 if (fromto_idx != DT_MULTILAYER_INDEX_INVALID) {
662                         layers_select_src[fromto_idx] = layers_src;
663                         layers_select_dst[fromto_idx] = layers_dst;
664                 }
665
666                 data_transfer_exec_preprocess_objects(C, op, ob_src, &ctx_objects, false);
667
668                 for (ctx_ob_dst = ctx_objects.first; ctx_ob_dst; ctx_ob_dst = ctx_ob_dst->next) {
669                         Object *ob_dst = ctx_ob_dst->ptr.data;
670                         if (data_transfer_exec_is_object_valid(op, ob_src, ob_dst, false)) {
671                                 BKE_object_data_transfer_layout(scene, ob_src, ob_dst, data_type, use_delete,
672                                                                 layers_select_src, layers_select_dst);
673                         }
674
675                         DAG_id_tag_update(&ob_dst->id, OB_RECALC_DATA);
676                 }
677
678                 BLI_freelistN(&ctx_objects);
679         }
680
681         WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, NULL);
682
683         return OPERATOR_FINISHED;
684 }
685
686 static int datalayout_transfer_invoke(bContext *C, wmOperator *op, const wmEvent *event)
687 {
688         if (edit_modifier_invoke_properties(C, op)) {
689                 return datalayout_transfer_exec(C, op);
690         }
691         else {
692                 return WM_menu_invoke(C, op, event);
693         }
694 }
695
696 void OBJECT_OT_datalayout_transfer(wmOperatorType *ot)
697 {
698         PropertyRNA *prop;
699
700         ot->name = "Transfer Mesh Data Layout";
701         ot->description = "Transfer layout of data layer(s) from active to selected meshes";
702         ot->idname = "OBJECT_OT_datalayout_transfer";
703
704         ot->poll = datalayout_transfer_poll;
705         ot->invoke = datalayout_transfer_invoke;
706         ot->exec = datalayout_transfer_exec;
707         ot->check = data_transfer_check;
708         ot->ui = data_transfer_ui;
709
710         /* flags */
711         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
712
713         /* Properties.*/
714         edit_modifier_properties(ot);
715
716         /* Data type to transfer. */
717         ot->prop = RNA_def_enum(ot->srna, "data_type", DT_layer_items, 0, "Data Type", "Which data to transfer");
718         RNA_def_boolean(ot->srna, "use_delete", false, "Exact Match",
719                         "Also delete some data layers from destination if necessary, so that it matches exactly source");
720
721         /* How to handle multi-layers types of data. */
722         prop = RNA_def_enum(ot->srna, "layers_select_src", rna_enum_dt_layers_select_src_items, DT_LAYERS_ACTIVE_SRC,
723                             "Source Layers Selection", "Which layers to transfer, in case of multi-layers types");
724         RNA_def_property_enum_funcs_runtime(prop, NULL, NULL, dt_layers_select_src_itemf);
725
726         prop = RNA_def_enum(ot->srna, "layers_select_dst", rna_enum_dt_layers_select_dst_items, DT_LAYERS_ACTIVE_DST,
727                             "Destination Layers Matching", "How to match source and destination layers");
728         RNA_def_property_enum_funcs_runtime(prop, NULL, NULL, dt_layers_select_dst_itemf);
729 }