2 * ***** BEGIN GPL LICENSE BLOCK *****
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.
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.
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.
18 * The Original Code is Copyright (C) 2014 by Blender Foundation.
19 * All rights reserved.
21 * The Original Code is: all of this file.
23 * Contributor(s): Bastien Montagne.
25 * ***** END GPL LICENSE BLOCK *****
28 /** \file blender/editors/object/object_data_transfer.c
32 #include "DNA_mesh_types.h"
33 #include "DNA_modifier_types.h"
34 #include "DNA_object_types.h"
35 #include "DNA_scene_types.h"
38 #include "BLI_blenlib.h"
39 #include "BLI_utildefines.h"
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"
50 #include "RNA_access.h"
51 #include "RNA_define.h"
52 #include "RNA_enum_types.h"
57 #include "ED_object.h"
59 #include "UI_interface.h"
61 #include "object_intern.h"
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"},
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"},
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}
92 /* Note: 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)
96 EnumPropertyItem *item = NULL, tmp_item = {0};
99 const int data_type = RNA_enum_get(ptr, "data_type");
101 if (!C) { /* needed for docs and i18n tools */
102 return DT_layers_select_src_items;
105 RNA_enum_items_add_value(&item, &totitem, DT_layers_select_src_items, DT_LAYERS_ACTIVE_SRC);
106 RNA_enum_items_add_value(&item, &totitem, DT_layers_select_src_items, DT_LAYERS_ALL_SRC);
108 if (data_type == DT_TYPE_MDEFORMVERT) {
109 Object *ob_src = CTX_data_active_object(C);
111 if (BKE_object_pose_armature_get(ob_src)) {
112 RNA_enum_items_add_value(&item, &totitem, DT_layers_select_src_items, DT_LAYERS_VGROUP_SRC_BONE_SELECT);
113 RNA_enum_items_add_value(&item, &totitem, DT_layers_select_src_items, DT_LAYERS_VGROUP_SRC_BONE_DEFORM);
120 RNA_enum_item_add_separator(&item, &totitem);
122 for (i = 0, dg = ob_src->defbase.first; dg; i++, dg = dg->next) {
124 tmp_item.identifier = tmp_item.name = dg->name;
125 RNA_enum_item_add(&item, &totitem, &tmp_item);
129 else if (data_type == DT_TYPE_SHAPEKEY) {
132 else if (data_type == DT_TYPE_UV) {
133 Object *ob_src = CTX_data_active_object(C);
134 Scene *scene = CTX_data_scene(C);
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);
146 RNA_enum_item_add_separator(&item, &totitem);
148 for (i = 0; i < num_data; 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);
155 else if (data_type == DT_TYPE_VCOL) {
156 Object *ob_src = CTX_data_active_object(C);
157 Scene *scene = CTX_data_scene(C);
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);
169 RNA_enum_item_add_separator(&item, &totitem);
171 for (i = 0; i < num_data; 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);
179 RNA_enum_item_end(&item, &totitem);
185 /* Note: DT_layers_select_dst_items enum is from rna_modifier.c */
186 static EnumPropertyItem *dt_layers_select_dst_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free)
188 EnumPropertyItem *item = NULL;
191 const int layers_select_src = RNA_enum_get(ptr, "layers_select_src");
193 if (!C) { /* needed for docs and i18n tools */
194 return DT_layers_select_dst_items;
197 if (layers_select_src == DT_LAYERS_ACTIVE_SRC || layers_select_src >= 0) {
198 RNA_enum_items_add_value(&item, &totitem, DT_layers_select_dst_items, DT_LAYERS_ACTIVE_DST);
200 RNA_enum_items_add_value(&item, &totitem, DT_layers_select_dst_items, DT_LAYERS_NAME_DST);
201 RNA_enum_items_add_value(&item, &totitem, DT_layers_select_dst_items, DT_LAYERS_INDEX_DST);
203 /* No 'specific' to-layers here, since we may transfer to several objects at once! */
205 RNA_enum_item_end(&item, &totitem);
211 /* Note: DT_mix_mode_items enum is from rna_modifier.c */
212 static EnumPropertyItem *dt_mix_mode_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free)
214 EnumPropertyItem *item = NULL;
217 const int dtdata_type = RNA_enum_get(ptr, "data_type");
218 bool support_advanced_mixing, support_threshold;
220 if (!C) { /* needed for docs and i18n tools */
221 return DT_mix_mode_items;
224 RNA_enum_items_add_value(&item, &totitem, DT_mix_mode_items, CDT_MIX_TRANSFER);
226 BKE_object_data_transfer_get_dttypes_capacity(dtdata_type, &support_advanced_mixing, &support_threshold);
228 if (support_threshold) {
229 RNA_enum_items_add_value(&item, &totitem, DT_mix_mode_items, CDT_MIX_REPLACE_ABOVE_THRESHOLD);
230 RNA_enum_items_add_value(&item, &totitem, DT_mix_mode_items, CDT_MIX_REPLACE_BELOW_THRESHOLD);
233 if (support_advanced_mixing) {
234 RNA_enum_item_add_separator(&item, &totitem);
235 RNA_enum_items_add_value(&item, &totitem, DT_mix_mode_items, CDT_MIX_MIX);
236 RNA_enum_items_add_value(&item, &totitem, DT_mix_mode_items, CDT_MIX_ADD);
237 RNA_enum_items_add_value(&item, &totitem, DT_mix_mode_items, CDT_MIX_SUB);
238 RNA_enum_items_add_value(&item, &totitem, DT_mix_mode_items, CDT_MIX_MUL);
241 RNA_enum_item_end(&item, &totitem);
247 static bool data_transfer_check(bContext *UNUSED(C), wmOperator *op)
249 const int layers_select_src = RNA_enum_get(op->ptr, "layers_select_src");
250 PropertyRNA *prop = RNA_struct_find_property(op->ptr, "layers_select_dst");
251 const int layers_select_dst = RNA_property_enum_get(op->ptr, prop);
253 /* TODO: check for invalid layers_src select modes too! */
255 if ((layers_select_src != DT_LAYERS_ACTIVE_SRC) && (layers_select_dst == DT_LAYERS_ACTIVE_DST)) {
256 RNA_property_enum_set(op->ptr, prop, DT_LAYERS_NAME_DST);
263 /* Helper, used by both data_transfer_exec and datalayout_transfer_exec. */
264 static void data_transfer_exec_preprocess_objects(
265 bContext *C, wmOperator *op, Object *ob_src, ListBase *ctx_objects, const bool reverse_transfer)
267 CollectionPointerLink *ctx_ob;
268 CTX_data_selected_editable_objects(C, ctx_objects);
270 if (reverse_transfer) {
271 return; /* Nothing else to do in this case... */
274 for (ctx_ob = ctx_objects->first; ctx_ob; ctx_ob = ctx_ob->next) {
275 Object *ob = ctx_ob->ptr.data;
277 if ((ob == ob_src) || (ob->type != OB_MESH)) {
283 /* Do not transfer to linked data, not supported. */
284 BKE_reportf(op->reports, RPT_WARNING, "Skipping object '%s', linked data '%s' cannot be modified",
285 ob->id.name + 2, me->id.name + 2);
286 me->id.flag &= ~LIB_DOIT;
290 me->id.flag |= LIB_DOIT;
294 /* Helper, used by both data_transfer_exec and datalayout_transfer_exec. */
295 static bool data_transfer_exec_is_object_valid(
296 wmOperator *op, Object *ob_src, Object *ob_dst, const bool reverse_transfer)
299 if ((ob_dst == ob_src) || (ob_src->type != OB_MESH) || (ob_dst->type != OB_MESH)) {
303 if (reverse_transfer) {
308 if (me->id.flag & LIB_DOIT) {
309 me->id.flag &= ~LIB_DOIT;
312 else if (me->id.lib == NULL) {
313 /* Do not transfer apply operation more than once. */
314 /* XXX This is not nice regarding vgroups, which are half-Object data... :/ */
315 BKE_reportf(op->reports, RPT_WARNING,
316 "Skipping object '%s', data '%s' has already been processed with a previous object",
317 ob_dst->id.name + 2, me->id.name + 2);
322 static int data_transfer_exec(bContext *C, wmOperator *op)
324 Scene *scene = CTX_data_scene(C);
325 Object *ob_src = ED_object_active_context(C);
327 ListBase ctx_objects;
328 CollectionPointerLink *ctx_ob_dst;
330 bool changed = false;
332 const bool reverse_transfer = RNA_boolean_get(op->ptr, "use_reverse_transfer");
334 const int data_type = RNA_enum_get(op->ptr, "data_type");
335 const bool use_create = RNA_boolean_get(op->ptr, "use_create");
337 const int map_vert_mode = RNA_enum_get(op->ptr, "vert_mapping");
338 const int map_edge_mode = RNA_enum_get(op->ptr, "edge_mapping");
339 const int map_loop_mode = RNA_enum_get(op->ptr, "loop_mapping");
340 const int map_poly_mode = RNA_enum_get(op->ptr, "poly_mapping");
342 const bool use_object_transform = RNA_boolean_get(op->ptr, "use_object_transform");
343 const bool use_max_distance = RNA_boolean_get(op->ptr, "use_max_distance");
344 const float max_distance = use_max_distance ? RNA_float_get(op->ptr, "max_distance") : FLT_MAX;
345 const float ray_radius = RNA_float_get(op->ptr, "ray_radius");
346 const float islands_precision = RNA_float_get(op->ptr, "islands_precision");
348 const int layers_src = RNA_enum_get(op->ptr, "layers_select_src");
349 const int layers_dst = RNA_enum_get(op->ptr, "layers_select_dst");
350 int layers_select_src[DT_MULTILAYER_INDEX_MAX] = {0};
351 int layers_select_dst[DT_MULTILAYER_INDEX_MAX] = {0};
352 const int fromto_idx = BKE_object_data_transfer_dttype_to_srcdst_index(data_type);
354 const int mix_mode = RNA_enum_get(op->ptr, "mix_mode");
355 const float mix_factor = RNA_float_get(op->ptr, "mix_factor");
357 SpaceTransform space_transform_data;
358 SpaceTransform *space_transform = use_object_transform ? &space_transform_data : NULL;
360 if (reverse_transfer && ((ID *)(ob_src->data))->lib) {
361 /* Do not transfer to linked data, not supported. */
362 return OPERATOR_CANCELLED;
365 if (fromto_idx != DT_MULTILAYER_INDEX_INVALID) {
366 layers_select_src[fromto_idx] = layers_src;
367 layers_select_dst[fromto_idx] = layers_dst;
370 data_transfer_exec_preprocess_objects(C, op, ob_src, &ctx_objects, reverse_transfer);
372 for (ctx_ob_dst = ctx_objects.first; ctx_ob_dst; ctx_ob_dst = ctx_ob_dst->next) {
373 Object *ob_dst = ctx_ob_dst->ptr.data;
375 if (reverse_transfer) {
376 SWAP(Object *, ob_src, ob_dst);
379 if (data_transfer_exec_is_object_valid(op, ob_src, ob_dst, reverse_transfer)) {
380 if (space_transform) {
381 BLI_SPACE_TRANSFORM_SETUP(space_transform, ob_dst, ob_src);
384 if (BKE_object_data_transfer_mesh(
385 scene, ob_src, ob_dst, data_type, use_create,
386 map_vert_mode, map_edge_mode, map_loop_mode, map_poly_mode,
387 space_transform, max_distance, ray_radius, islands_precision,
388 layers_select_src, layers_select_dst,
389 mix_mode, mix_factor, NULL, false, op->reports))
395 DAG_id_tag_update(&ob_dst->id, OB_RECALC_DATA);
397 if (reverse_transfer) {
398 SWAP(Object *, ob_src, ob_dst);
402 BLI_freelistN(&ctx_objects);
404 WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, NULL);
407 /* Note: issue with that is that if canceled, operator cannot be redone... Nasty in our case. */
408 return changed ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
411 return OPERATOR_FINISHED;
415 /* Used by both OBJECT_OT_data_transfer and OBJECT_OT_datalayout_transfer */
416 /* Note this context poll is only really partial, it cannot check for all possible invalid cases. */
417 static int data_transfer_poll(bContext *C)
419 Object *ob = ED_object_active_context(C);
420 ID *data = (ob) ? ob->data : NULL;
421 return (ob && ob->type == OB_MESH && data);
424 /* Used by both OBJECT_OT_data_transfer and OBJECT_OT_datalayout_transfer */
425 static bool data_transfer_draw_check_prop(PointerRNA *ptr, PropertyRNA *prop)
427 PropertyRNA *prop_other;
429 const char *prop_id = RNA_property_identifier(prop);
430 const int data_type = RNA_enum_get(ptr, "data_type");
431 bool use_max_distance = false;
432 bool use_modifier = false;
434 if ((prop_other = RNA_struct_find_property(ptr, "use_max_distance"))) {
435 use_max_distance = RNA_property_boolean_get(ptr, prop_other);
437 if ((prop_other = RNA_struct_find_property(ptr, "modifier"))) {
438 use_modifier = RNA_property_is_set(ptr, prop_other);
441 if (STREQ(prop_id, "modifier")) {
446 /* Hide everything but 'modifier' property, if set. */
450 if (STREQ(prop_id, "max_distance") && !use_max_distance) {
453 if (STREQ(prop_id, "islands_precision") && !DT_DATATYPE_IS_LOOP(data_type)) {
457 if (STREQ(prop_id, "vert_mapping") && !DT_DATATYPE_IS_VERT(data_type)) {
460 if (STREQ(prop_id, "edge_mapping") && !DT_DATATYPE_IS_EDGE(data_type)) {
463 if (STREQ(prop_id, "loop_mapping") && !DT_DATATYPE_IS_LOOP(data_type)) {
466 if (STREQ(prop_id, "poly_mapping") && !DT_DATATYPE_IS_POLY(data_type)) {
470 if ((STREQ(prop_id, "layers_select_src") || STREQ(prop_id, "layers_select_dst")) &&
471 !DT_DATATYPE_IS_MULTILAYERS(data_type))
480 /* Used by both OBJECT_OT_data_transfer and OBJECT_OT_datalayout_transfer */
481 static void data_transfer_ui(bContext *C, wmOperator *op)
483 uiLayout *layout = op->layout;
484 wmWindowManager *wm = CTX_wm_manager(C);
487 RNA_pointer_create(&wm->id, op->type->srna, op->properties, &ptr);
489 /* Main auto-draw call */
490 uiDefAutoButsRNA(layout, &ptr, data_transfer_draw_check_prop, '\0');
493 /* transfers weight from active to selected */
494 void OBJECT_OT_data_transfer(wmOperatorType *ot)
499 ot->name = "Transfer Mesh Data";
500 ot->idname = "OBJECT_OT_data_transfer";
501 ot->description = "Transfer data layer(s) (weights, edge sharp, ...) from active to selected meshes";
504 ot->poll = data_transfer_poll;
505 ot->invoke = WM_menu_invoke;
506 ot->exec = data_transfer_exec;
507 ot->check = data_transfer_check;
508 ot->ui = data_transfer_ui;
511 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
514 prop = RNA_def_boolean(ot->srna, "use_reverse_transfer", false, "Reverse Transfer",
515 "Transfer from selected objects to active one");
516 RNA_def_property_flag(prop, PROP_HIDDEN);
518 /* Data type to transfer. */
519 ot->prop = RNA_def_enum(ot->srna, "data_type", DT_layer_items, 0, "Data Type", "Which data to transfer");
520 RNA_def_boolean(ot->srna, "use_create", true, "Create Data", "Add data layers on destination meshes if needed");
522 /* Mapping methods. */
523 RNA_def_enum(ot->srna, "vert_mapping", DT_method_vertex_items, MREMAP_MODE_VERT_NEAREST, "Vertex Mapping",
524 "Method used to map source vertices to destination ones");
525 RNA_def_enum(ot->srna, "edge_mapping", DT_method_edge_items, MREMAP_MODE_EDGE_NEAREST, "Edge Mapping",
526 "Method used to map source edges to destination ones");
527 RNA_def_enum(ot->srna, "loop_mapping", DT_method_loop_items, MREMAP_MODE_LOOP_NEAREST_POLYNOR,
528 "Face Corner Mapping", "Method used to map source faces' corners to destination ones");
529 RNA_def_enum(ot->srna, "poly_mapping", DT_method_poly_items, MREMAP_MODE_POLY_NEAREST, "Face Mapping",
530 "Method used to map source faces to destination ones");
532 /* Mapping options and filtering. */
533 RNA_def_boolean(ot->srna, "use_object_transform", true, "Object Transform",
534 "Evaluate source and destination meshes in their respective object spaces");
535 RNA_def_boolean(ot->srna, "use_max_distance", false, "Only Neighbor Geometry",
536 "Source elements must be closer than given distance from destination one");
537 prop = RNA_def_float(ot->srna, "max_distance", 1.0f, 0.0f, FLT_MAX, "Max Distance",
538 "Maximum allowed distance between source and destination element, for non-topology mappings",
540 RNA_def_property_subtype(prop, PROP_DISTANCE);
541 prop = RNA_def_float(ot->srna, "ray_radius", 0.0f, 0.0f, FLT_MAX, "Ray Radius",
542 "'Width' of rays (especially useful when raycasting against vertices or edges)",
544 RNA_def_property_subtype(prop, PROP_DISTANCE);
545 prop = RNA_def_float(ot->srna, "islands_precision", 0.1f, 0.0f, 10.0f, "Islands Precision",
546 "Factor controlling precision of islands handling (the higher, the better the results)",
548 RNA_def_property_subtype(prop, PROP_FACTOR);
550 /* How to handle multi-layers types of data. */
551 prop = RNA_def_enum(ot->srna, "layers_select_src", DT_layers_select_src_items, DT_LAYERS_ACTIVE_SRC,
552 "Source Layers Selection", "Which layers to transfer, in case of multi-layers types");
553 RNA_def_property_enum_funcs_runtime(prop, NULL, NULL, dt_layers_select_src_itemf);
555 prop = RNA_def_enum(ot->srna, "layers_select_dst", DT_layers_select_dst_items, DT_LAYERS_ACTIVE_DST,
556 "Destination Layers Matching", "How to match source and destination layers");
557 RNA_def_property_enum_funcs_runtime(prop, NULL, NULL, dt_layers_select_dst_itemf);
559 prop = RNA_def_enum(ot->srna, "mix_mode", DT_mix_mode_items, CDT_MIX_TRANSFER, "Mix Mode",
560 "How to affect destination elements with source values");
561 RNA_def_property_enum_funcs_runtime(prop, NULL, NULL, dt_mix_mode_itemf);
562 RNA_def_float(ot->srna, "mix_factor", 1.0f, 0.0f, 1.0f, "Mix Factor",
563 "Factor to use when applying data to destination (exact behavior depends on mix mode)", 0.0f, 1.0f);
566 /******************************************************************************/
567 /* Note: This operator is hybrid, it can work as a usual standalone Object operator,
568 * or as a DataTransfer modifier tool.
571 static int datalayout_transfer_poll(bContext *C)
573 return (edit_modifier_poll_generic(C, &RNA_DataTransferModifier, (1 << OB_MESH)) || data_transfer_poll(C));
576 static int datalayout_transfer_exec(bContext *C, wmOperator *op)
578 Scene *scene = CTX_data_scene(C);
579 Object *ob_act = ED_object_active_context(C);
580 DataTransferModifierData *dtmd;
582 dtmd = (DataTransferModifierData *)edit_modifier_property_get(op, ob_act, eModifierType_DataTransfer);
584 /* If we have a modifier, we transfer data layout from this modifier's source object to active one.
585 * Else, we transfer data layout from active object to all selected ones. */
587 Object *ob_src = dtmd->ob_source;
588 Object *ob_dst = ob_act;
590 const bool use_delete = false; /* Never when used from modifier, for now. */
593 return OPERATOR_CANCELLED;
596 BKE_object_data_transfer_layout(scene, ob_src, ob_dst, dtmd->data_types, use_delete,
597 dtmd->layers_select_src, dtmd->layers_select_dst);
599 DAG_id_tag_update(&ob_dst->id, OB_RECALC_DATA);
602 Object *ob_src = ob_act;
604 ListBase ctx_objects;
605 CollectionPointerLink *ctx_ob_dst;
607 const int data_type = RNA_enum_get(op->ptr, "data_type");
608 const bool use_delete = RNA_boolean_get(op->ptr, "use_delete");
610 const int layers_src = RNA_enum_get(op->ptr, "layers_select_src");
611 const int layers_dst = RNA_enum_get(op->ptr, "layers_select_dst");
612 int layers_select_src[DT_MULTILAYER_INDEX_MAX] = {0};
613 int layers_select_dst[DT_MULTILAYER_INDEX_MAX] = {0};
614 const int fromto_idx = BKE_object_data_transfer_dttype_to_srcdst_index(data_type);
616 if (fromto_idx != DT_MULTILAYER_INDEX_INVALID) {
617 layers_select_src[fromto_idx] = layers_src;
618 layers_select_dst[fromto_idx] = layers_dst;
621 data_transfer_exec_preprocess_objects(C, op, ob_src, &ctx_objects, false);
623 for (ctx_ob_dst = ctx_objects.first; ctx_ob_dst; ctx_ob_dst = ctx_ob_dst->next) {
624 Object *ob_dst = ctx_ob_dst->ptr.data;
625 if (data_transfer_exec_is_object_valid(op, ob_src, ob_dst, false)) {
626 BKE_object_data_transfer_layout(scene, ob_src, ob_dst, data_type, use_delete,
627 layers_select_src, layers_select_dst);
630 DAG_id_tag_update(&ob_dst->id, OB_RECALC_DATA);
633 BLI_freelistN(&ctx_objects);
636 WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, NULL);
638 return OPERATOR_FINISHED;
641 static int datalayout_transfer_invoke(bContext *C, wmOperator *op, const wmEvent *event)
643 if (edit_modifier_invoke_properties(C, op)) {
644 return datalayout_transfer_exec(C, op);
647 return WM_menu_invoke(C, op, event);
651 void OBJECT_OT_datalayout_transfer(wmOperatorType *ot)
655 ot->name = "Transfer Mesh Data Layout";
656 ot->description = "Transfer layout of data layer(s) from active to selected meshes";
657 ot->idname = "OBJECT_OT_datalayout_transfer";
659 ot->poll = datalayout_transfer_poll;
660 ot->invoke = datalayout_transfer_invoke;
661 ot->exec = datalayout_transfer_exec;
662 ot->check = data_transfer_check;
663 ot->ui = data_transfer_ui;
666 ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
669 edit_modifier_properties(ot);
671 /* Data type to transfer. */
672 ot->prop = RNA_def_enum(ot->srna, "data_type", DT_layer_items, 0, "Data Type", "Which data to transfer");
673 RNA_def_boolean(ot->srna, "use_delete", false, "Exact Match",
674 "Also delete some data layers from destination if necessary, so that it matches exactly source");
676 /* How to handle multi-layers types of data. */
677 prop = RNA_def_enum(ot->srna, "layers_select_src", DT_layers_select_src_items, DT_LAYERS_ACTIVE_SRC,
678 "Source Layers Selection", "Which layers to transfer, in case of multi-layers types");
679 RNA_def_property_enum_funcs_runtime(prop, NULL, NULL, dt_layers_select_src_itemf);
681 prop = RNA_def_enum(ot->srna, "layers_select_dst", DT_layers_select_dst_items, DT_LAYERS_ACTIVE_DST,
682 "Destination Layers Matching", "How to match source and destination layers");
683 RNA_def_property_enum_funcs_runtime(prop, NULL, NULL, dt_layers_select_dst_itemf);