Blender  V2.93
object_data_transfer.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2014 by Blender Foundation.
17  * All rights reserved.
18  */
19 
24 #include "DNA_mesh_types.h"
25 #include "DNA_modifier_types.h"
26 #include "DNA_object_types.h"
27 #include "DNA_scene_types.h"
28 
29 #include "BLI_blenlib.h"
30 #include "BLI_math.h"
31 #include "BLI_string.h"
32 #include "BLI_utildefines.h"
33 
34 #include "BKE_context.h"
35 #include "BKE_data_transfer.h"
36 #include "BKE_mesh_mapping.h"
37 #include "BKE_mesh_remap.h"
38 #include "BKE_mesh_runtime.h"
39 #include "BKE_object.h"
40 #include "BKE_report.h"
41 
42 #include "DEG_depsgraph.h"
43 #include "DEG_depsgraph_query.h"
44 
45 #include "RNA_access.h"
46 #include "RNA_define.h"
47 #include "RNA_enum_types.h"
48 
49 #include "WM_api.h"
50 #include "WM_types.h"
51 
52 #include "ED_object.h"
53 
54 #include "object_intern.h"
55 
56 /* All possible data to transfer.
57  * Note some are 'fake' ones, i.e. they are not hold by real CDLayers. */
58 /* Not shared with modifier, since we use a usual enum here, not a multi-choice one. */
59 static const EnumPropertyItem DT_layer_items[] = {
60  {0, "", 0, "Vertex Data", ""},
62  "VGROUP_WEIGHTS",
63  0,
64  "Vertex Group(s)",
65  "Transfer active or all vertex groups"},
66 #if 0 /* XXX For now, would like to finish/merge work from 2014 GSOC first. */
67  {DT_TYPE_SHAPEKEY, "SHAPEKEYS", 0, "Shapekey(s)", "Transfer active or all shape keys"},
68 #endif
69 /* XXX When SkinModifier is enabled,
70  * it seems to erase its own CD_MVERT_SKIN layer from final DM :( */
71 #if 0
72  {DT_TYPE_SKIN, "SKIN", 0, "Skin Weight", "Transfer skin weights"},
73 #endif
74  {DT_TYPE_BWEIGHT_VERT, "BEVEL_WEIGHT_VERT", 0, "Bevel Weight", "Transfer bevel weights"},
75  {0, "", 0, "Edge Data", ""},
76  {DT_TYPE_SHARP_EDGE, "SHARP_EDGE", 0, "Sharp", "Transfer sharp mark"},
77  {DT_TYPE_SEAM, "SEAM", 0, "UV Seam", "Transfer UV seam mark"},
78  {DT_TYPE_CREASE, "CREASE", 0, "Subdivision Crease", "Transfer crease values"},
79  {DT_TYPE_BWEIGHT_EDGE, "BEVEL_WEIGHT_EDGE", 0, "Bevel Weight", "Transfer bevel weights"},
81  "FREESTYLE_EDGE",
82  0,
83  "Freestyle Mark",
84  "Transfer Freestyle edge mark"},
85  {0, "", 0, "Face Corner Data", ""},
86  {DT_TYPE_LNOR, "CUSTOM_NORMAL", 0, "Custom Normals", "Transfer custom normals"},
87  {DT_TYPE_VCOL, "VCOL", 0, "Vertex Colors", "Vertex (face corners) colors"},
88  {DT_TYPE_UV, "UV", 0, "UVs", "Transfer UV layers"},
89  {0, "", 0, "Face Data", ""},
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 /* Note: rna_enum_dt_layers_select_src_items enum is from rna_modifier.c */
101  PointerRNA *ptr,
102  PropertyRNA *UNUSED(prop),
103  bool *r_free)
104 {
105  if (!C) { /* needed for docs and i18n tools */
107  }
108 
109  EnumPropertyItem *item = NULL, tmp_item = {0};
110  int totitem = 0;
111  const int data_type = RNA_enum_get(ptr, "data_type");
112 
113  PropertyRNA *prop = RNA_struct_find_property(ptr, "use_reverse_transfer");
114  const bool reverse_transfer = prop != NULL && RNA_property_boolean_get(ptr, prop);
115  const int layers_select_dst = reverse_transfer ? RNA_enum_get(ptr, "layers_select_src") :
116  RNA_enum_get(ptr, "layers_select_dst");
117 
118  if (!reverse_transfer || layers_select_dst == DT_LAYERS_ACTIVE_DST || layers_select_dst >= 0) {
121  }
124 
125  if (data_type == DT_TYPE_MDEFORMVERT) {
126  Object *ob_src = CTX_data_active_object(C);
127 
128  if (BKE_object_pose_armature_get(ob_src)) {
133  }
134 
135  if (ob_src) {
136  bDeformGroup *dg;
137  int i;
138 
139  RNA_enum_item_add_separator(&item, &totitem);
140 
141  for (i = 0, dg = ob_src->defbase.first; dg; i++, dg = dg->next) {
142  tmp_item.value = i;
143  tmp_item.identifier = tmp_item.name = dg->name;
144  RNA_enum_item_add(&item, &totitem, &tmp_item);
145  }
146  }
147  }
148  else if (data_type == DT_TYPE_SHAPEKEY) {
149  /* TODO */
150  }
151  else if (data_type == DT_TYPE_UV) {
152  Object *ob_src = CTX_data_active_object(C);
153 
154  if (ob_src) {
156  Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
157  Object *ob_src_eval = DEG_get_evaluated_object(depsgraph, ob_src);
158 
159  CustomData_MeshMasks cddata_masks = CD_MASK_BAREMESH;
160  cddata_masks.lmask |= CD_MASK_MLOOPUV;
161  Mesh *me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_src_eval, &cddata_masks);
162  int num_data = CustomData_number_of_layers(&me_eval->ldata, CD_MLOOPUV);
163 
164  RNA_enum_item_add_separator(&item, &totitem);
165 
166  for (int i = 0; i < num_data; i++) {
167  tmp_item.value = i;
168  tmp_item.identifier = tmp_item.name = CustomData_get_layer_name(
169  &me_eval->ldata, CD_MLOOPUV, i);
170  RNA_enum_item_add(&item, &totitem, &tmp_item);
171  }
172  }
173  }
174  else if (data_type == DT_TYPE_VCOL) {
175  Object *ob_src = CTX_data_active_object(C);
176 
177  if (ob_src) {
179  Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
180  Object *ob_src_eval = DEG_get_evaluated_object(depsgraph, ob_src);
181 
182  CustomData_MeshMasks cddata_masks = CD_MASK_BAREMESH;
183  cddata_masks.lmask |= CD_MASK_MLOOPCOL;
184  Mesh *me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_src_eval, &cddata_masks);
185  int num_data = CustomData_number_of_layers(&me_eval->ldata, CD_MLOOPCOL);
186 
187  RNA_enum_item_add_separator(&item, &totitem);
188 
189  for (int i = 0; i < num_data; i++) {
190  tmp_item.value = i;
191  tmp_item.identifier = tmp_item.name = CustomData_get_layer_name(
192  &me_eval->ldata, CD_MLOOPCOL, i);
193  RNA_enum_item_add(&item, &totitem, &tmp_item);
194  }
195  }
196  }
197 
198  RNA_enum_item_end(&item, &totitem);
199  *r_free = true;
200 
201  return item;
202 }
203 
204 /* Note: rna_enum_dt_layers_select_dst_items enum is from rna_modifier.c */
206  PointerRNA *ptr,
207  PropertyRNA *UNUSED(prop),
208  bool *r_free)
209 {
210  if (!C) { /* needed for docs and i18n tools */
212  }
213 
214  EnumPropertyItem *item = NULL;
215  int totitem = 0;
216 
217  PropertyRNA *prop = RNA_struct_find_property(ptr, "use_reverse_transfer");
218  const bool reverse_transfer = prop != NULL && RNA_property_boolean_get(ptr, prop);
219  const int layers_select_src = reverse_transfer ? RNA_enum_get(ptr, "layers_select_dst") :
220  RNA_enum_get(ptr, "layers_select_src");
221 
222  if (reverse_transfer || layers_select_src == DT_LAYERS_ACTIVE_SRC || layers_select_src >= 0) {
225  }
230 
231  /* No 'specific' to-layers here, since we may transfer to several objects at once! */
232 
233  RNA_enum_item_end(&item, &totitem);
234  *r_free = true;
235 
236  return item;
237 }
238 
240  PointerRNA *ptr,
241  PropertyRNA *prop,
242  bool *r_free)
243 {
244  const bool reverse_transfer = RNA_boolean_get(ptr, "use_reverse_transfer");
245 
246  if (STREQ(RNA_property_identifier(prop), "layers_select_dst")) {
247  if (reverse_transfer) {
248  return dt_layers_select_src_itemf(C, ptr, prop, r_free);
249  }
250  return dt_layers_select_dst_itemf(C, ptr, prop, r_free);
251  }
252  if (reverse_transfer) {
253  return dt_layers_select_dst_itemf(C, ptr, prop, r_free);
254  }
255  return dt_layers_select_src_itemf(C, ptr, prop, r_free);
256 }
257 
258 /* Note: rna_enum_dt_mix_mode_items enum is from rna_modifier.c */
260  PointerRNA *ptr,
261  PropertyRNA *UNUSED(prop),
262  bool *r_free)
263 {
264  EnumPropertyItem *item = NULL;
265  int totitem = 0;
266 
267  const int dtdata_type = RNA_enum_get(ptr, "data_type");
268  bool support_advanced_mixing, support_threshold;
269 
270  if (!C) { /* needed for docs and i18n tools */
272  }
273 
275 
277  dtdata_type, &support_advanced_mixing, &support_threshold);
278 
279  if (support_threshold) {
284  }
285 
286  if (support_advanced_mixing) {
287  RNA_enum_item_add_separator(&item, &totitem);
292  }
293 
294  RNA_enum_item_end(&item, &totitem);
295  *r_free = true;
296 
297  return item;
298 }
299 
301 {
302  const int layers_select_src = RNA_enum_get(op->ptr, "layers_select_src");
303  PropertyRNA *prop = RNA_struct_find_property(op->ptr, "layers_select_dst");
304  const int layers_select_dst = RNA_property_enum_get(op->ptr, prop);
305 
306  /* TODO: check for invalid layers_src select modes too! */
307 
308  if ((layers_select_src != DT_LAYERS_ACTIVE_SRC) && (layers_select_dst == DT_LAYERS_ACTIVE_DST)) {
310  return true;
311  }
312 
313  return false;
314 }
315 
316 /* Helper, used by both data_transfer_exec and datalayout_transfer_exec. */
318  wmOperator *op,
319  Object *ob_src,
320  ListBase *ctx_objects,
321  const bool reverse_transfer)
322 {
323  CollectionPointerLink *ctx_ob;
325 
326  if (reverse_transfer) {
327  return; /* Nothing else to do in this case... */
328  }
329 
330  for (ctx_ob = ctx_objects->first; ctx_ob; ctx_ob = ctx_ob->next) {
331  Object *ob = ctx_ob->ptr.data;
332  Mesh *me;
333  if ((ob == ob_src) || (ob->type != OB_MESH)) {
334  continue;
335  }
336 
337  me = ob->data;
338  if (ID_IS_LINKED(me)) {
339  /* Do not transfer to linked data, not supported. */
340  BKE_reportf(op->reports,
341  RPT_WARNING,
342  "Skipping object '%s', linked data '%s' cannot be modified",
343  ob->id.name + 2,
344  me->id.name + 2);
345  me->id.tag &= ~LIB_TAG_DOIT;
346  continue;
347  }
348 
349  me->id.tag |= LIB_TAG_DOIT;
350  }
351 }
352 
353 /* Helper, used by both data_transfer_exec and datalayout_transfer_exec. */
355  Object *ob_src,
356  Object *ob_dst,
357  const bool reverse_transfer)
358 {
359  Mesh *me;
360  if ((ob_dst == ob_src) || (ob_src->type != OB_MESH) || (ob_dst->type != OB_MESH)) {
361  return false;
362  }
363 
364  if (reverse_transfer) {
365  return true;
366  }
367 
368  me = ob_dst->data;
369  if (me->id.tag & LIB_TAG_DOIT) {
370  me->id.tag &= ~LIB_TAG_DOIT;
371  return true;
372  }
373  if (!ID_IS_LINKED(me) && !ID_IS_OVERRIDE_LIBRARY(me)) {
374  /* Do not apply transfer operation more than once. */
375  /* XXX This is not nice regarding vgroups, which are half-Object data... :/ */
376  BKE_reportf(
377  op->reports,
378  RPT_WARNING,
379  "Skipping object '%s', data '%s' has already been processed with a previous object",
380  ob_dst->id.name + 2,
381  me->id.name + 2);
382  }
383  return false;
384 }
385 
387 {
388  Object *ob_src = ED_object_active_context(C);
390  Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
391 
392  ListBase ctx_objects;
393  CollectionPointerLink *ctx_ob_dst;
394 
395  bool changed = false;
396 
397  const bool is_frozen = RNA_boolean_get(op->ptr, "use_freeze");
398 
399  const bool reverse_transfer = RNA_boolean_get(op->ptr, "use_reverse_transfer");
400 
401  const int data_type = RNA_enum_get(op->ptr, "data_type");
402  const bool use_create = RNA_boolean_get(op->ptr, "use_create");
403 
404  const int map_vert_mode = RNA_enum_get(op->ptr, "vert_mapping");
405  const int map_edge_mode = RNA_enum_get(op->ptr, "edge_mapping");
406  const int map_loop_mode = RNA_enum_get(op->ptr, "loop_mapping");
407  const int map_poly_mode = RNA_enum_get(op->ptr, "poly_mapping");
408 
409  const bool use_auto_transform = RNA_boolean_get(op->ptr, "use_auto_transform");
410  const bool use_object_transform = RNA_boolean_get(op->ptr, "use_object_transform");
411  const bool use_max_distance = RNA_boolean_get(op->ptr, "use_max_distance");
412  const float max_distance = use_max_distance ? RNA_float_get(op->ptr, "max_distance") : FLT_MAX;
413  const float ray_radius = RNA_float_get(op->ptr, "ray_radius");
414  const float islands_precision = RNA_float_get(op->ptr, "islands_precision");
415 
416  int layers_src = RNA_enum_get(op->ptr, "layers_select_src");
417  int layers_dst = RNA_enum_get(op->ptr, "layers_select_dst");
418  int layers_select_src[DT_MULTILAYER_INDEX_MAX] = {0};
419  int layers_select_dst[DT_MULTILAYER_INDEX_MAX] = {0};
420  const int fromto_idx = BKE_object_data_transfer_dttype_to_srcdst_index(data_type);
421 
422  const int mix_mode = RNA_enum_get(op->ptr, "mix_mode");
423  const float mix_factor = RNA_float_get(op->ptr, "mix_factor");
424 
425  SpaceTransform space_transform_data;
426  SpaceTransform *space_transform = (use_object_transform && !use_auto_transform) ?
427  &space_transform_data :
428  NULL;
429 
430  if (is_frozen) {
431  BKE_report(
432  op->reports,
433  RPT_INFO,
434  "Operator is frozen, changes to its settings won't take effect until you unfreeze it");
435  return OPERATOR_FINISHED;
436  }
437 
438  if (reverse_transfer && (ID_IS_LINKED(ob_src->data) || ID_IS_OVERRIDE_LIBRARY(ob_src->data))) {
439  /* Do not transfer to linked or override data, not supported. */
440  return OPERATOR_CANCELLED;
441  }
442 
443  if (reverse_transfer) {
444  SWAP(int, layers_src, layers_dst);
445  }
446 
447  if (fromto_idx != DT_MULTILAYER_INDEX_INVALID) {
448  layers_select_src[fromto_idx] = layers_src;
449  layers_select_dst[fromto_idx] = layers_dst;
450  }
451 
452  data_transfer_exec_preprocess_objects(C, op, ob_src, &ctx_objects, reverse_transfer);
453 
454  for (ctx_ob_dst = ctx_objects.first; ctx_ob_dst; ctx_ob_dst = ctx_ob_dst->next) {
455  Object *ob_dst = ctx_ob_dst->ptr.data;
456 
457  if (reverse_transfer) {
458  SWAP(Object *, ob_src, ob_dst);
459  }
460 
461  if (data_transfer_exec_is_object_valid(op, ob_src, ob_dst, reverse_transfer)) {
462  Object *ob_src_eval = DEG_get_evaluated_object(depsgraph, ob_src);
463 
464  if (space_transform) {
465  Object *ob_dst_eval = DEG_get_evaluated_object(depsgraph, ob_dst);
466  BLI_SPACE_TRANSFORM_SETUP(space_transform, ob_dst_eval, ob_src_eval);
467  }
468 
470  scene_eval,
471  ob_src_eval,
472  ob_dst,
473  data_type,
474  use_create,
475  map_vert_mode,
476  map_edge_mode,
477  map_loop_mode,
478  map_poly_mode,
479  space_transform,
480  use_auto_transform,
481  max_distance,
482  ray_radius,
483  islands_precision,
484  layers_select_src,
485  layers_select_dst,
486  mix_mode,
487  mix_factor,
488  NULL,
489  false,
490  op->reports)) {
491 
492  if (data_type == DT_TYPE_LNOR && use_create) {
493  ((Mesh *)ob_dst->data)->flag |= ME_AUTOSMOOTH;
494  }
495 
497  changed = true;
498  }
499  }
500 
501  if (reverse_transfer) {
502  SWAP(Object *, ob_src, ob_dst);
503  }
504  }
505 
506  BLI_freelistN(&ctx_objects);
507 
508  if (changed) {
511  }
512 
513 #if 0 /* TODO */
514  /* Note: issue with that is that if canceled, operator cannot be redone... Nasty in our case. */
515  return changed ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
516 #else
517  return OPERATOR_FINISHED;
518 #endif
519 }
520 
521 /* Used by both OBJECT_OT_data_transfer and OBJECT_OT_datalayout_transfer */
522 /* Note this context poll is only really partial,
523  * it cannot check for all possible invalid cases. */
525 {
527  ID *data = (ob) ? ob->data : NULL;
528  return (ob != NULL && ob->type == OB_MESH && data != NULL);
529 }
530 
531 /* Used by both OBJECT_OT_data_transfer and OBJECT_OT_datalayout_transfer */
533  wmOperator *op,
534  const PropertyRNA *prop)
535 {
536  PointerRNA *ptr = op->ptr;
537  PropertyRNA *prop_other;
538 
539  const char *prop_id = RNA_property_identifier(prop);
540  const int data_type = RNA_enum_get(ptr, "data_type");
541  bool use_auto_transform = false;
542  bool use_max_distance = false;
543  bool use_modifier = false;
544 
545  if ((prop_other = RNA_struct_find_property(ptr, "use_auto_transform"))) {
546  use_auto_transform = RNA_property_boolean_get(ptr, prop_other);
547  }
548  if ((prop_other = RNA_struct_find_property(ptr, "use_max_distance"))) {
549  use_max_distance = RNA_property_boolean_get(ptr, prop_other);
550  }
551  if ((prop_other = RNA_struct_find_property(ptr, "modifier"))) {
552  use_modifier = RNA_property_is_set(ptr, prop_other);
553  }
554 
555  if (STREQ(prop_id, "modifier")) {
556  return use_modifier;
557  }
558 
559  if (use_modifier) {
560  /* Hide everything but 'modifier' property, if set. */
561  return false;
562  }
563 
564  if (STREQ(prop_id, "use_object_transform")) {
565  if (use_auto_transform) {
566  return false;
567  }
568  }
569  else if (STREQ(prop_id, "max_distance")) {
570  if (!use_max_distance) {
571  return false;
572  }
573  }
574  else if (STREQ(prop_id, "islands_precision")) {
575  if (!DT_DATATYPE_IS_LOOP(data_type)) {
576  return false;
577  }
578  }
579  else if (STREQ(prop_id, "vert_mapping")) {
580  if (!DT_DATATYPE_IS_VERT(data_type)) {
581  return false;
582  }
583  }
584  else if (STREQ(prop_id, "edge_mapping")) {
585  if (!DT_DATATYPE_IS_EDGE(data_type)) {
586  return false;
587  }
588  }
589  else if (STREQ(prop_id, "loop_mapping")) {
590  if (!DT_DATATYPE_IS_LOOP(data_type)) {
591  return false;
592  }
593  }
594  else if (STREQ(prop_id, "poly_mapping")) {
595  if (!DT_DATATYPE_IS_POLY(data_type)) {
596  return false;
597  }
598  }
599  else if (STR_ELEM(prop_id, "layers_select_src", "layers_select_dst")) {
600  if (!DT_DATATYPE_IS_MULTILAYERS(data_type)) {
601  return false;
602  }
603  }
604 
605  /* Else, show it! */
606  return true;
607 }
608 
609 /* Transfer mesh data from active to selected objects. */
611 {
612  PropertyRNA *prop;
613 
614  /* Identifiers.*/
615  ot->name = "Transfer Mesh Data";
616  ot->idname = "OBJECT_OT_data_transfer";
617  ot->description =
618  "Transfer data layer(s) (weights, edge sharp, etc.) from active to selected meshes";
619 
620  /* API callbacks.*/
626 
627  /* Flags.*/
629 
630  /* Properties.*/
631  prop = RNA_def_boolean(ot->srna,
632  "use_reverse_transfer",
633  false,
634  "Reverse Transfer",
635  "Transfer from selected objects to active one");
637 
639  "use_freeze",
640  false,
641  "Freeze Operator",
642  "Prevent changes to settings to re-run the operator, "
643  "handy to change several things at once with heavy geometry");
644 
645  /* Data type to transfer. */
646  ot->prop = RNA_def_enum(
647  ot->srna, "data_type", DT_layer_items, 0, "Data Type", "Which data to transfer");
649  "use_create",
650  true,
651  "Create Data",
652  "Add data layers on destination meshes if needed");
653 
654  /* Mapping methods. */
656  "vert_mapping",
659  "Vertex Mapping",
660  "Method used to map source vertices to destination ones");
662  "edge_mapping",
665  "Edge Mapping",
666  "Method used to map source edges to destination ones");
668  "loop_mapping",
671  "Face Corner Mapping",
672  "Method used to map source faces' corners to destination ones");
674  "poly_mapping",
677  "Face Mapping",
678  "Method used to map source faces to destination ones");
679 
680  /* Mapping options and filtering. */
682  ot->srna,
683  "use_auto_transform",
684  false,
685  "Auto Transform",
686  "Automatically compute transformation to get the best possible match between source and "
687  "destination meshes.\n"
688  "Warning: Results will never be as good as manual matching of objects");
690  "use_object_transform",
691  true,
692  "Object Transform",
693  "Evaluate source and destination meshes in global space");
695  "use_max_distance",
696  false,
697  "Only Neighbor Geometry",
698  "Source elements must be closer than given distance from destination one");
699  prop = RNA_def_float(
700  ot->srna,
701  "max_distance",
702  1.0f,
703  0.0f,
704  FLT_MAX,
705  "Max Distance",
706  "Maximum allowed distance between source and destination element, for non-topology mappings",
707  0.0f,
708  100.0f);
710  prop = RNA_def_float(
711  ot->srna,
712  "ray_radius",
713  0.0f,
714  0.0f,
715  FLT_MAX,
716  "Ray Radius",
717  "'Width' of rays (especially useful when raycasting against vertices or edges)",
718  0.0f,
719  10.0f);
721  prop = RNA_def_float(
722  ot->srna,
723  "islands_precision",
724  0.1f,
725  0.0f,
726  10.0f,
727  "Islands Precision",
728  "Factor controlling precision of islands handling (the higher, the better the results)",
729  0.0f,
730  1.0f);
732 
733  /* How to handle multi-layers types of data. */
734  prop = RNA_def_enum(ot->srna,
735  "layers_select_src",
738  "Source Layers Selection",
739  "Which layers to transfer, in case of multi-layers types");
741 
742  prop = RNA_def_enum(ot->srna,
743  "layers_select_dst",
746  "Destination Layers Matching",
747  "How to match source and destination layers");
749 
750  prop = RNA_def_enum(ot->srna,
751  "mix_mode",
754  "Mix Mode",
755  "How to affect destination elements with source values");
758  ot->srna,
759  "mix_factor",
760  1.0f,
761  0.0f,
762  1.0f,
763  "Mix Factor",
764  "Factor to use when applying data to destination (exact behavior depends on mix mode)",
765  0.0f,
766  1.0f);
767 }
768 
769 /******************************************************************************/
770 /* Note: This operator is hybrid, it can work as a usual standalone Object operator,
771  * or as a DataTransfer modifier tool.
772  */
773 
775 {
776  return (edit_modifier_poll_generic(C, &RNA_DataTransferModifier, (1 << OB_MESH), true, false) ||
778 }
779 
781 {
782  Object *ob_act = ED_object_active_context(C);
784  Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
786 
788  op, ob_act, eModifierType_DataTransfer);
789 
790  /* If we have a modifier, we transfer data layout from this modifier's source object to
791  * active one. Else, we transfer data layout from active object to all selected ones. */
792  if (dtmd) {
793  Object *ob_src = dtmd->ob_source;
794  Object *ob_dst = ob_act;
795 
796  const bool use_delete = false; /* Never when used from modifier, for now. */
797 
798  if (!ob_src || ID_IS_LINKED(ob_dst) || ID_IS_OVERRIDE_LIBRARY(ob_dst)) {
799  return OPERATOR_CANCELLED;
800  }
801 
802  Object *ob_src_eval = DEG_get_evaluated_object(depsgraph, ob_src);
803 
805  scene_eval,
806  ob_src_eval,
807  ob_dst,
808  dtmd->data_types,
809  use_delete,
810  dtmd->layers_select_src,
811  dtmd->layers_select_dst);
812 
814  }
815  else {
816  Object *ob_src = ob_act;
817 
818  ListBase ctx_objects;
819  CollectionPointerLink *ctx_ob_dst;
820 
821  const int data_type = RNA_enum_get(op->ptr, "data_type");
822  const bool use_delete = RNA_boolean_get(op->ptr, "use_delete");
823 
824  const int layers_src = RNA_enum_get(op->ptr, "layers_select_src");
825  const int layers_dst = RNA_enum_get(op->ptr, "layers_select_dst");
826  int layers_select_src[DT_MULTILAYER_INDEX_MAX] = {0};
827  int layers_select_dst[DT_MULTILAYER_INDEX_MAX] = {0};
828  const int fromto_idx = BKE_object_data_transfer_dttype_to_srcdst_index(data_type);
829 
830  if (fromto_idx != DT_MULTILAYER_INDEX_INVALID) {
831  layers_select_src[fromto_idx] = layers_src;
832  layers_select_dst[fromto_idx] = layers_dst;
833  }
834 
835  Object *ob_src_eval = DEG_get_evaluated_object(depsgraph, ob_src);
836 
837  data_transfer_exec_preprocess_objects(C, op, ob_src, &ctx_objects, false);
838 
839  for (ctx_ob_dst = ctx_objects.first; ctx_ob_dst; ctx_ob_dst = ctx_ob_dst->next) {
840  Object *ob_dst = ctx_ob_dst->ptr.data;
841  if (data_transfer_exec_is_object_valid(op, ob_src, ob_dst, false)) {
843  scene_eval,
844  ob_src_eval,
845  ob_dst,
846  data_type,
847  use_delete,
848  layers_select_src,
849  layers_select_dst);
850  }
851 
853  }
854 
855  BLI_freelistN(&ctx_objects);
856  }
857 
860 
861  return OPERATOR_FINISHED;
862 }
863 
864 static int datalayout_transfer_invoke(bContext *C, wmOperator *op, const wmEvent *event)
865 {
867  return datalayout_transfer_exec(C, op);
868  }
869  return WM_menu_invoke(C, op, event);
870 }
871 
873 {
874  PropertyRNA *prop;
875 
876  ot->name = "Transfer Mesh Data Layout";
877  ot->description = "Transfer layout of data layer(s) from active to selected meshes";
878  ot->idname = "OBJECT_OT_datalayout_transfer";
879 
885 
886  /* flags */
888 
889  /* Properties.*/
891 
892  /* Data type to transfer. */
893  ot->prop = RNA_def_enum(
894  ot->srna, "data_type", DT_layer_items, 0, "Data Type", "Which data to transfer");
896  "use_delete",
897  false,
898  "Exact Match",
899  "Also delete some data layers from destination if necessary, so that it matches "
900  "exactly source");
901 
902  /* How to handle multi-layers types of data. */
903  prop = RNA_def_enum(ot->srna,
904  "layers_select_src",
907  "Source Layers Selection",
908  "Which layers to transfer, in case of multi-layers types");
910 
911  prop = RNA_def_enum(ot->srna,
912  "layers_select_dst",
915  "Destination Layers Matching",
916  "How to match source and destination layers");
918 }
struct Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
Definition: context.c:1424
struct Object * CTX_data_active_object(const bContext *C)
Definition: context.c:1279
int CTX_data_selected_editable_objects(const bContext *C, ListBase *list)
Definition: context.c:1229
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1018
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)
@ 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
const CustomData_MeshMasks CD_MASK_BAREMESH
Definition: customdata.c:1919
@ DT_LAYERS_VGROUP_SRC_BONE_SELECT
@ DT_LAYERS_VGROUP_SRC_BONE_DEFORM
@ DT_LAYERS_ALL_SRC
@ DT_LAYERS_ACTIVE_SRC
@ DT_LAYERS_ACTIVE_DST
@ DT_LAYERS_INDEX_DST
@ DT_LAYERS_NAME_DST
#define DT_DATATYPE_IS_POLY(_dt)
#define DT_DATATYPE_IS_MULTILAYERS(_dt)
int BKE_object_data_transfer_dttype_to_srcdst_index(const int dtdata_type)
void BKE_object_data_transfer_layout(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob_src, struct Object *ob_dst, const int data_types, const 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)
bool BKE_object_data_transfer_get_dttypes_capacity(const int dtdata_types, bool *r_advanced_mixing, bool *r_threshold)
#define DT_DATATYPE_IS_EDGE(_dt)
bool BKE_object_data_transfer_mesh(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob_src, struct Object *ob_dst, const int data_types, const bool use_create, const int map_vert_mode, const int map_edge_mode, const int map_loop_mode, const int map_poly_mode, struct SpaceTransform *space_transform, const bool auto_transform, const float max_distance, const float ray_radius, const float islands_handling_precision, const int fromlayers_select[DT_MULTILAYER_INDEX_MAX], const int tolayers_select[DT_MULTILAYER_INDEX_MAX], const int mix_mode, const float mix_factor, const char *vgroup_name, const bool invert_vgroup, struct ReportList *reports)
@ DT_TYPE_SKIN
@ DT_TYPE_UV
@ DT_TYPE_BWEIGHT_VERT
@ DT_TYPE_FREESTYLE_FACE
@ DT_TYPE_SHAPEKEY
@ DT_TYPE_CREASE
@ DT_TYPE_SEAM
@ DT_TYPE_LNOR
@ DT_TYPE_VCOL
@ DT_TYPE_SHARP_FACE
@ DT_TYPE_MDEFORMVERT
@ DT_TYPE_BWEIGHT_EDGE
@ DT_TYPE_FREESTYLE_EDGE
@ DT_TYPE_SHARP_EDGE
@ DT_MULTILAYER_INDEX_MAX
@ DT_MULTILAYER_INDEX_INVALID
#define DT_DATATYPE_IS_VERT(_dt)
@ 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, 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.c:2487
void BKE_report(ReportList *reports, ReportType type, const char *message)
Definition: report.c:104
void BKE_reportf(ReportList *reports, ReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:547
#define BLI_SPACE_TRANSFORM_SETUP(data, local, target)
#define STR_ELEM(...)
Definition: BLI_string.h:218
#define SWAP(type, a, b)
#define UNUSED(x)
#define STREQ(a, b)
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:51
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:611
@ LIB_TAG_DOIT
Definition: DNA_ID.h:554
#define ID_IS_LINKED(_id)
Definition: DNA_ID.h:426
#define ID_IS_OVERRIDE_LIBRARY(_id)
Definition: DNA_ID.h:445
#define CD_MASK_MLOOPCOL
@ CD_MLOOPCOL
@ 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)
StructRNA RNA_DataTransferModifier
@ PROP_SKIP_SAVE
Definition: RNA_types.h:204
@ PROP_HIDDEN
Definition: RNA_types.h:202
@ PROP_DISTANCE
Definition: RNA_types.h:135
@ PROP_FACTOR
Definition: RNA_types.h:131
#define C
Definition: RandGen.cpp:39
#define ND_DRAW
Definition: WM_types.h:362
@ OPTYPE_UNDO
Definition: WM_types.h:155
@ OPTYPE_REGISTER
Definition: WM_types.h:153
#define NC_OBJECT
Definition: WM_types.h:280
return(oflags[bm->toolflag_index].f &oflag) !=0
const Depsgraph * depsgraph
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 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 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, const bool is_editmode_allowed, const 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:1145
bool RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:6655
void RNA_property_enum_set(PointerRNA *ptr, PropertyRNA *prop, int value)
Definition: rna_access.c:3562
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:866
bool RNA_property_boolean_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:2331
float RNA_float_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6355
int RNA_property_enum_get(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:3543
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6261
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6402
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:3825
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, bool default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3481
void RNA_def_property_enum_funcs_runtime(PropertyRNA *prop, EnumPropertyGetFunc getfunc, EnumPropertySetFunc setfunc, EnumPropertyItemFunc itemfunc)
Definition: rna_define.c:3285
void RNA_enum_item_end(EnumPropertyItem **items, int *totitem)
Definition: rna_define.c:4470
void RNA_enum_item_add(EnumPropertyItem **items, int *totitem, const EnumPropertyItem *item)
Definition: rna_define.c:4416
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
Definition: rna_define.c:1512
void RNA_enum_item_add_separator(EnumPropertyItem **items, int *totitem)
Definition: rna_define.c:4442
void RNA_def_property_subtype(PropertyRNA *prop, PropertySubType subtype)
Definition: rna_define.c:1563
void RNA_enum_items_add_value(EnumPropertyItem **items, int *totitem, const EnumPropertyItem *item, int value)
Definition: rna_define.c:4455
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:3771
const EnumPropertyItem rna_enum_dt_method_loop_items[]
Definition: rna_modifier.c:461
const EnumPropertyItem rna_enum_dt_method_edge_items[]
Definition: rna_modifier.c:434
const EnumPropertyItem rna_enum_dt_method_poly_items[]
Definition: rna_modifier.c:492
const EnumPropertyItem rna_enum_dt_mix_mode_items[]
Definition: rna_modifier.c:513
const EnumPropertyItem rna_enum_dt_layers_select_src_items[]
Definition: rna_modifier.c:551
const EnumPropertyItem rna_enum_dt_method_vertex_items[]
Definition: rna_modifier.c:402
const EnumPropertyItem rna_enum_dt_layers_select_dst_items[]
Definition: rna_modifier.c:567
Definition: DNA_ID.h:273
int tag
Definition: DNA_ID.h:292
char name[66]
Definition: DNA_ID.h:283
void * first
Definition: DNA_listBase.h:47
struct CustomData pdata ldata
ListBase defbase
void * data
void * data
Definition: RNA_types.h:52
struct bDeformGroup * next
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:752
const char * name
Definition: WM_types.h:721
const char * idname
Definition: WM_types.h:723
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:776
bool(* poll_property)(const struct bContext *C, struct wmOperator *op, const PropertyRNA *prop) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:782
struct StructRNA * srna
Definition: WM_types.h:802
const char * description
Definition: WM_types.h:726
bool(* check)(struct bContext *, struct wmOperator *)
Definition: WM_types.h:744
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:736
PropertyRNA * prop
Definition: WM_types.h:814
struct ReportList * reports
struct PointerRNA * ptr
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
PointerRNA * ptr
Definition: wm_files.c:3157
wmOperatorType * ot
Definition: wm_files.c:3156
int WM_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
Definition: wm_operators.c:982