Blender  V3.3
object_data_transfer.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2014 Blender Foundation. All rights reserved. */
3 
8 #include "DNA_mesh_types.h"
9 #include "DNA_modifier_types.h"
10 #include "DNA_object_types.h"
11 #include "DNA_scene_types.h"
12 
13 #include "BLI_blenlib.h"
14 #include "BLI_math.h"
15 #include "BLI_string.h"
16 #include "BLI_utildefines.h"
17 
18 #include "BKE_context.h"
19 #include "BKE_data_transfer.h"
20 #include "BKE_deform.h"
21 #include "BKE_mesh_mapping.h"
22 #include "BKE_mesh_remap.h"
23 #include "BKE_mesh_runtime.h"
24 #include "BKE_object.h"
25 #include "BKE_report.h"
26 
27 #include "DEG_depsgraph.h"
28 #include "DEG_depsgraph_query.h"
29 
30 #include "BLT_translation.h"
31 
32 #include "RNA_access.h"
33 #include "RNA_define.h"
34 #include "RNA_enum_types.h"
35 #include "RNA_prototypes.h"
36 
37 #include "WM_api.h"
38 #include "WM_types.h"
39 
40 #include "ED_object.h"
41 
42 #include "object_intern.h"
43 
44 /* All possible data to transfer.
45  * Note some are 'fake' ones, i.e. they are not hold by real CDLayers. */
46 /* Not shared with modifier, since we use a usual enum here, not a multi-choice one. */
47 static const EnumPropertyItem DT_layer_items[] = {
48  RNA_ENUM_ITEM_HEADING(N_("Vertex Data"), NULL),
50  "VGROUP_WEIGHTS",
51  0,
52  "Vertex Group(s)",
53  "Transfer active or all vertex groups"},
54 #if 0 /* XXX For now, would like to finish/merge work from 2014 GSOC first. */
55  {DT_TYPE_SHAPEKEY, "SHAPEKEYS", 0, "Shapekey(s)", "Transfer active or all shape keys"},
56 #endif
57 /* XXX When SkinModifier is enabled,
58  * it seems to erase its own CD_MVERT_SKIN layer from final DM :( */
59 #if 0
60  {DT_TYPE_SKIN, "SKIN", 0, "Skin Weight", "Transfer skin weights"},
61 #endif
62  {DT_TYPE_BWEIGHT_VERT, "BEVEL_WEIGHT_VERT", 0, "Bevel Weight", "Transfer bevel weights"},
64  "COLOR_VERTEX",
65  0,
66  "Colors",
67  "Color Attributes"},
68 
69  RNA_ENUM_ITEM_HEADING(N_("Edge Data"), NULL),
70  {DT_TYPE_SHARP_EDGE, "SHARP_EDGE", 0, "Sharp", "Transfer sharp mark"},
71  {DT_TYPE_SEAM, "SEAM", 0, "UV Seam", "Transfer UV seam mark"},
72  {DT_TYPE_CREASE, "CREASE", 0, "Subdivision Crease", "Transfer crease values"},
73  {DT_TYPE_BWEIGHT_EDGE, "BEVEL_WEIGHT_EDGE", 0, "Bevel Weight", "Transfer bevel weights"},
75  "FREESTYLE_EDGE",
76  0,
77  "Freestyle Mark",
78  "Transfer Freestyle edge mark"},
79 
80  RNA_ENUM_ITEM_HEADING(N_("Face Corner Data"), NULL),
81  {DT_TYPE_LNOR, "CUSTOM_NORMAL", 0, "Custom Normals", "Transfer custom normals"},
83  "COLOR_CORNER",
84  0,
85  "Colors",
86  "Color Attributes"},
87  {DT_TYPE_UV, "UV", 0, "UVs", "Transfer UV layers"},
88 
89  RNA_ENUM_ITEM_HEADING(N_("Face Data"), NULL),
90  {DT_TYPE_SHARP_FACE, "SMOOTH", 0, "Smooth", "Transfer flat/smooth mark"},
92  "FREESTYLE_FACE",
93  0,
94  "Freestyle Mark",
95  "Transfer Freestyle face mark"},
96  {0, NULL, 0, NULL, NULL},
97 };
98 
99 static void dt_add_vcol_layers(CustomData *cdata,
101  EnumPropertyItem **r_item,
102  int *r_totitem)
103 {
105  int idx = 0;
106  for (int i = 0; i < 2; i++) {
108 
109  if (!(mask & CD_TYPE_AS_MASK(type))) {
110  continue;
111  }
112 
113  int num_data = CustomData_number_of_layers(cdata, type);
114 
115  RNA_enum_item_add_separator(r_item, r_totitem);
116 
117  for (int j = 0; j < num_data; j++) {
118  EnumPropertyItem tmp_item = {0};
119  tmp_item.value = idx++;
120  tmp_item.identifier = tmp_item.name = CustomData_get_layer_name(cdata, type, j);
121  RNA_enum_item_add(r_item, r_totitem, &tmp_item);
122  }
123  }
124 }
125 /* NOTE: #rna_enum_dt_layers_select_src_items enum is from rna_modifier.c. */
127  PointerRNA *ptr,
128  PropertyRNA *UNUSED(prop),
129  bool *r_free)
130 {
131  if (!C) { /* needed for docs and i18n tools */
133  }
134 
135  EnumPropertyItem *item = NULL, tmp_item = {0};
136  int totitem = 0;
137  const int data_type = RNA_enum_get(ptr, "data_type");
138 
139  PropertyRNA *prop = RNA_struct_find_property(ptr, "use_reverse_transfer");
140  const bool reverse_transfer = prop != NULL && RNA_property_boolean_get(ptr, prop);
141  const int layers_select_dst = reverse_transfer ? RNA_enum_get(ptr, "layers_select_src") :
142  RNA_enum_get(ptr, "layers_select_dst");
143 
144  if (!reverse_transfer || layers_select_dst == DT_LAYERS_ACTIVE_DST || layers_select_dst >= 0) {
147  }
150 
151  Object *ob_src = ED_object_active_context(C);
152  if (ob_src == NULL) {
153  RNA_enum_item_end(&item, &totitem);
154  *r_free = true;
155  return item;
156  }
157 
158  if (data_type == DT_TYPE_MDEFORMVERT && BKE_object_supports_vertex_groups(ob_src)) {
159  if (BKE_object_pose_armature_get(ob_src)) {
164  }
165 
166  const bDeformGroup *dg;
167  int i;
168 
169  RNA_enum_item_add_separator(&item, &totitem);
170 
171  const ListBase *defbase = BKE_object_defgroup_list(ob_src);
172  for (i = 0, dg = defbase->first; dg; i++, dg = dg->next) {
173  tmp_item.value = i;
174  tmp_item.identifier = tmp_item.name = dg->name;
175  RNA_enum_item_add(&item, &totitem, &tmp_item);
176  }
177  }
178  else if (data_type == DT_TYPE_SHAPEKEY) {
179  /* TODO */
180  }
181  else if (data_type == DT_TYPE_UV) {
183  Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
184  Object *ob_src_eval = DEG_get_evaluated_object(depsgraph, ob_src);
185 
186  CustomData_MeshMasks cddata_masks = CD_MASK_BAREMESH;
187  cddata_masks.lmask |= CD_MASK_MLOOPUV;
188  Mesh *me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_src_eval, &cddata_masks);
189  int num_data = CustomData_number_of_layers(&me_eval->ldata, CD_MLOOPUV);
190 
191  RNA_enum_item_add_separator(&item, &totitem);
192 
193  for (int i = 0; i < num_data; i++) {
194  tmp_item.value = i;
195  tmp_item.identifier = tmp_item.name = CustomData_get_layer_name(
196  &me_eval->ldata, CD_MLOOPUV, i);
197  RNA_enum_item_add(&item, &totitem, &tmp_item);
198  }
199  }
200  else if (data_type & DT_TYPE_VCOL_ALL) {
202  Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
203  Object *ob_src_eval = DEG_get_evaluated_object(depsgraph, ob_src);
204 
205  CustomData_MeshMasks cddata_masks = CD_MASK_BAREMESH;
206  if (data_type & (DT_TYPE_MPROPCOL_VERT)) {
207  cddata_masks.vmask |= CD_MASK_PROP_COLOR;
208  }
209  if (data_type & (DT_TYPE_MLOOPCOL_VERT)) {
210  cddata_masks.vmask |= CD_MASK_PROP_BYTE_COLOR;
211  }
212 
213  if (data_type & (DT_TYPE_MPROPCOL_LOOP)) {
214  cddata_masks.lmask |= CD_MASK_PROP_COLOR;
215  }
216  if (data_type & (DT_TYPE_MLOOPCOL_LOOP)) {
217  cddata_masks.lmask |= CD_MASK_PROP_BYTE_COLOR;
218  }
219 
220  Mesh *me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_src_eval, &cddata_masks);
221 
222  if (data_type & (DT_TYPE_MLOOPCOL_VERT | DT_TYPE_MPROPCOL_VERT)) {
223  dt_add_vcol_layers(&me_eval->vdata, cddata_masks.vmask, &item, &totitem);
224  }
225  if (data_type & (DT_TYPE_MLOOPCOL_LOOP | DT_TYPE_MPROPCOL_LOOP)) {
226  dt_add_vcol_layers(&me_eval->ldata, cddata_masks.lmask, &item, &totitem);
227  }
228  }
229 
230  RNA_enum_item_end(&item, &totitem);
231  *r_free = true;
232 
233  return item;
234 }
235 
236 /* NOTE: #rna_enum_dt_layers_select_dst_items enum is from `rna_modifier.c`. */
238  PointerRNA *ptr,
239  PropertyRNA *UNUSED(prop),
240  bool *r_free)
241 {
242  if (!C) { /* needed for docs and i18n tools */
244  }
245 
246  EnumPropertyItem *item = NULL;
247  int totitem = 0;
248 
249  PropertyRNA *prop = RNA_struct_find_property(ptr, "use_reverse_transfer");
250  const bool reverse_transfer = prop != NULL && RNA_property_boolean_get(ptr, prop);
251  const int layers_select_src = reverse_transfer ? RNA_enum_get(ptr, "layers_select_dst") :
252  RNA_enum_get(ptr, "layers_select_src");
253 
254  if (reverse_transfer || layers_select_src == DT_LAYERS_ACTIVE_SRC || layers_select_src >= 0) {
257  }
262 
263  /* No 'specific' to-layers here, since we may transfer to several objects at once! */
264 
265  RNA_enum_item_end(&item, &totitem);
266  *r_free = true;
267 
268  return item;
269 }
270 
272  PointerRNA *ptr,
273  PropertyRNA *prop,
274  bool *r_free)
275 {
276  const bool reverse_transfer = RNA_boolean_get(ptr, "use_reverse_transfer");
277 
278  if (STREQ(RNA_property_identifier(prop), "layers_select_dst")) {
279  if (reverse_transfer) {
280  return dt_layers_select_src_itemf(C, ptr, prop, r_free);
281  }
282  return dt_layers_select_dst_itemf(C, ptr, prop, r_free);
283  }
284  if (reverse_transfer) {
285  return dt_layers_select_dst_itemf(C, ptr, prop, r_free);
286  }
287  return dt_layers_select_src_itemf(C, ptr, prop, r_free);
288 }
289 
290 /* NOTE: rna_enum_dt_mix_mode_items enum is from `rna_modifier.c`. */
292  PointerRNA *ptr,
293  PropertyRNA *UNUSED(prop),
294  bool *r_free)
295 {
296  EnumPropertyItem *item = NULL;
297  int totitem = 0;
298 
299  const int dtdata_type = RNA_enum_get(ptr, "data_type");
300  bool support_advanced_mixing, support_threshold;
301 
302  if (!C) { /* needed for docs and i18n tools */
304  }
305 
307 
309  dtdata_type, &support_advanced_mixing, &support_threshold);
310 
311  if (support_threshold) {
316  }
317 
318  if (support_advanced_mixing) {
319  RNA_enum_item_add_separator(&item, &totitem);
324  }
325 
326  RNA_enum_item_end(&item, &totitem);
327  *r_free = true;
328 
329  return item;
330 }
331 
333 {
334  const int layers_select_src = RNA_enum_get(op->ptr, "layers_select_src");
335  PropertyRNA *prop = RNA_struct_find_property(op->ptr, "layers_select_dst");
336  const int layers_select_dst = RNA_property_enum_get(op->ptr, prop);
337 
338  /* TODO: check for invalid layers_src select modes too! */
339 
340  if ((layers_select_src != DT_LAYERS_ACTIVE_SRC) && (layers_select_dst == DT_LAYERS_ACTIVE_DST)) {
342  return true;
343  }
344 
345  return false;
346 }
347 
348 /* Helper, used by both data_transfer_exec and datalayout_transfer_exec. */
350  wmOperator *op,
351  Object *ob_src,
352  ListBase *ctx_objects,
353  const bool reverse_transfer)
354 {
355  CollectionPointerLink *ctx_ob;
357 
358  if (reverse_transfer) {
359  return; /* Nothing else to do in this case... */
360  }
361 
362  for (ctx_ob = ctx_objects->first; ctx_ob; ctx_ob = ctx_ob->next) {
363  Object *ob = ctx_ob->ptr.data;
364  Mesh *me;
365  if ((ob == ob_src) || (ob->type != OB_MESH)) {
366  continue;
367  }
368 
369  me = ob->data;
370  if (ID_IS_LINKED(me) || ID_IS_OVERRIDE_LIBRARY(me)) {
371  /* Do not transfer to linked/override data, not supported. */
372  BKE_reportf(op->reports,
373  RPT_WARNING,
374  "Skipping object '%s', linked or override data '%s' cannot be modified",
375  ob->id.name + 2,
376  me->id.name + 2);
377  me->id.tag &= ~LIB_TAG_DOIT;
378  continue;
379  }
380 
381  me->id.tag |= LIB_TAG_DOIT;
382  }
383 }
384 
385 /* Helper, used by both data_transfer_exec and datalayout_transfer_exec. */
387  Object *ob_src,
388  Object *ob_dst,
389  const bool reverse_transfer)
390 {
391  Mesh *me;
392  if ((ob_dst == ob_src) || (ob_src->type != OB_MESH) || (ob_dst->type != OB_MESH)) {
393  return false;
394  }
395 
396  if (reverse_transfer) {
397  return true;
398  }
399 
400  me = ob_dst->data;
401  if (me->id.tag & LIB_TAG_DOIT) {
402  me->id.tag &= ~LIB_TAG_DOIT;
403  return true;
404  }
405  if (!ID_IS_LINKED(me) && !ID_IS_OVERRIDE_LIBRARY(me)) {
406  /* Do not apply transfer operation more than once. */
407  /* XXX This is not nice regarding vgroups, which are half-Object data... :/ */
408  BKE_reportf(
409  op->reports,
410  RPT_WARNING,
411  "Skipping object '%s', data '%s' has already been processed with a previous object",
412  ob_dst->id.name + 2,
413  me->id.name + 2);
414  }
415  return false;
416 }
417 
419 {
420  Object *ob_src = ED_object_active_context(C);
422  Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
423 
424  ListBase ctx_objects;
425  CollectionPointerLink *ctx_ob_dst;
426 
427  bool changed = false;
428 
429  const bool is_frozen = RNA_boolean_get(op->ptr, "use_freeze");
430 
431  const bool reverse_transfer = RNA_boolean_get(op->ptr, "use_reverse_transfer");
432 
433  const int data_type = RNA_enum_get(op->ptr, "data_type");
434  const bool use_create = RNA_boolean_get(op->ptr, "use_create");
435 
436  const int map_vert_mode = RNA_enum_get(op->ptr, "vert_mapping");
437  const int map_edge_mode = RNA_enum_get(op->ptr, "edge_mapping");
438  const int map_loop_mode = RNA_enum_get(op->ptr, "loop_mapping");
439  const int map_poly_mode = RNA_enum_get(op->ptr, "poly_mapping");
440 
441  const bool use_auto_transform = RNA_boolean_get(op->ptr, "use_auto_transform");
442  const bool use_object_transform = RNA_boolean_get(op->ptr, "use_object_transform");
443  const bool use_max_distance = RNA_boolean_get(op->ptr, "use_max_distance");
444  const float max_distance = use_max_distance ? RNA_float_get(op->ptr, "max_distance") : FLT_MAX;
445  const float ray_radius = RNA_float_get(op->ptr, "ray_radius");
446  const float islands_precision = RNA_float_get(op->ptr, "islands_precision");
447 
448  int layers_src = RNA_enum_get(op->ptr, "layers_select_src");
449  int layers_dst = RNA_enum_get(op->ptr, "layers_select_dst");
450  int layers_select_src[DT_MULTILAYER_INDEX_MAX] = {0};
451  int layers_select_dst[DT_MULTILAYER_INDEX_MAX] = {0};
452  const int fromto_idx = BKE_object_data_transfer_dttype_to_srcdst_index(data_type);
453 
454  const int mix_mode = RNA_enum_get(op->ptr, "mix_mode");
455  const float mix_factor = RNA_float_get(op->ptr, "mix_factor");
456 
457  SpaceTransform space_transform_data;
458  SpaceTransform *space_transform = (use_object_transform && !use_auto_transform) ?
459  &space_transform_data :
460  NULL;
461 
462  if (is_frozen) {
463  BKE_report(
464  op->reports,
465  RPT_INFO,
466  "Operator is frozen, changes to its settings won't take effect until you unfreeze it");
467  return OPERATOR_FINISHED;
468  }
469 
470  if (reverse_transfer && (ID_IS_LINKED(ob_src->data) || ID_IS_OVERRIDE_LIBRARY(ob_src->data))) {
471  /* Do not transfer to linked or override data, not supported. */
472  return OPERATOR_CANCELLED;
473  }
474 
475  if (reverse_transfer) {
476  SWAP(int, layers_src, layers_dst);
477  }
478 
479  if (fromto_idx != DT_MULTILAYER_INDEX_INVALID) {
480  layers_select_src[fromto_idx] = layers_src;
481  layers_select_dst[fromto_idx] = layers_dst;
482  }
483 
484  data_transfer_exec_preprocess_objects(C, op, ob_src, &ctx_objects, reverse_transfer);
485 
486  for (ctx_ob_dst = ctx_objects.first; ctx_ob_dst; ctx_ob_dst = ctx_ob_dst->next) {
487  Object *ob_dst = ctx_ob_dst->ptr.data;
488 
489  if (reverse_transfer) {
490  SWAP(Object *, ob_src, ob_dst);
491  }
492 
493  if (data_transfer_exec_is_object_valid(op, ob_src, ob_dst, reverse_transfer)) {
494  Object *ob_src_eval = DEG_get_evaluated_object(depsgraph, ob_src);
495 
496  if (space_transform) {
497  Object *ob_dst_eval = DEG_get_evaluated_object(depsgraph, ob_dst);
498  BLI_SPACE_TRANSFORM_SETUP(space_transform, ob_dst_eval, ob_src_eval);
499  }
500 
502  scene_eval,
503  ob_src_eval,
504  ob_dst,
505  data_type,
506  use_create,
507  map_vert_mode,
508  map_edge_mode,
509  map_loop_mode,
510  map_poly_mode,
511  space_transform,
512  use_auto_transform,
513  max_distance,
514  ray_radius,
515  islands_precision,
516  layers_select_src,
517  layers_select_dst,
518  mix_mode,
519  mix_factor,
520  NULL,
521  false,
522  op->reports)) {
523 
524  if (data_type == DT_TYPE_LNOR && use_create) {
525  ((Mesh *)ob_dst->data)->flag |= ME_AUTOSMOOTH;
526  }
527 
529  changed = true;
530  }
531  }
532 
533  if (reverse_transfer) {
534  SWAP(Object *, ob_src, ob_dst);
535  }
536  }
537 
538  BLI_freelistN(&ctx_objects);
539 
540  if (changed) {
543  }
544 
545 #if 0 /* TODO */
546  /* NOTE: issue with that is that if canceled, operator cannot be redone... Nasty in our case. */
547  return changed ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
548 #else
549  return OPERATOR_FINISHED;
550 #endif
551 }
552 
553 /* Used by both OBJECT_OT_data_transfer and OBJECT_OT_datalayout_transfer */
554 /* Note this context poll is only really partial,
555  * it cannot check for all possible invalid cases. */
557 {
559  ID *data = (ob) ? ob->data : NULL;
560  return (ob != NULL && ob->type == OB_MESH && data != NULL);
561 }
562 
563 /* Used by both OBJECT_OT_data_transfer and OBJECT_OT_datalayout_transfer */
565  wmOperator *op,
566  const PropertyRNA *prop)
567 {
568  PointerRNA *ptr = op->ptr;
569  PropertyRNA *prop_other;
570 
571  const char *prop_id = RNA_property_identifier(prop);
572  const int data_type = RNA_enum_get(ptr, "data_type");
573  bool use_auto_transform = false;
574  bool use_max_distance = false;
575  bool use_modifier = false;
576 
577  if ((prop_other = RNA_struct_find_property(ptr, "use_auto_transform"))) {
578  use_auto_transform = RNA_property_boolean_get(ptr, prop_other);
579  }
580  if ((prop_other = RNA_struct_find_property(ptr, "use_max_distance"))) {
581  use_max_distance = RNA_property_boolean_get(ptr, prop_other);
582  }
583  if ((prop_other = RNA_struct_find_property(ptr, "modifier"))) {
584  use_modifier = RNA_property_is_set(ptr, prop_other);
585  }
586 
587  if (STREQ(prop_id, "modifier")) {
588  return use_modifier;
589  }
590 
591  if (use_modifier) {
592  /* Hide everything but 'modifier' property, if set. */
593  return false;
594  }
595 
596  if (STREQ(prop_id, "use_object_transform")) {
597  if (use_auto_transform) {
598  return false;
599  }
600  }
601  else if (STREQ(prop_id, "max_distance")) {
602  if (!use_max_distance) {
603  return false;
604  }
605  }
606  else if (STREQ(prop_id, "islands_precision")) {
607  if (!DT_DATATYPE_IS_LOOP(data_type)) {
608  return false;
609  }
610  }
611  else if (STREQ(prop_id, "vert_mapping")) {
612  if (!DT_DATATYPE_IS_VERT(data_type)) {
613  return false;
614  }
615  }
616  else if (STREQ(prop_id, "edge_mapping")) {
617  if (!DT_DATATYPE_IS_EDGE(data_type)) {
618  return false;
619  }
620  }
621  else if (STREQ(prop_id, "loop_mapping")) {
622  if (!DT_DATATYPE_IS_LOOP(data_type)) {
623  return false;
624  }
625  }
626  else if (STREQ(prop_id, "poly_mapping")) {
627  if (!DT_DATATYPE_IS_POLY(data_type)) {
628  return false;
629  }
630  }
631  else if (STR_ELEM(prop_id, "layers_select_src", "layers_select_dst")) {
632  if (!DT_DATATYPE_IS_MULTILAYERS(data_type)) {
633  return false;
634  }
635  }
636 
637  /* Else, show it! */
638  return true;
639 }
640 
643  PointerRNA *ptr)
644 {
645  const bool reverse_transfer = RNA_boolean_get(ptr, "use_reverse_transfer");
646 
647  if (reverse_transfer) {
648  return BLI_strdup(TIP_(
649  "Transfer data layer(s) (weights, edge sharp, etc.) from selected meshes to active one"));
650  }
651 
652  return NULL;
653 }
654 
656 {
657  PropertyRNA *prop;
658 
659  /* Identifiers. */
660  ot->name = "Transfer Mesh Data";
661  ot->idname = "OBJECT_OT_data_transfer";
662  ot->description =
663  "Transfer data layer(s) (weights, edge sharp, etc.) from active to selected meshes";
664 
665  /* API callbacks. */
672 
673  /* Flags. */
675 
676  /* Properties. */
677  prop = RNA_def_boolean(ot->srna,
678  "use_reverse_transfer",
679  false,
680  "Reverse Transfer",
681  "Transfer from selected objects to active one");
683 
685  "use_freeze",
686  false,
687  "Freeze Operator",
688  "Prevent changes to settings to re-run the operator, "
689  "handy to change several things at once with heavy geometry");
690 
691  /* Data type to transfer. */
692  ot->prop = RNA_def_enum(
693  ot->srna, "data_type", DT_layer_items, 0, "Data Type", "Which data to transfer");
695  "use_create",
696  true,
697  "Create Data",
698  "Add data layers on destination meshes if needed");
699 
700  /* Mapping methods. */
702  "vert_mapping",
705  "Vertex Mapping",
706  "Method used to map source vertices to destination ones");
708  "edge_mapping",
711  "Edge Mapping",
712  "Method used to map source edges to destination ones");
714  "loop_mapping",
717  "Face Corner Mapping",
718  "Method used to map source faces' corners to destination ones");
720  "poly_mapping",
723  "Face Mapping",
724  "Method used to map source faces to destination ones");
725 
726  /* Mapping options and filtering. */
728  ot->srna,
729  "use_auto_transform",
730  false,
731  "Auto Transform",
732  "Automatically compute transformation to get the best possible match between source and "
733  "destination meshes.\n"
734  "Warning: Results will never be as good as manual matching of objects");
736  "use_object_transform",
737  true,
738  "Object Transform",
739  "Evaluate source and destination meshes in global space");
741  "use_max_distance",
742  false,
743  "Only Neighbor Geometry",
744  "Source elements must be closer than given distance from destination one");
745  prop = RNA_def_float(
746  ot->srna,
747  "max_distance",
748  1.0f,
749  0.0f,
750  FLT_MAX,
751  "Max Distance",
752  "Maximum allowed distance between source and destination element, for non-topology mappings",
753  0.0f,
754  100.0f);
756  prop = RNA_def_float(
757  ot->srna,
758  "ray_radius",
759  0.0f,
760  0.0f,
761  FLT_MAX,
762  "Ray Radius",
763  "'Width' of rays (especially useful when raycasting against vertices or edges)",
764  0.0f,
765  10.0f);
767  prop = RNA_def_float(
768  ot->srna,
769  "islands_precision",
770  0.1f,
771  0.0f,
772  10.0f,
773  "Islands Precision",
774  "Factor controlling precision of islands handling (the higher, the better the results)",
775  0.0f,
776  1.0f);
778 
779  /* How to handle multi-layers types of data. */
780  prop = RNA_def_enum(ot->srna,
781  "layers_select_src",
784  "Source Layers Selection",
785  "Which layers to transfer, in case of multi-layers types");
787 
788  prop = RNA_def_enum(ot->srna,
789  "layers_select_dst",
792  "Destination Layers Matching",
793  "How to match source and destination layers");
795 
796  prop = RNA_def_enum(ot->srna,
797  "mix_mode",
800  "Mix Mode",
801  "How to affect destination elements with source values");
804  ot->srna,
805  "mix_factor",
806  1.0f,
807  0.0f,
808  1.0f,
809  "Mix Factor",
810  "Factor to use when applying data to destination (exact behavior depends on mix mode)",
811  0.0f,
812  1.0f);
813 }
814 
815 /******************************************************************************/
816 /* NOTE: This operator is hybrid, it can work as a usual standalone Object operator,
817  * or as a DataTransfer modifier tool.
818  */
819 
821 {
822  return (edit_modifier_poll_generic(C, &RNA_DataTransferModifier, (1 << OB_MESH), true, false) ||
824 }
825 
827 {
828  Object *ob_act = ED_object_active_context(C);
830  Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
832 
834  op, ob_act, eModifierType_DataTransfer);
835 
836  /* If we have a modifier, we transfer data layout from this modifier's source object to
837  * active one. Else, we transfer data layout from active object to all selected ones. */
838  if (dtmd) {
839  Object *ob_src = dtmd->ob_source;
840  Object *ob_dst = ob_act;
841 
842  const bool use_delete = false; /* Never when used from modifier, for now. */
843 
844  if (!ob_src || ID_IS_LINKED(ob_dst) || ID_IS_OVERRIDE_LIBRARY(ob_dst)) {
845  return OPERATOR_CANCELLED;
846  }
847 
848  Object *ob_src_eval = DEG_get_evaluated_object(depsgraph, ob_src);
849 
851  scene_eval,
852  ob_src_eval,
853  ob_dst,
854  dtmd->data_types,
855  use_delete,
856  dtmd->layers_select_src,
857  dtmd->layers_select_dst);
858 
860  }
861  else {
862  Object *ob_src = ob_act;
863 
864  ListBase ctx_objects;
865  CollectionPointerLink *ctx_ob_dst;
866 
867  const int data_type = RNA_enum_get(op->ptr, "data_type");
868  const bool use_delete = RNA_boolean_get(op->ptr, "use_delete");
869 
870  const int layers_src = RNA_enum_get(op->ptr, "layers_select_src");
871  const int layers_dst = RNA_enum_get(op->ptr, "layers_select_dst");
872  int layers_select_src[DT_MULTILAYER_INDEX_MAX] = {0};
873  int layers_select_dst[DT_MULTILAYER_INDEX_MAX] = {0};
874  const int fromto_idx = BKE_object_data_transfer_dttype_to_srcdst_index(data_type);
875 
876  if (fromto_idx != DT_MULTILAYER_INDEX_INVALID) {
877  layers_select_src[fromto_idx] = layers_src;
878  layers_select_dst[fromto_idx] = layers_dst;
879  }
880 
881  Object *ob_src_eval = DEG_get_evaluated_object(depsgraph, ob_src);
882 
883  data_transfer_exec_preprocess_objects(C, op, ob_src, &ctx_objects, false);
884 
885  for (ctx_ob_dst = ctx_objects.first; ctx_ob_dst; ctx_ob_dst = ctx_ob_dst->next) {
886  Object *ob_dst = ctx_ob_dst->ptr.data;
887  if (data_transfer_exec_is_object_valid(op, ob_src, ob_dst, false)) {
889  scene_eval,
890  ob_src_eval,
891  ob_dst,
892  data_type,
893  use_delete,
894  layers_select_src,
895  layers_select_dst);
896  }
897 
899  }
900 
901  BLI_freelistN(&ctx_objects);
902  }
903 
906 
907  return OPERATOR_FINISHED;
908 }
909 
910 static int datalayout_transfer_invoke(bContext *C, wmOperator *op, const wmEvent *event)
911 {
913  return datalayout_transfer_exec(C, op);
914  }
915  return WM_menu_invoke(C, op, event);
916 }
917 
919 {
920  PropertyRNA *prop;
921 
922  ot->name = "Transfer Mesh Data Layout";
923  ot->description = "Transfer layout of data layer(s) from active to selected meshes";
924  ot->idname = "OBJECT_OT_datalayout_transfer";
925 
931 
932  /* flags */
934 
935  /* Properties. */
937 
938  /* Data type to transfer. */
939  ot->prop = RNA_def_enum(
940  ot->srna, "data_type", DT_layer_items, 0, "Data Type", "Which data to transfer");
942  "use_delete",
943  false,
944  "Exact Match",
945  "Also delete some data layers from destination if necessary, so that it matches "
946  "exactly source");
947 
948  /* How to handle multi-layers types of data. */
949  prop = RNA_def_enum(ot->srna,
950  "layers_select_src",
953  "Source Layers Selection",
954  "Which layers to transfer, in case of multi-layers types");
956 
957  prop = RNA_def_enum(ot->srna,
958  "layers_select_dst",
961  "Destination Layers Matching",
962  "How to match source and destination layers");
964 }
struct Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
Definition: context.c:1528
int CTX_data_selected_editable_objects(const bContext *C, ListBase *list)
Definition: context.c:1303
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1074
const char * CustomData_get_layer_name(const struct CustomData *data, int type, int n)
int CustomData_number_of_layers(const struct CustomData *data, int type)
const CustomData_MeshMasks CD_MASK_BAREMESH
Definition: customdata.cc:2051
uint64_t eCustomDataMask
@ CDT_MIX_SUB
@ CDT_MIX_REPLACE_BELOW_THRESHOLD
@ CDT_MIX_REPLACE_ABOVE_THRESHOLD
@ CDT_MIX_ADD
@ CDT_MIX_MUL
@ CDT_MIX_TRANSFER
@ CDT_MIX_MIX
#define CD_TYPE_AS_MASK(_type)
@ DT_MULTILAYER_INDEX_MAX
@ DT_MULTILAYER_INDEX_INVALID
@ DT_LAYERS_VGROUP_SRC_BONE_SELECT
@ DT_LAYERS_VGROUP_SRC_BONE_DEFORM
@ DT_LAYERS_ALL_SRC
@ DT_LAYERS_ACTIVE_SRC
#define DT_DATATYPE_IS_POLY(_dt)
int BKE_object_data_transfer_dttype_to_srcdst_index(int dtdata_type)
#define DT_DATATYPE_IS_MULTILAYERS(_dt)
void BKE_object_data_transfer_layout(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob_src, struct Object *ob_dst, int data_types, bool use_delete, const int fromlayers_select[DT_MULTILAYER_INDEX_MAX], const int tolayers_select[DT_MULTILAYER_INDEX_MAX])
#define DT_DATATYPE_IS_LOOP(_dt)
#define DT_DATATYPE_IS_EDGE(_dt)
bool BKE_object_data_transfer_get_dttypes_capacity(int dtdata_types, bool *r_advanced_mixing, bool *r_threshold)
Definition: data_transfer.c:80
bool BKE_object_data_transfer_mesh(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob_src, struct Object *ob_dst, int data_types, bool use_create, int map_vert_mode, int map_edge_mode, int map_loop_mode, int map_poly_mode, struct SpaceTransform *space_transform, bool auto_transform, float max_distance, float ray_radius, float islands_handling_precision, const int fromlayers_select[DT_MULTILAYER_INDEX_MAX], const int tolayers_select[DT_MULTILAYER_INDEX_MAX], int mix_mode, float mix_factor, const char *vgroup_name, bool invert_vgroup, struct ReportList *reports)
@ DT_LAYERS_ACTIVE_DST
@ DT_LAYERS_INDEX_DST
@ DT_LAYERS_NAME_DST
@ DT_TYPE_VCOL_ALL
@ DT_TYPE_MLOOPCOL_LOOP
@ DT_TYPE_SKIN
@ DT_TYPE_UV
@ DT_TYPE_MPROPCOL_VERT
@ DT_TYPE_BWEIGHT_VERT
@ DT_TYPE_FREESTYLE_FACE
@ DT_TYPE_SHAPEKEY
@ DT_TYPE_CREASE
@ DT_TYPE_SEAM
@ DT_TYPE_MLOOPCOL_VERT
@ DT_TYPE_LNOR
@ DT_TYPE_MPROPCOL_LOOP
@ DT_TYPE_SHARP_FACE
@ DT_TYPE_MDEFORMVERT
@ DT_TYPE_BWEIGHT_EDGE
@ DT_TYPE_FREESTYLE_EDGE
@ DT_TYPE_SHARP_EDGE
#define DT_DATATYPE_IS_VERT(_dt)
support for deformation groups and hooks.
bool BKE_object_supports_vertex_groups(const struct Object *ob)
const struct ListBase * BKE_object_defgroup_list(const struct Object *ob)
@ MREMAP_MODE_VERT_NEAREST
@ MREMAP_MODE_LOOP_NEAREST_POLYNOR
@ MREMAP_MODE_EDGE_NEAREST
@ MREMAP_MODE_POLY_NEAREST
struct Mesh * mesh_get_eval_final(struct Depsgraph *depsgraph, const struct Scene *scene, struct Object *ob, const struct CustomData_MeshMasks *dataMask)
General operations, lookup, etc. for blender objects.
struct Object * BKE_object_pose_armature_get(struct Object *ob)
Definition: object.cc:2511
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition: report.c:83
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:466
#define BLI_SPACE_TRANSFORM_SETUP(data, local, target)
#define STR_ELEM(...)
Definition: BLI_string.h:539
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL() ATTR_MALLOC
Definition: string.c:42
#define SWAP(type, a, b)
#define UNUSED(x)
#define STREQ(a, b)
#define TIP_(msgid)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:35
void DEG_id_tag_update(struct ID *id, int flag)
void DEG_relations_tag_update(struct Main *bmain)
struct Object * DEG_get_evaluated_object(const struct Depsgraph *depsgraph, struct Object *object)
struct Scene * DEG_get_evaluated_scene(const struct Depsgraph *graph)
@ ID_RECALC_GEOMETRY
Definition: DNA_ID.h:791
#define ID_IS_LINKED(_id)
Definition: DNA_ID.h:566
@ LIB_TAG_DOIT
Definition: DNA_ID.h:707
#define ID_IS_OVERRIDE_LIBRARY(_id)
Definition: DNA_ID.h:588
#define CD_MASK_PROP_BYTE_COLOR
#define CD_MASK_PROP_COLOR
eCustomDataType
@ CD_PROP_BYTE_COLOR
@ CD_PROP_COLOR
@ CD_MLOOPUV
#define CD_MASK_MLOOPUV
@ ME_AUTOSMOOTH
@ eModifierType_DataTransfer
Object is a sort of wrapper for general info.
@ OB_MESH
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
struct Object * ED_object_active_context(const struct bContext *C)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
@ PROP_SKIP_SAVE
Definition: RNA_types.h:218
@ PROP_HIDDEN
Definition: RNA_types.h:216
#define RNA_ENUM_ITEM_HEADING(name, description)
Definition: RNA_types.h:477
@ PROP_DISTANCE
Definition: RNA_types.h:149
@ PROP_FACTOR
Definition: RNA_types.h:144
#define C
Definition: RandGen.cpp:25
@ OPTYPE_UNDO
Definition: WM_types.h:148
@ OPTYPE_REGISTER
Definition: WM_types.h:146
#define ND_DRAW
Definition: WM_types.h:410
#define NC_OBJECT
Definition: WM_types.h:329
return(oflags[bm->toolflag_index].f &oflag) !=0
const Depsgraph * depsgraph
static char ** types
Definition: makesdna.c:67
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
Definition: math_float4.h:513
static const EnumPropertyItem DT_layer_items[]
static const EnumPropertyItem * dt_layers_select_src_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free)
static int datalayout_transfer_exec(bContext *C, wmOperator *op)
static int datalayout_transfer_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static bool data_transfer_poll_property(const bContext *UNUSED(C), wmOperator *op, const PropertyRNA *prop)
void OBJECT_OT_datalayout_transfer(wmOperatorType *ot)
static const EnumPropertyItem * dt_layers_select_dst_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free)
static char * data_transfer_get_description(bContext *UNUSED(C), wmOperatorType *UNUSED(ot), PointerRNA *ptr)
static bool data_transfer_check(bContext *UNUSED(C), wmOperator *op)
static bool data_transfer_exec_is_object_valid(wmOperator *op, Object *ob_src, Object *ob_dst, const bool reverse_transfer)
static const EnumPropertyItem * dt_layers_select_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *prop, bool *r_free)
void OBJECT_OT_data_transfer(wmOperatorType *ot)
static void data_transfer_exec_preprocess_objects(bContext *C, wmOperator *op, Object *ob_src, ListBase *ctx_objects, const bool reverse_transfer)
static void dt_add_vcol_layers(CustomData *cdata, eCustomDataMask mask, EnumPropertyItem **r_item, int *r_totitem)
static bool datalayout_transfer_poll(bContext *C)
static int data_transfer_exec(bContext *C, wmOperator *op)
static bool data_transfer_poll(bContext *C)
static const EnumPropertyItem * dt_mix_mode_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free)
bool edit_modifier_invoke_properties(struct bContext *C, struct wmOperator *op)
bool edit_modifier_poll_generic(struct bContext *C, struct StructRNA *rna_type, int obtype_flag, bool is_editmode_allowed, bool is_liboverride_allowed)
struct ModifierData * edit_modifier_property_get(struct wmOperator *op, struct Object *ob, int type)
void edit_modifier_properties(struct wmOperatorType *ot)
const char * RNA_property_identifier(const PropertyRNA *prop)
Definition: rna_access.c:1000
bool RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:5271
void RNA_property_enum_set(PointerRNA *ptr, PropertyRNA *prop, int value)
Definition: rna_access.c:3421
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:717
bool RNA_property_boolean_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:2153
float RNA_float_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4957
int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:3402
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:4863
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:5004
PropertyRNA * RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, float default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax)
Definition: rna_define.c:3836
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, bool default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3493
void RNA_def_property_enum_funcs_runtime(PropertyRNA *prop, EnumPropertyGetFunc getfunc, EnumPropertySetFunc setfunc, EnumPropertyItemFunc itemfunc)
Definition: rna_define.c:3258
void RNA_enum_item_end(EnumPropertyItem **items, int *totitem)
Definition: rna_define.c:4487
void RNA_enum_item_add(EnumPropertyItem **items, int *totitem, const EnumPropertyItem *item)
Definition: rna_define.c:4436
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
Definition: rna_define.c:1490
void RNA_enum_item_add_separator(EnumPropertyItem **items, int *totitem)
Definition: rna_define.c:4459
void RNA_def_property_subtype(PropertyRNA *prop, PropertySubType subtype)
Definition: rna_define.c:1534
void RNA_enum_items_add_value(EnumPropertyItem **items, int *totitem, const EnumPropertyItem *item, int value)
Definition: rna_define.c:4472
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3783
const EnumPropertyItem rna_enum_dt_method_loop_items[]
Definition: rna_modifier.c:492
const EnumPropertyItem rna_enum_dt_method_edge_items[]
Definition: rna_modifier.c:465
const EnumPropertyItem rna_enum_dt_method_poly_items[]
Definition: rna_modifier.c:523
const EnumPropertyItem rna_enum_dt_mix_mode_items[]
Definition: rna_modifier.c:544
const EnumPropertyItem rna_enum_dt_layers_select_src_items[]
Definition: rna_modifier.c:582
const EnumPropertyItem rna_enum_dt_method_vertex_items[]
Definition: rna_modifier.c:433
const EnumPropertyItem rna_enum_dt_layers_select_dst_items[]
Definition: rna_modifier.c:598
const char * identifier
Definition: RNA_types.h:461
const char * name
Definition: RNA_types.h:465
Definition: DNA_ID.h:368
int tag
Definition: DNA_ID.h:387
char name[66]
Definition: DNA_ID.h:378
void * first
Definition: DNA_listBase.h:31
CustomData vdata
CustomData ldata
void * data
void * data
Definition: RNA_types.h:38
struct bDeformGroup * next
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:919
const char * name
Definition: WM_types.h:888
const char * idname
Definition: WM_types.h:890
char *(* get_description)(struct bContext *C, struct wmOperatorType *, struct PointerRNA *)
Definition: WM_types.h:966
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:943
bool(* poll_property)(const struct bContext *C, struct wmOperator *op, const PropertyRNA *prop) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:949
struct StructRNA * srna
Definition: WM_types.h:969
const char * description
Definition: WM_types.h:893
bool(* check)(struct bContext *, struct wmOperator *)
Definition: WM_types.h:911
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:903
PropertyRNA * prop
Definition: WM_types.h:981
struct ReportList * reports
struct PointerRNA * ptr
#define N_(msgid)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
PointerRNA * ptr
Definition: wm_files.c:3480
wmOperatorType * ot
Definition: wm_files.c:3479
int WM_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))