Blender  V3.3
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 "CLG_log.h"
9 
10 #include "MEM_guardedalloc.h"
11 
12 #include "DNA_customdata_types.h"
13 #include "DNA_mesh_types.h"
14 #include "DNA_meshdata_types.h"
15 #include "DNA_object_types.h"
16 #include "DNA_scene_types.h"
17 
18 #include "BLI_blenlib.h"
19 #include "BLI_math.h"
20 #include "BLI_utildefines.h"
21 
22 #include "BKE_attribute.h"
23 #include "BKE_customdata.h"
24 #include "BKE_data_transfer.h"
25 #include "BKE_deform.h"
26 #include "BKE_mesh.h"
27 #include "BKE_mesh_mapping.h"
28 #include "BKE_mesh_remap.h"
29 #include "BKE_mesh_runtime.h"
30 #include "BKE_mesh_wrapper.h"
31 #include "BKE_modifier.h"
32 #include "BKE_object.h"
33 #include "BKE_object_deform.h"
34 #include "BKE_report.h"
35 
36 #include "data_transfer_intern.h"
37 
38 static CLG_LogRef LOG = {"bke.data_transfer"};
39 
40 void BKE_object_data_transfer_dttypes_to_cdmask(const int dtdata_types,
41  CustomData_MeshMasks *r_data_masks)
42 {
43  for (int i = 0; i < DT_TYPE_MAX; i++) {
44  const int dtdata_type = 1 << i;
45  int cddata_type;
46 
47  if (!(dtdata_types & dtdata_type)) {
48  continue;
49  }
50 
51  cddata_type = BKE_object_data_transfer_dttype_to_cdtype(dtdata_type);
52  if (!(cddata_type & CD_FAKE)) {
53  if (DT_DATATYPE_IS_VERT(dtdata_type)) {
54  r_data_masks->vmask |= 1LL << cddata_type;
55  }
56  else if (DT_DATATYPE_IS_EDGE(dtdata_type)) {
57  r_data_masks->emask |= 1LL << cddata_type;
58  }
59  else if (DT_DATATYPE_IS_LOOP(dtdata_type)) {
60  r_data_masks->lmask |= 1LL << cddata_type;
61  }
62  else if (DT_DATATYPE_IS_POLY(dtdata_type)) {
63  r_data_masks->pmask |= 1LL << cddata_type;
64  }
65  }
66  else if (cddata_type == CD_FAKE_MDEFORMVERT) {
67  r_data_masks->vmask |= CD_MASK_MDEFORMVERT; /* Exception for vgroups :/ */
68  }
69  else if (cddata_type == CD_FAKE_UV) {
70  r_data_masks->lmask |= CD_MASK_MLOOPUV;
71  }
72  else if (cddata_type == CD_FAKE_LNOR) {
73  r_data_masks->vmask |= CD_MASK_NORMAL;
74  r_data_masks->pmask |= CD_MASK_NORMAL;
76  }
77  }
78 }
79 
81  bool *r_advanced_mixing,
82  bool *r_threshold)
83 {
84  bool ret = false;
85 
86  *r_advanced_mixing = false;
87  *r_threshold = false;
88 
89  for (int i = 0; (i < DT_TYPE_MAX) && !(ret && *r_advanced_mixing && *r_threshold); i++) {
90  const int dtdata_type = 1 << i;
91 
92  if (!(dtdata_types & dtdata_type)) {
93  continue;
94  }
95 
96  switch (dtdata_type) {
97  /* Vertex data */
99  *r_advanced_mixing = true;
100  *r_threshold = true;
101  ret = true;
102  break;
103  case DT_TYPE_SKIN:
104  *r_threshold = true;
105  ret = true;
106  break;
108  ret = true;
109  break;
110  /* Edge data */
111  case DT_TYPE_SHARP_EDGE:
112  *r_threshold = true;
113  ret = true;
114  break;
115  case DT_TYPE_SEAM:
116  *r_threshold = true;
117  ret = true;
118  break;
119  case DT_TYPE_CREASE:
120  ret = true;
121  break;
123  ret = true;
124  break;
126  *r_threshold = true;
127  ret = true;
128  break;
129  /* Loop/Poly data */
130  case DT_TYPE_UV:
131  ret = true;
132  break;
137  *r_advanced_mixing = true;
138  *r_threshold = true;
139  ret = true;
140  break;
141  case DT_TYPE_LNOR:
142  *r_advanced_mixing = true;
143  ret = true;
144  break;
145  case DT_TYPE_SHARP_FACE:
146  *r_threshold = true;
147  ret = true;
148  break;
150  *r_threshold = true;
151  ret = true;
152  break;
153  }
154  }
155 
156  return ret;
157 }
158 
160 {
161  int i, ret = 0;
162 
163  for (i = 0; (i < DT_TYPE_MAX) && (ret ^ (ME_VERT | ME_EDGE | ME_LOOP | ME_POLY)); i++) {
164  const int dtdata_type = 1 << i;
165 
166  if (!(dtdata_types & dtdata_type)) {
167  continue;
168  }
169 
170  if (DT_DATATYPE_IS_VERT(dtdata_type)) {
171  ret |= ME_VERT;
172  }
173  if (DT_DATATYPE_IS_EDGE(dtdata_type)) {
174  ret |= ME_EDGE;
175  }
176  if (DT_DATATYPE_IS_LOOP(dtdata_type)) {
177  ret |= ME_LOOP;
178  }
179  if (DT_DATATYPE_IS_POLY(dtdata_type)) {
180  ret |= ME_POLY;
181  }
182  }
183 
184  return ret;
185 }
186 
188 {
189  switch (dtdata_type) {
190  case DT_TYPE_MDEFORMVERT:
191  return CD_FAKE_MDEFORMVERT;
192  case DT_TYPE_SHAPEKEY:
193  return CD_FAKE_SHAPEKEY;
194  case DT_TYPE_SKIN:
195  return CD_MVERT_SKIN;
197  return CD_FAKE_BWEIGHT;
198 
199  case DT_TYPE_SHARP_EDGE:
200  return CD_FAKE_SHARP;
201  case DT_TYPE_SEAM:
202  return CD_FAKE_SEAM;
203  case DT_TYPE_CREASE:
204  return CD_FAKE_CREASE;
206  return CD_FAKE_BWEIGHT;
208  return CD_FREESTYLE_EDGE;
209 
210  case DT_TYPE_UV:
211  return CD_FAKE_UV;
212  case DT_TYPE_SHARP_FACE:
213  return CD_FAKE_SHARP;
215  return CD_FREESTYLE_FACE;
216  case DT_TYPE_LNOR:
217  return CD_FAKE_LNOR;
220  return CD_PROP_BYTE_COLOR;
223  return CD_PROP_COLOR;
224  default:
226  }
227  return 0; /* Should never be reached! */
228 }
229 
231 {
232  switch (dtdata_type) {
233  case DT_TYPE_MDEFORMVERT:
235  case DT_TYPE_SHAPEKEY:
237  case DT_TYPE_UV:
238  return DT_MULTILAYER_INDEX_UV;
247  default:
249  }
250 }
251 
252 /* ********** */
253 
254 /* Generic pre/post processing, only used by custom loop normals currently. */
255 
257  Mesh *me_dst,
258  const int dtdata_type,
259  const bool dirty_nors_dst)
260 {
261  if (dtdata_type == DT_TYPE_LNOR) {
262  /* Compute custom normals into regular loop normals, which will be used for the transfer. */
263  MVert *verts_dst = me_dst->mvert;
264  const int num_verts_dst = me_dst->totvert;
265  MEdge *edges_dst = me_dst->medge;
266  const int num_edges_dst = me_dst->totedge;
267  MPoly *polys_dst = me_dst->mpoly;
268  const int num_polys_dst = me_dst->totpoly;
269  MLoop *loops_dst = me_dst->mloop;
270  const int num_loops_dst = me_dst->totloop;
271  CustomData *ldata_dst = &me_dst->ldata;
272 
273  const bool use_split_nors_dst = (me_dst->flag & ME_AUTOSMOOTH) != 0;
274  const float split_angle_dst = me_dst->smoothresh;
275 
276  /* This should be ensured by cddata_masks we pass to code generating/giving us me_src now. */
278  (void)me_src;
279 
280  float(*loop_nors_dst)[3];
281  short(*custom_nors_dst)[2] = CustomData_get_layer(ldata_dst, CD_CUSTOMLOOPNORMAL);
282 
283  /* Cache loop nors into a temp CDLayer. */
284  loop_nors_dst = CustomData_get_layer(ldata_dst, CD_NORMAL);
285  const bool do_loop_nors_dst = (loop_nors_dst == NULL);
286  if (do_loop_nors_dst) {
287  loop_nors_dst = CustomData_add_layer(ldata_dst, CD_NORMAL, CD_CALLOC, NULL, num_loops_dst);
289  }
290  if (dirty_nors_dst || do_loop_nors_dst) {
291  BKE_mesh_normals_loop_split(verts_dst,
293  num_verts_dst,
294  edges_dst,
295  num_edges_dst,
296  loops_dst,
297  loop_nors_dst,
298  num_loops_dst,
299  polys_dst,
301  num_polys_dst,
302  use_split_nors_dst,
303  split_angle_dst,
304  NULL,
305  custom_nors_dst,
306  NULL);
307  }
308  }
309 }
310 
312  Object *UNUSED(ob_dst),
313  Mesh *UNUSED(me_src),
314  Mesh *me_dst,
315  const int dtdata_type,
316  const bool changed)
317 {
318  if (dtdata_type == DT_TYPE_LNOR) {
319  if (!changed) {
320  return;
321  }
322 
323  /* Bake edited destination loop normals into custom normals again. */
324  MVert *verts_dst = me_dst->mvert;
325  const int num_verts_dst = me_dst->totvert;
326  MEdge *edges_dst = me_dst->medge;
327  const int num_edges_dst = me_dst->totedge;
328  MPoly *polys_dst = me_dst->mpoly;
329  const int num_polys_dst = me_dst->totpoly;
330  MLoop *loops_dst = me_dst->mloop;
331  const int num_loops_dst = me_dst->totloop;
332  CustomData *ldata_dst = &me_dst->ldata;
333 
334  const float(*poly_nors_dst)[3] = BKE_mesh_poly_normals_ensure(me_dst);
335  float(*loop_nors_dst)[3] = CustomData_get_layer(ldata_dst, CD_NORMAL);
336  short(*custom_nors_dst)[2] = CustomData_get_layer(ldata_dst, CD_CUSTOMLOOPNORMAL);
337 
338  if (!custom_nors_dst) {
339  custom_nors_dst = CustomData_add_layer(
340  ldata_dst, CD_CUSTOMLOOPNORMAL, CD_CALLOC, NULL, num_loops_dst);
341  }
342 
343  /* Note loop_nors_dst contains our custom normals as transferred from source... */
346  num_verts_dst,
347  edges_dst,
348  num_edges_dst,
349  loops_dst,
350  loop_nors_dst,
351  num_loops_dst,
352  polys_dst,
353  poly_nors_dst,
354  num_polys_dst,
355  custom_nors_dst);
356  }
357 }
358 
359 /* ********** */
360 
362 {
363  switch (cddata_type) {
364  case CD_FAKE_UV:
366  default:
367  break;
368  }
369  return NULL;
370 }
371 
372 float data_transfer_interp_float_do(const int mix_mode,
373  const float val_dst,
374  const float val_src,
375  const float mix_factor)
376 {
377  float val_ret;
378 
379  if (((mix_mode == CDT_MIX_REPLACE_ABOVE_THRESHOLD && (val_dst < mix_factor)) ||
380  (mix_mode == CDT_MIX_REPLACE_BELOW_THRESHOLD && (val_dst > mix_factor)))) {
381  return val_dst; /* Do not affect destination. */
382  }
383 
384  switch (mix_mode) {
387  return val_src;
388  case CDT_MIX_MIX:
389  val_ret = (val_dst + val_src) * 0.5f;
390  break;
391  case CDT_MIX_ADD:
392  val_ret = val_dst + val_src;
393  break;
394  case CDT_MIX_SUB:
395  val_ret = val_dst - val_src;
396  break;
397  case CDT_MIX_MUL:
398  val_ret = val_dst * val_src;
399  break;
400  case CDT_MIX_TRANSFER:
401  default:
402  val_ret = val_src;
403  break;
404  }
405  return interpf(val_ret, val_dst, mix_factor);
406 }
407 
409  void *dest,
410  const void **sources,
411  const float *weights,
412  const int count,
413  const float mix_factor)
414 {
415  const char **data_src = (const char **)sources;
416  char *data_dst = (char *)dest;
417 
418  const int mix_mode = laymap->mix_mode;
419  float val_src = 0.0f;
420  const float val_dst = (float)(*data_dst) / 255.0f;
421 
422  for (int i = count; i--;) {
423  val_src += ((float)(*data_src[i]) / 255.0f) * weights[i];
424  }
425 
426  val_src = data_transfer_interp_float_do(mix_mode, val_dst, val_src, mix_factor);
427 
428  CLAMP(val_src, 0.0f, 1.0f);
429 
430  *data_dst = (char)(val_src * 255.0f);
431 }
432 
433 /* Helpers to match sources and destinations data layers
434  * (also handles 'conversions' in CD_FAKE cases). */
435 
437  const int cddata_type,
438  const int mix_mode,
439  const float mix_factor,
440  const float *mix_weights,
441  const void *data_src,
442  void *data_dst,
443  const int data_src_n,
444  const int data_dst_n,
445  const size_t elem_size,
446  const size_t data_size,
447  const size_t data_offset,
448  const uint64_t data_flag,
450  void *interp_data)
451 {
452  CustomDataTransferLayerMap *item = MEM_mallocN(sizeof(*item), __func__);
453 
454  BLI_assert(data_dst != NULL);
455 
456  item->data_type = cddata_type;
457  item->mix_mode = mix_mode;
458  item->mix_factor = mix_factor;
459  item->mix_weights = mix_weights;
460 
461  item->data_src = data_src;
462  item->data_dst = data_dst;
463  item->data_src_n = data_src_n;
464  item->data_dst_n = data_dst_n;
465  item->elem_size = elem_size;
466 
467  item->data_size = data_size;
468  item->data_offset = data_offset;
469  item->data_flag = data_flag;
470 
471  item->interp = interp;
472  item->interp_data = interp_data;
473 
474  BLI_addtail(r_map, item);
475 }
476 
478  const int cddata_type,
479  const int mix_mode,
480  const float mix_factor,
481  const float *mix_weights,
482  const void *data_src,
483  void *data_dst,
485  void *interp_data)
486 {
487  uint64_t data_flag = 0;
488 
489  if (cddata_type == CD_FREESTYLE_EDGE) {
490  data_flag = FREESTYLE_EDGE_MARK;
491  }
492  else if (cddata_type == CD_FREESTYLE_FACE) {
493  data_flag = FREESTYLE_FACE_MARK;
494  }
495 
497  cddata_type,
498  mix_mode,
499  mix_factor,
500  mix_weights,
501  data_src,
502  data_dst,
503  0,
504  0,
505  0,
506  0,
507  0,
508  data_flag,
509  interp,
510  interp_data);
511 }
512 
521  const int cddata_type,
522  const int mix_mode,
523  const float mix_factor,
524  const float *mix_weights,
525  const int num_elem_dst,
526  const bool use_create,
527  const bool use_delete,
528  CustomData *cd_src,
529  CustomData *cd_dst,
530  const bool use_dupref_dst,
531  const int tolayers,
532  const bool *use_layers_src,
533  const int num_layers_src,
535  void *interp_data)
536 {
537  const void *data_src;
538  void *data_dst = NULL;
539  int idx_src = num_layers_src;
540  int idx_dst, tot_dst = CustomData_number_of_layers(cd_dst, cddata_type);
541  bool *data_dst_to_delete = NULL;
542 
543  if (!use_layers_src) {
544  /* No source at all, we can only delete all dest if requested... */
545  if (use_delete) {
546  idx_dst = tot_dst;
547  while (idx_dst--) {
548  CustomData_free_layer(cd_dst, cddata_type, num_elem_dst, idx_dst);
549  }
550  }
551  return true;
552  }
553 
554  switch (tolayers) {
555  case DT_LAYERS_INDEX_DST:
556  idx_dst = tot_dst;
557 
558  /* Find last source actually used! */
559  while (idx_src-- && !use_layers_src[idx_src]) {
560  /* pass */
561  }
562  idx_src++;
563 
564  if (idx_dst < idx_src) {
565  if (use_create) {
566  /* Create as much data layers as necessary! */
567  for (; idx_dst < idx_src; idx_dst++) {
568  CustomData_add_layer(cd_dst, cddata_type, CD_CALLOC, NULL, num_elem_dst);
569  }
570  }
571  else {
572  /* Otherwise, just try to map what we can with existing dst data layers. */
573  idx_src = idx_dst;
574  }
575  }
576  else if (use_delete && idx_dst > idx_src) {
577  while (idx_dst-- > idx_src) {
578  CustomData_free_layer(cd_dst, cddata_type, num_elem_dst, idx_dst);
579  }
580  }
581  if (r_map) {
582  while (idx_src--) {
583  if (!use_layers_src[idx_src]) {
584  continue;
585  }
586  data_src = CustomData_get_layer_n(cd_src, cddata_type, idx_src);
587  /* If dest is a evaluated mesh (from modifier),
588  * we do not want to overwrite cdlayers of orig mesh! */
589  if (use_dupref_dst) {
591  cd_dst, cddata_type, idx_src, num_elem_dst);
592  }
593  else {
594  data_dst = CustomData_get_layer_n(cd_dst, cddata_type, idx_src);
595  }
597  cddata_type,
598  mix_mode,
599  mix_factor,
600  mix_weights,
601  data_src,
602  data_dst,
603  interp,
604  interp_data);
605  }
606  }
607  break;
608  case DT_LAYERS_NAME_DST:
609  if (use_delete) {
610  if (tot_dst) {
611  data_dst_to_delete = MEM_mallocN(sizeof(*data_dst_to_delete) * (size_t)tot_dst,
612  __func__);
613  memset(data_dst_to_delete, true, sizeof(*data_dst_to_delete) * (size_t)tot_dst);
614  }
615  }
616 
617  while (idx_src--) {
618  const char *name;
619 
620  if (!use_layers_src[idx_src]) {
621  continue;
622  }
623 
624  name = CustomData_get_layer_name(cd_src, cddata_type, idx_src);
625  data_src = CustomData_get_layer_n(cd_src, cddata_type, idx_src);
626 
627  if ((idx_dst = CustomData_get_named_layer(cd_dst, cddata_type, name)) == -1) {
628  if (use_create) {
629  CustomData_add_layer_named(cd_dst, cddata_type, CD_CALLOC, NULL, num_elem_dst, name);
630  idx_dst = CustomData_get_named_layer(cd_dst, cddata_type, name);
631  }
632  else {
633  /* If we are not allowed to create missing dst data layers,
634  * just skip matching src one. */
635  continue;
636  }
637  }
638  else if (data_dst_to_delete) {
639  data_dst_to_delete[idx_dst] = false;
640  }
641  if (r_map) {
642  /* If dest is a evaluated mesh (from modifier),
643  * we do not want to overwrite cdlayers of orig mesh! */
644  if (use_dupref_dst) {
646  cd_dst, cddata_type, idx_dst, num_elem_dst);
647  }
648  else {
649  data_dst = CustomData_get_layer_n(cd_dst, cddata_type, idx_dst);
650  }
652  cddata_type,
653  mix_mode,
654  mix_factor,
655  mix_weights,
656  data_src,
657  data_dst,
658  interp,
659  interp_data);
660  }
661  }
662 
663  if (data_dst_to_delete) {
664  /* NOTE:
665  * This won't affect newly created layers, if any, since tot_dst has not been updated!
666  * Also, looping backward ensures us we do not suffer
667  * from index shifting when deleting a layer. */
668  for (idx_dst = tot_dst; idx_dst--;) {
669  if (data_dst_to_delete[idx_dst]) {
670  CustomData_free_layer(cd_dst, cddata_type, num_elem_dst, idx_dst);
671  }
672  }
673 
674  MEM_freeN(data_dst_to_delete);
675  }
676  break;
677  default:
678  return false;
679  }
680 
681  return true;
682 }
683 
685  const int cddata_type,
686  const int mix_mode,
687  const float mix_factor,
688  const float *mix_weights,
689  const int num_elem_dst,
690  const bool use_create,
691  const bool use_delete,
692  CustomData *cd_src,
693  CustomData *cd_dst,
694  const bool use_dupref_dst,
695  const int fromlayers,
696  const int tolayers,
698  void *interp_data)
699 {
700  int idx_src, idx_dst;
701  const void *data_src;
702  void *data_dst = NULL;
703 
704  if (CustomData_layertype_is_singleton(cddata_type)) {
705  if (!(data_src = CustomData_get_layer(cd_src, cddata_type))) {
706  if (use_delete) {
707  CustomData_free_layer(cd_dst, cddata_type, num_elem_dst, 0);
708  }
709  return true;
710  }
711 
712  data_dst = CustomData_get_layer(cd_dst, cddata_type);
713  if (!data_dst) {
714  if (!use_create) {
715  return true;
716  }
717  data_dst = CustomData_add_layer(cd_dst, cddata_type, CD_CALLOC, NULL, num_elem_dst);
718  }
719  else if (use_dupref_dst && r_map) {
720  /* If dest is a evaluated mesh (from modifier),
721  * we do not want to overwrite cdlayers of orig mesh! */
722  data_dst = CustomData_duplicate_referenced_layer(cd_dst, cddata_type, num_elem_dst);
723  }
724 
725  if (r_map) {
727  cddata_type,
728  mix_mode,
729  mix_factor,
730  mix_weights,
731  data_src,
732  data_dst,
733  interp,
734  interp_data);
735  }
736  }
737  else if (fromlayers == DT_LAYERS_ACTIVE_SRC || fromlayers >= 0) {
738  /* NOTE: use_delete has not much meaning in this case, ignored. */
739 
740  if (fromlayers >= 0) { /* Real-layer index */
741  idx_src = fromlayers;
742  }
743  else {
744  if ((idx_src = CustomData_get_active_layer(cd_src, cddata_type)) == -1) {
745  return true;
746  }
747  }
748  data_src = CustomData_get_layer_n(cd_src, cddata_type, idx_src);
749  if (!data_src) {
750  return true;
751  }
752 
753  if (tolayers >= 0) { /* Real-layer index */
754  idx_dst = tolayers;
755  /* If dest is a evaluated mesh (from modifier),
756  * we do not want to overwrite cdlayers of orig mesh! */
757  if (use_dupref_dst && r_map) {
759  cd_dst, cddata_type, idx_dst, num_elem_dst);
760  }
761  else {
762  data_dst = CustomData_get_layer_n(cd_dst, cddata_type, idx_dst);
763  }
764  }
765  else if (tolayers == DT_LAYERS_ACTIVE_DST) {
766  if ((idx_dst = CustomData_get_active_layer(cd_dst, cddata_type)) == -1) {
767  if (!use_create) {
768  return true;
769  }
770  data_dst = CustomData_add_layer(cd_dst, cddata_type, CD_CALLOC, NULL, num_elem_dst);
771  }
772  else {
773  /* If dest is a evaluated mesh (from modifier),
774  * we do not want to overwrite cdlayers of orig mesh! */
775  if (use_dupref_dst && r_map) {
777  cd_dst, cddata_type, idx_dst, num_elem_dst);
778  }
779  else {
780  data_dst = CustomData_get_layer_n(cd_dst, cddata_type, idx_dst);
781  }
782  }
783  }
784  else if (tolayers == DT_LAYERS_INDEX_DST) {
785  int num = CustomData_number_of_layers(cd_dst, cddata_type);
786  idx_dst = idx_src;
787  if (num <= idx_dst) {
788  if (!use_create) {
789  return true;
790  }
791  /* Create as much data layers as necessary! */
792  for (; num <= idx_dst; num++) {
793  CustomData_add_layer(cd_dst, cddata_type, CD_CALLOC, NULL, num_elem_dst);
794  }
795  }
796  /* If dest is a evaluated mesh (from modifier),
797  * we do not want to overwrite cdlayers of orig mesh! */
798  if (use_dupref_dst && r_map) {
800  cd_dst, cddata_type, idx_dst, num_elem_dst);
801  }
802  else {
803  data_dst = CustomData_get_layer_n(cd_dst, cddata_type, idx_dst);
804  }
805  }
806  else if (tolayers == DT_LAYERS_NAME_DST) {
807  const char *name = CustomData_get_layer_name(cd_src, cddata_type, idx_src);
808  if ((idx_dst = CustomData_get_named_layer(cd_dst, cddata_type, name)) == -1) {
809  if (!use_create) {
810  return true;
811  }
812  CustomData_add_layer_named(cd_dst, cddata_type, CD_CALLOC, NULL, num_elem_dst, name);
813  idx_dst = CustomData_get_named_layer(cd_dst, cddata_type, name);
814  }
815  /* If dest is a evaluated mesh (from modifier),
816  * we do not want to overwrite cdlayers of orig mesh! */
817  if (use_dupref_dst && r_map) {
819  cd_dst, cddata_type, idx_dst, num_elem_dst);
820  }
821  else {
822  data_dst = CustomData_get_layer_n(cd_dst, cddata_type, idx_dst);
823  }
824  }
825  else {
826  return false;
827  }
828 
829  if (!data_dst) {
830  return false;
831  }
832 
833  if (r_map) {
835  cddata_type,
836  mix_mode,
837  mix_factor,
838  mix_weights,
839  data_src,
840  data_dst,
841  interp,
842  interp_data);
843  }
844  }
845  else if (fromlayers == DT_LAYERS_ALL_SRC) {
846  int num_src = CustomData_number_of_layers(cd_src, cddata_type);
847  bool *use_layers_src = num_src ?
848  MEM_mallocN(sizeof(*use_layers_src) * (size_t)num_src, __func__) :
849  NULL;
850  bool ret;
851 
852  if (use_layers_src) {
853  memset(use_layers_src, true, sizeof(*use_layers_src) * num_src);
854  }
855 
857  cddata_type,
858  mix_mode,
859  mix_factor,
860  mix_weights,
861  num_elem_dst,
862  use_create,
863  use_delete,
864  cd_src,
865  cd_dst,
866  use_dupref_dst,
867  tolayers,
868  use_layers_src,
869  num_src,
870  interp,
871  interp_data);
872 
873  if (use_layers_src) {
874  MEM_freeN(use_layers_src);
875  }
876  return ret;
877  }
878  else {
879  return false;
880  }
881 
882  return true;
883 }
884 
886  Object *ob_src,
887  Object *ob_dst,
888  Mesh *me_src,
889  Mesh *me_dst,
890  const int elem_type,
891  int cddata_type,
892  int mix_mode,
893  float mix_factor,
894  const float *mix_weights,
895  const int num_elem_dst,
896  const bool use_create,
897  const bool use_delete,
898  const int fromlayers,
899  const int tolayers,
900  SpaceTransform *space_transform)
901 {
902  CustomData *cd_src, *cd_dst;
903 
905  void *interp_data = NULL;
906 
907  if (elem_type == ME_VERT) {
908  if (!(cddata_type & CD_FAKE)) {
909  cd_src = &me_src->vdata;
910  cd_dst = &me_dst->vdata;
911 
913  cddata_type,
914  mix_mode,
915  mix_factor,
916  mix_weights,
917  num_elem_dst,
918  use_create,
919  use_delete,
920  cd_src,
921  cd_dst,
922  me_dst != ob_dst->data,
923  fromlayers,
924  tolayers,
925  interp,
926  interp_data)) {
927  /* We handle specific source selection cases here. */
928  return false;
929  }
930  return true;
931  }
932  if (cddata_type == CD_FAKE_BWEIGHT) {
933  const size_t elem_size = sizeof(*((MVert *)NULL));
934  const size_t data_size = sizeof(((MVert *)NULL)->bweight);
935  const size_t data_offset = offsetof(MVert, bweight);
936  const uint64_t data_flag = 0;
937 
938  if (!(me_src->cd_flag & ME_CDFLAG_VERT_BWEIGHT)) {
939  if (use_delete) {
940  me_dst->cd_flag &= ~ME_CDFLAG_VERT_BWEIGHT;
941  }
942  return true;
943  }
944  me_dst->cd_flag |= ME_CDFLAG_VERT_BWEIGHT;
945  if (r_map) {
947  cddata_type,
948  mix_mode,
949  mix_factor,
950  mix_weights,
951  me_src->mvert,
952  me_dst->mvert,
953  me_src->totvert,
954  me_dst->totvert,
955  elem_size,
956  data_size,
957  data_offset,
958  data_flag,
960  interp_data);
961  }
962  return true;
963  }
964  if (cddata_type == CD_FAKE_MDEFORMVERT) {
965  bool ret;
966 
967  cd_src = &me_src->vdata;
968  cd_dst = &me_dst->vdata;
969 
971  mix_mode,
972  mix_factor,
973  mix_weights,
974  num_elem_dst,
975  use_create,
976  use_delete,
977  ob_src,
978  ob_dst,
979  cd_src,
980  cd_dst,
981  me_dst != ob_dst->data,
982  fromlayers,
983  tolayers);
984 
985  /* Mesh stores its dvert in a specific pointer too. :( */
986  me_dst->dvert = CustomData_get_layer(&me_dst->vdata, CD_MDEFORMVERT);
987  return ret;
988  }
989  if (cddata_type == CD_FAKE_SHAPEKEY) {
990  /* TODO: leaving shape-keys aside for now, quite specific case,
991  * since we can't access them from #MVert :/ */
992  return false;
993  }
994  }
995  else if (elem_type == ME_EDGE) {
996  if (!(cddata_type & CD_FAKE)) { /* Unused for edges, currently... */
997  cd_src = &me_src->edata;
998  cd_dst = &me_dst->edata;
999 
1001  cddata_type,
1002  mix_mode,
1003  mix_factor,
1004  mix_weights,
1005  num_elem_dst,
1006  use_create,
1007  use_delete,
1008  cd_src,
1009  cd_dst,
1010  me_dst != ob_dst->data,
1011  fromlayers,
1012  tolayers,
1013  interp,
1014  interp_data)) {
1015  /* We handle specific source selection cases here. */
1016  return false;
1017  }
1018  return true;
1019  }
1020  if (cddata_type == CD_FAKE_CREASE) {
1021  const size_t elem_size = sizeof(*((MEdge *)NULL));
1022  const size_t data_size = sizeof(((MEdge *)NULL)->crease);
1023  const size_t data_offset = offsetof(MEdge, crease);
1024  const uint64_t data_flag = 0;
1025 
1026  if (!(me_src->cd_flag & ME_CDFLAG_EDGE_CREASE)) {
1027  if (use_delete) {
1028  me_dst->cd_flag &= ~ME_CDFLAG_EDGE_CREASE;
1029  }
1030  return true;
1031  }
1032  me_dst->cd_flag |= ME_CDFLAG_EDGE_CREASE;
1033  if (r_map) {
1035  cddata_type,
1036  mix_mode,
1037  mix_factor,
1038  mix_weights,
1039  me_src->medge,
1040  me_dst->medge,
1041  me_src->totedge,
1042  me_dst->totedge,
1043  elem_size,
1044  data_size,
1045  data_offset,
1046  data_flag,
1048  interp_data);
1049  }
1050  return true;
1051  }
1052  if (cddata_type == CD_FAKE_BWEIGHT) {
1053  const size_t elem_size = sizeof(*((MEdge *)NULL));
1054  const size_t data_size = sizeof(((MEdge *)NULL)->bweight);
1055  const size_t data_offset = offsetof(MEdge, bweight);
1056  const uint64_t data_flag = 0;
1057 
1058  if (!(me_src->cd_flag & ME_CDFLAG_EDGE_BWEIGHT)) {
1059  if (use_delete) {
1060  me_dst->cd_flag &= ~ME_CDFLAG_EDGE_BWEIGHT;
1061  }
1062  return true;
1063  }
1064  me_dst->cd_flag |= ME_CDFLAG_EDGE_BWEIGHT;
1065  if (r_map) {
1067  cddata_type,
1068  mix_mode,
1069  mix_factor,
1070  mix_weights,
1071  me_src->medge,
1072  me_dst->medge,
1073  me_src->totedge,
1074  me_dst->totedge,
1075  elem_size,
1076  data_size,
1077  data_offset,
1078  data_flag,
1080  interp_data);
1081  }
1082  return true;
1083  }
1084  if (r_map && ELEM(cddata_type, CD_FAKE_SHARP, CD_FAKE_SEAM)) {
1085  const size_t elem_size = sizeof(*((MEdge *)NULL));
1086  const size_t data_size = sizeof(((MEdge *)NULL)->flag);
1087  const size_t data_offset = offsetof(MEdge, flag);
1088  const uint64_t data_flag = (cddata_type == CD_FAKE_SHARP) ? ME_SHARP : ME_SEAM;
1089 
1091  cddata_type,
1092  mix_mode,
1093  mix_factor,
1094  mix_weights,
1095  me_src->medge,
1096  me_dst->medge,
1097  me_src->totedge,
1098  me_dst->totedge,
1099  elem_size,
1100  data_size,
1101  data_offset,
1102  data_flag,
1103  NULL,
1104  interp_data);
1105  return true;
1106  }
1107 
1108  return false;
1109  }
1110  else if (elem_type == ME_LOOP) {
1111  if (cddata_type == CD_FAKE_UV) {
1112  cddata_type = CD_MLOOPUV;
1113  }
1114  else if (cddata_type == CD_FAKE_LNOR) {
1115  /* Pre-process should have generated it,
1116  * Post-process will convert it back to CD_CUSTOMLOOPNORMAL. */
1117  cddata_type = CD_NORMAL;
1118  interp_data = space_transform;
1120  }
1121 
1122  if (!(cddata_type & CD_FAKE)) {
1123  cd_src = &me_src->ldata;
1124  cd_dst = &me_dst->ldata;
1125 
1127  cddata_type,
1128  mix_mode,
1129  mix_factor,
1130  mix_weights,
1131  num_elem_dst,
1132  use_create,
1133  use_delete,
1134  cd_src,
1135  cd_dst,
1136  me_dst != ob_dst->data,
1137  fromlayers,
1138  tolayers,
1139  interp,
1140  interp_data)) {
1141  /* We handle specific source selection cases here. */
1142  return false;
1143  }
1144  return true;
1145  }
1146 
1147  return false;
1148  }
1149  else if (elem_type == ME_POLY) {
1150  if (cddata_type == CD_FAKE_UV) {
1151  cddata_type = CD_MLOOPUV;
1152  }
1153 
1154  if (!(cddata_type & CD_FAKE)) {
1155  cd_src = &me_src->pdata;
1156  cd_dst = &me_dst->pdata;
1157 
1159  cddata_type,
1160  mix_mode,
1161  mix_factor,
1162  mix_weights,
1163  num_elem_dst,
1164  use_create,
1165  use_delete,
1166  cd_src,
1167  cd_dst,
1168  me_dst != ob_dst->data,
1169  fromlayers,
1170  tolayers,
1171  interp,
1172  interp_data)) {
1173  /* We handle specific source selection cases here. */
1174  return false;
1175  }
1176  return true;
1177  }
1178  if (r_map && cddata_type == CD_FAKE_SHARP) {
1179  const size_t elem_size = sizeof(*((MPoly *)NULL));
1180  const size_t data_size = sizeof(((MPoly *)NULL)->flag);
1181  const size_t data_offset = offsetof(MPoly, flag);
1182  const uint64_t data_flag = ME_SMOOTH;
1183 
1185  cddata_type,
1186  mix_mode,
1187  mix_factor,
1188  mix_weights,
1189  me_src->mpoly,
1190  me_dst->mpoly,
1191  me_src->totpoly,
1192  me_dst->totpoly,
1193  elem_size,
1194  data_size,
1195  data_offset,
1196  data_flag,
1197  NULL,
1198  interp_data);
1199  return true;
1200  }
1201 
1202  return false;
1203  }
1204 
1205  return false;
1206 }
1207 
1209  Scene *scene,
1210  Object *ob_src,
1211  Object *ob_dst,
1212  const int data_types,
1213  const bool use_delete,
1214  const int fromlayers_select[DT_MULTILAYER_INDEX_MAX],
1215  const int tolayers_select[DT_MULTILAYER_INDEX_MAX])
1216 {
1217  Mesh *me_src;
1218  Mesh *me_dst;
1219 
1220  const bool use_create = true; /* We always create needed layers here. */
1221 
1222  CustomData_MeshMasks me_src_mask = CD_MASK_BAREMESH;
1223 
1224  BLI_assert((ob_src != ob_dst) && (ob_src->type == OB_MESH) && (ob_dst->type == OB_MESH));
1225 
1226  me_dst = ob_dst->data;
1227 
1228  /* Get source evaluated mesh. */
1229  BKE_object_data_transfer_dttypes_to_cdmask(data_types, &me_src_mask);
1230  me_src = mesh_get_eval_final(depsgraph, scene, ob_src, &me_src_mask);
1231  if (!me_src) {
1232  return;
1233  }
1234 
1235  /* Check all possible data types. */
1236  for (int i = 0; i < DT_TYPE_MAX; i++) {
1237  const int dtdata_type = 1 << i;
1238  int cddata_type;
1239  int fromlayers, tolayers, fromto_idx;
1240 
1241  if (!(data_types & dtdata_type)) {
1242  continue;
1243  }
1244 
1245  cddata_type = BKE_object_data_transfer_dttype_to_cdtype(dtdata_type);
1246 
1247  fromto_idx = BKE_object_data_transfer_dttype_to_srcdst_index(dtdata_type);
1248 
1249  if (fromto_idx != DT_MULTILAYER_INDEX_INVALID) {
1250  fromlayers = fromlayers_select[fromto_idx];
1251  tolayers = tolayers_select[fromto_idx];
1252  }
1253  else {
1254  fromlayers = tolayers = 0;
1255  }
1256 
1257  if (DT_DATATYPE_IS_VERT(dtdata_type)) {
1258  const int num_elem_dst = me_dst->totvert;
1259 
1261  ob_src,
1262  ob_dst,
1263  me_src,
1264  me_dst,
1265  ME_VERT,
1266  cddata_type,
1267  0,
1268  0.0f,
1269  NULL,
1270  num_elem_dst,
1271  use_create,
1272  use_delete,
1273  fromlayers,
1274  tolayers,
1275  NULL);
1276  }
1277  if (DT_DATATYPE_IS_EDGE(dtdata_type)) {
1278  const int num_elem_dst = me_dst->totedge;
1279 
1281  ob_src,
1282  ob_dst,
1283  me_src,
1284  me_dst,
1285  ME_EDGE,
1286  cddata_type,
1287  0,
1288  0.0f,
1289  NULL,
1290  num_elem_dst,
1291  use_create,
1292  use_delete,
1293  fromlayers,
1294  tolayers,
1295  NULL);
1296  }
1297  if (DT_DATATYPE_IS_LOOP(dtdata_type)) {
1298  const int num_elem_dst = me_dst->totloop;
1299 
1301  ob_src,
1302  ob_dst,
1303  me_src,
1304  me_dst,
1305  ME_LOOP,
1306  cddata_type,
1307  0,
1308  0.0f,
1309  NULL,
1310  num_elem_dst,
1311  use_create,
1312  use_delete,
1313  fromlayers,
1314  tolayers,
1315  NULL);
1316  }
1317  if (DT_DATATYPE_IS_POLY(dtdata_type)) {
1318  const int num_elem_dst = me_dst->totpoly;
1319 
1321  ob_src,
1322  ob_dst,
1323  me_src,
1324  me_dst,
1325  ME_POLY,
1326  cddata_type,
1327  0,
1328  0.0f,
1329  NULL,
1330  num_elem_dst,
1331  use_create,
1332  use_delete,
1333  fromlayers,
1334  tolayers,
1335  NULL);
1336  }
1337  }
1338 }
1339 
1341  Scene *scene,
1342  Object *ob_src,
1343  Object *ob_dst,
1344  Mesh *me_dst,
1345  const int data_types,
1346  bool use_create,
1347  const int map_vert_mode,
1348  const int map_edge_mode,
1349  const int map_loop_mode,
1350  const int map_poly_mode,
1351  SpaceTransform *space_transform,
1352  const bool auto_transform,
1353  const float max_distance,
1354  const float ray_radius,
1355  const float islands_handling_precision,
1356  const int fromlayers_select[DT_MULTILAYER_INDEX_MAX],
1357  const int tolayers_select[DT_MULTILAYER_INDEX_MAX],
1358  const int mix_mode,
1359  const float mix_factor,
1360  const char *vgroup_name,
1361  const bool invert_vgroup,
1362  ReportList *reports)
1363 {
1364 #define VDATA 0
1365 #define EDATA 1
1366 #define LDATA 2
1367 #define PDATA 3
1368 #define DATAMAX 4
1369 
1370  SpaceTransform auto_space_transform;
1371 
1372  Mesh *me_src;
1373  /* Assumed always true if not using an evaluated mesh as destination. */
1374  bool dirty_nors_dst = true;
1375 
1376  const MDeformVert *mdef = NULL;
1377  int vg_idx = -1;
1378  float *weights[DATAMAX] = {NULL};
1379 
1380  MeshPairRemap geom_map[DATAMAX] = {{0}};
1381  bool geom_map_init[DATAMAX] = {0};
1382  ListBase lay_map = {NULL};
1383  bool changed = false;
1384  bool is_modifier = false;
1385 
1386  const bool use_delete = false; /* We never delete data layers from destination here. */
1387 
1388  CustomData_MeshMasks me_src_mask = CD_MASK_BAREMESH;
1389 
1390  BLI_assert((ob_src != ob_dst) && (ob_src->type == OB_MESH) && (ob_dst->type == OB_MESH));
1391 
1392  if (me_dst) {
1393  dirty_nors_dst = BKE_mesh_vertex_normals_are_dirty(me_dst);
1394  /* Never create needed custom layers on passed destination mesh
1395  * (assumed to *not* be ob_dst->data, aka modifier case). */
1396  use_create = false;
1397  is_modifier = true;
1398  }
1399  else {
1400  me_dst = ob_dst->data;
1401  }
1402 
1403  if (vgroup_name) {
1404  mdef = CustomData_get_layer(&me_dst->vdata, CD_MDEFORMVERT);
1405  if (mdef) {
1406  vg_idx = BKE_id_defgroup_name_index(&me_dst->id, vgroup_name);
1407  }
1408  }
1409 
1410  /* Get source evaluated mesh. */
1411  BKE_object_data_transfer_dttypes_to_cdmask(data_types, &me_src_mask);
1413  map_vert_mode, map_edge_mode, map_loop_mode, map_poly_mode, &me_src_mask);
1414  if (is_modifier) {
1416 
1417  if (me_src == NULL ||
1418  !CustomData_MeshMasks_are_matching(&ob_src->runtime.last_data_mask, &me_src_mask)) {
1419  CLOG_WARN(&LOG, "Data Transfer: source mesh data is not ready - dependency cycle?");
1420  return changed;
1421  }
1422  }
1423  else {
1424  me_src = mesh_get_eval_final(depsgraph, scene, ob_src, &me_src_mask);
1425  }
1426  if (!me_src) {
1427  return changed;
1428  }
1430 
1431  if (auto_transform) {
1432  if (space_transform == NULL) {
1433  space_transform = &auto_space_transform;
1434  }
1435 
1437  me_dst->mvert, me_dst->totvert, me_src, space_transform);
1438  }
1439 
1440  /* Check all possible data types.
1441  * Note item mappings and dest mix weights are cached. */
1442  for (int i = 0; i < DT_TYPE_MAX; i++) {
1443  const int dtdata_type = 1 << i;
1444  int cddata_type;
1445  int fromlayers, tolayers, fromto_idx;
1446 
1447  if (!(data_types & dtdata_type)) {
1448  continue;
1449  }
1450 
1451  data_transfer_dtdata_type_preprocess(me_src, me_dst, dtdata_type, dirty_nors_dst);
1452 
1453  cddata_type = BKE_object_data_transfer_dttype_to_cdtype(dtdata_type);
1454 
1455  fromto_idx = BKE_object_data_transfer_dttype_to_srcdst_index(dtdata_type);
1456  if (fromto_idx != DT_MULTILAYER_INDEX_INVALID) {
1457  fromlayers = fromlayers_select[fromto_idx];
1458  tolayers = tolayers_select[fromto_idx];
1459  }
1460  else {
1461  fromlayers = tolayers = 0;
1462  }
1463 
1464  if (DT_DATATYPE_IS_VERT(dtdata_type)) {
1465  MVert *verts_dst = me_dst->mvert;
1466  const int num_verts_dst = me_dst->totvert;
1467 
1468  if (!geom_map_init[VDATA]) {
1469  const int num_verts_src = me_src->totvert;
1470 
1471  if ((map_vert_mode == MREMAP_MODE_TOPOLOGY) && (num_verts_dst != num_verts_src)) {
1472  BKE_report(reports,
1473  RPT_ERROR,
1474  "Source and destination meshes do not have the same amount of vertices, "
1475  "'Topology' mapping cannot be used in this case");
1476  continue;
1477  }
1478  if ((map_vert_mode & MREMAP_USE_EDGE) && (me_src->totedge == 0)) {
1479  BKE_report(reports,
1480  RPT_ERROR,
1481  "Source mesh doesn't have any edges, "
1482  "None of the 'Edge' mappings can be used in this case");
1483  continue;
1484  }
1485  if ((map_vert_mode & MREMAP_USE_POLY) && (me_src->totpoly == 0)) {
1486  BKE_report(reports,
1487  RPT_ERROR,
1488  "Source mesh doesn't have any faces, "
1489  "None of the 'Face' mappings can be used in this case");
1490  continue;
1491  }
1492  if (ELEM(0, num_verts_dst, num_verts_src)) {
1493  BKE_report(reports,
1494  RPT_ERROR,
1495  "Source or destination meshes do not have any vertices, cannot transfer "
1496  "vertex data");
1497  continue;
1498  }
1499 
1501  space_transform,
1502  max_distance,
1503  ray_radius,
1504  verts_dst,
1505  num_verts_dst,
1506  dirty_nors_dst,
1507  me_src,
1508  me_dst,
1509  &geom_map[VDATA]);
1510  geom_map_init[VDATA] = true;
1511  }
1512 
1513  if (mdef && vg_idx != -1 && !weights[VDATA]) {
1514  weights[VDATA] = MEM_mallocN(sizeof(*(weights[VDATA])) * (size_t)num_verts_dst, __func__);
1516  mdef, vg_idx, num_verts_dst, invert_vgroup, weights[VDATA]);
1517  }
1518 
1520  ob_src,
1521  ob_dst,
1522  me_src,
1523  me_dst,
1524  ME_VERT,
1525  cddata_type,
1526  mix_mode,
1527  mix_factor,
1528  weights[VDATA],
1529  num_verts_dst,
1530  use_create,
1531  use_delete,
1532  fromlayers,
1533  tolayers,
1534  space_transform)) {
1535  CustomDataTransferLayerMap *lay_mapit;
1536 
1537  changed |= (lay_map.first != NULL);
1538 
1539  for (lay_mapit = lay_map.first; lay_mapit; lay_mapit = lay_mapit->next) {
1540  CustomData_data_transfer(&geom_map[VDATA], lay_mapit);
1541  }
1542 
1543  BLI_freelistN(&lay_map);
1544  }
1545  }
1546  if (DT_DATATYPE_IS_EDGE(dtdata_type)) {
1547  MVert *verts_dst = me_dst->mvert;
1548  const int num_verts_dst = me_dst->totvert;
1549  MEdge *edges_dst = me_dst->medge;
1550  const int num_edges_dst = me_dst->totedge;
1551 
1552  if (!geom_map_init[EDATA]) {
1553  const int num_edges_src = me_src->totedge;
1554 
1555  if ((map_edge_mode == MREMAP_MODE_TOPOLOGY) && (num_edges_dst != num_edges_src)) {
1556  BKE_report(reports,
1557  RPT_ERROR,
1558  "Source and destination meshes do not have the same amount of edges, "
1559  "'Topology' mapping cannot be used in this case");
1560  continue;
1561  }
1562  if ((map_edge_mode & MREMAP_USE_POLY) && (me_src->totpoly == 0)) {
1563  BKE_report(reports,
1564  RPT_ERROR,
1565  "Source mesh doesn't have any faces, "
1566  "None of the 'Face' mappings can be used in this case");
1567  continue;
1568  }
1569  if (ELEM(0, num_edges_dst, num_edges_src)) {
1570  BKE_report(
1571  reports,
1572  RPT_ERROR,
1573  "Source or destination meshes do not have any edges, cannot transfer edge data");
1574  continue;
1575  }
1576 
1578  space_transform,
1579  max_distance,
1580  ray_radius,
1581  verts_dst,
1582  num_verts_dst,
1583  edges_dst,
1584  num_edges_dst,
1585  dirty_nors_dst,
1586  me_src,
1587  me_dst,
1588  &geom_map[EDATA]);
1589  geom_map_init[EDATA] = true;
1590  }
1591 
1592  if (mdef && vg_idx != -1 && !weights[EDATA]) {
1593  weights[EDATA] = MEM_mallocN(sizeof(*weights[EDATA]) * (size_t)num_edges_dst, __func__);
1595  mdef, vg_idx, num_verts_dst, edges_dst, num_edges_dst, invert_vgroup, weights[EDATA]);
1596  }
1597 
1599  ob_src,
1600  ob_dst,
1601  me_src,
1602  me_dst,
1603  ME_EDGE,
1604  cddata_type,
1605  mix_mode,
1606  mix_factor,
1607  weights[EDATA],
1608  num_edges_dst,
1609  use_create,
1610  use_delete,
1611  fromlayers,
1612  tolayers,
1613  space_transform)) {
1614  CustomDataTransferLayerMap *lay_mapit;
1615 
1616  changed |= (lay_map.first != NULL);
1617 
1618  for (lay_mapit = lay_map.first; lay_mapit; lay_mapit = lay_mapit->next) {
1619  CustomData_data_transfer(&geom_map[EDATA], lay_mapit);
1620  }
1621 
1622  BLI_freelistN(&lay_map);
1623  }
1624  }
1625  if (DT_DATATYPE_IS_LOOP(dtdata_type)) {
1626  MVert *verts_dst = me_dst->mvert;
1627  const int num_verts_dst = me_dst->totvert;
1628  MEdge *edges_dst = me_dst->medge;
1629  const int num_edges_dst = me_dst->totedge;
1630  MPoly *polys_dst = me_dst->mpoly;
1631  const int num_polys_dst = me_dst->totpoly;
1632  MLoop *loops_dst = me_dst->mloop;
1633  const int num_loops_dst = me_dst->totloop;
1634  CustomData *ldata_dst = &me_dst->ldata;
1635 
1636  MeshRemapIslandsCalc island_callback = data_transfer_get_loop_islands_generator(cddata_type);
1637 
1638  if (!geom_map_init[LDATA]) {
1639  const int num_loops_src = me_src->totloop;
1640 
1641  if ((map_loop_mode == MREMAP_MODE_TOPOLOGY) && (num_loops_dst != num_loops_src)) {
1642  BKE_report(reports,
1643  RPT_ERROR,
1644  "Source and destination meshes do not have the same amount of face corners, "
1645  "'Topology' mapping cannot be used in this case");
1646  continue;
1647  }
1648  if ((map_loop_mode & MREMAP_USE_EDGE) && (me_src->totedge == 0)) {
1649  BKE_report(reports,
1650  RPT_ERROR,
1651  "Source mesh doesn't have any edges, "
1652  "None of the 'Edge' mappings can be used in this case");
1653  continue;
1654  }
1655  if (ELEM(0, num_loops_dst, num_loops_src)) {
1656  BKE_report(
1657  reports,
1658  RPT_ERROR,
1659  "Source or destination meshes do not have any faces, cannot transfer corner data");
1660  continue;
1661  }
1662 
1664  space_transform,
1665  max_distance,
1666  ray_radius,
1667  me_dst,
1668  verts_dst,
1669  num_verts_dst,
1670  edges_dst,
1671  num_edges_dst,
1672  loops_dst,
1673  num_loops_dst,
1674  polys_dst,
1675  num_polys_dst,
1676  ldata_dst,
1677  (me_dst->flag & ME_AUTOSMOOTH) != 0,
1678  me_dst->smoothresh,
1679  dirty_nors_dst,
1680  me_src,
1681  island_callback,
1682  islands_handling_precision,
1683  &geom_map[LDATA]);
1684  geom_map_init[LDATA] = true;
1685  }
1686 
1687  if (mdef && vg_idx != -1 && !weights[LDATA]) {
1688  weights[LDATA] = MEM_mallocN(sizeof(*weights[LDATA]) * (size_t)num_loops_dst, __func__);
1690  mdef, vg_idx, num_verts_dst, loops_dst, num_loops_dst, invert_vgroup, weights[LDATA]);
1691  }
1692 
1694  ob_src,
1695  ob_dst,
1696  me_src,
1697  me_dst,
1698  ME_LOOP,
1699  cddata_type,
1700  mix_mode,
1701  mix_factor,
1702  weights[LDATA],
1703  num_loops_dst,
1704  use_create,
1705  use_delete,
1706  fromlayers,
1707  tolayers,
1708  space_transform)) {
1709  CustomDataTransferLayerMap *lay_mapit;
1710 
1711  changed |= (lay_map.first != NULL);
1712 
1713  for (lay_mapit = lay_map.first; lay_mapit; lay_mapit = lay_mapit->next) {
1714  CustomData_data_transfer(&geom_map[LDATA], lay_mapit);
1715  }
1716 
1717  BLI_freelistN(&lay_map);
1718  }
1719  }
1720  if (DT_DATATYPE_IS_POLY(dtdata_type)) {
1721  MVert *verts_dst = me_dst->mvert;
1722  const int num_verts_dst = me_dst->totvert;
1723  MPoly *polys_dst = me_dst->mpoly;
1724  const int num_polys_dst = me_dst->totpoly;
1725  MLoop *loops_dst = me_dst->mloop;
1726  const int num_loops_dst = me_dst->totloop;
1727 
1728  if (!geom_map_init[PDATA]) {
1729  const int num_polys_src = me_src->totpoly;
1730 
1731  if ((map_poly_mode == MREMAP_MODE_TOPOLOGY) && (num_polys_dst != num_polys_src)) {
1732  BKE_report(reports,
1733  RPT_ERROR,
1734  "Source and destination meshes do not have the same amount of faces, "
1735  "'Topology' mapping cannot be used in this case");
1736  continue;
1737  }
1738  if ((map_poly_mode & MREMAP_USE_EDGE) && (me_src->totedge == 0)) {
1739  BKE_report(reports,
1740  RPT_ERROR,
1741  "Source mesh doesn't have any edges, "
1742  "None of the 'Edge' mappings can be used in this case");
1743  continue;
1744  }
1745  if (ELEM(0, num_polys_dst, num_polys_src)) {
1746  BKE_report(
1747  reports,
1748  RPT_ERROR,
1749  "Source or destination meshes do not have any faces, cannot transfer face data");
1750  continue;
1751  }
1752 
1754  space_transform,
1755  max_distance,
1756  ray_radius,
1757  me_dst,
1758  verts_dst,
1759  loops_dst,
1760  polys_dst,
1761  num_polys_dst,
1762  me_src,
1763  &geom_map[PDATA]);
1764  geom_map_init[PDATA] = true;
1765  }
1766 
1767  if (mdef && vg_idx != -1 && !weights[PDATA]) {
1768  weights[PDATA] = MEM_mallocN(sizeof(*weights[PDATA]) * (size_t)num_polys_dst, __func__);
1770  vg_idx,
1771  num_verts_dst,
1772  loops_dst,
1773  num_loops_dst,
1774  polys_dst,
1775  num_polys_dst,
1776  invert_vgroup,
1777  weights[PDATA]);
1778  }
1779 
1781  ob_src,
1782  ob_dst,
1783  me_src,
1784  me_dst,
1785  ME_POLY,
1786  cddata_type,
1787  mix_mode,
1788  mix_factor,
1789  weights[PDATA],
1790  num_polys_dst,
1791  use_create,
1792  use_delete,
1793  fromlayers,
1794  tolayers,
1795  space_transform)) {
1796  CustomDataTransferLayerMap *lay_mapit;
1797 
1798  changed |= (lay_map.first != NULL);
1799 
1800  for (lay_mapit = lay_map.first; lay_mapit; lay_mapit = lay_mapit->next) {
1801  CustomData_data_transfer(&geom_map[PDATA], lay_mapit);
1802  }
1803 
1804  BLI_freelistN(&lay_map);
1805  }
1806  }
1807 
1808  data_transfer_dtdata_type_postprocess(ob_src, ob_dst, me_src, me_dst, dtdata_type, changed);
1809  }
1810 
1811  for (int i = 0; i < DATAMAX; i++) {
1812  BKE_mesh_remap_free(&geom_map[i]);
1813  MEM_SAFE_FREE(weights[i]);
1814  }
1815 
1816  return changed;
1817 
1818 #undef VDATA
1819 #undef EDATA
1820 #undef LDATA
1821 #undef PDATA
1822 #undef DATAMAX
1823 }
1824 
1826  Scene *scene,
1827  Object *ob_src,
1828  Object *ob_dst,
1829  const int data_types,
1830  const bool use_create,
1831  const int map_vert_mode,
1832  const int map_edge_mode,
1833  const int map_loop_mode,
1834  const int map_poly_mode,
1835  SpaceTransform *space_transform,
1836  const bool auto_transform,
1837  const float max_distance,
1838  const float ray_radius,
1839  const float islands_handling_precision,
1840  const int fromlayers_select[DT_MULTILAYER_INDEX_MAX],
1841  const int tolayers_select[DT_MULTILAYER_INDEX_MAX],
1842  const int mix_mode,
1843  const float mix_factor,
1844  const char *vgroup_name,
1845  const bool invert_vgroup,
1846  ReportList *reports)
1847 {
1849  scene,
1850  ob_src,
1851  ob_dst,
1852  NULL,
1853  data_types,
1854  use_create,
1855  map_vert_mode,
1856  map_edge_mode,
1857  map_loop_mode,
1858  map_poly_mode,
1859  space_transform,
1860  auto_transform,
1861  max_distance,
1862  ray_radius,
1863  islands_handling_precision,
1864  fromlayers_select,
1865  tolayers_select,
1866  mix_mode,
1867  mix_factor,
1868  vgroup_name,
1869  invert_vgroup,
1870  reports);
1871 }
typedef float(TangentPoint)[2]
Generic geometry attributes built on CustomData.
CustomData interface, see also DNA_customdata_types.h.
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)
bool CustomData_free_layer(struct CustomData *data, int type, int totelem, int index)
Definition: customdata.cc:2831
@ CD_CALLOC
@ ME_VERT
@ ME_POLY
@ ME_LOOP
@ ME_EDGE
bool CustomData_layertype_is_singleton(int type)
Definition: customdata.cc:4280
void(* cd_datatransfer_interp)(const struct CustomDataTransferLayerMap *laymap, void *dest, const void **sources, const float *weights, int count, float mix_factor)
void CustomData_data_transfer(const struct MeshPairRemap *me_remap, const CustomDataTransferLayerMap *laymap)
bool CustomData_MeshMasks_are_matching(const CustomData_MeshMasks *mask_ref, const CustomData_MeshMasks *mask_required)
Definition: customdata.cc:87
void * CustomData_add_layer_named(struct CustomData *data, int type, eCDAllocType alloctype, void *layer, int totelem, const char *name)
Definition: customdata.cc:2792
const CustomData_MeshMasks CD_MASK_BAREMESH
Definition: customdata.cc:2051
int CustomData_get_active_layer(const struct CustomData *data, int type)
void * CustomData_get_layer_n(const struct CustomData *data, int type, int n)
@ CD_FAKE_UV
@ CD_FAKE_LNOR
@ CD_FAKE_CREASE
@ CD_FAKE
@ CD_FAKE_SHARP
@ CD_FAKE_BWEIGHT
@ CD_FAKE_MDEFORMVERT
@ CD_FAKE_SHAPEKEY
@ CD_FAKE_SEAM
void * CustomData_get_layer(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
int CustomData_get_named_layer(const struct CustomData *data, int type, const char *name)
void * CustomData_add_layer(struct CustomData *data, int type, eCDAllocType alloctype, void *layer, int totelem)
Definition: customdata.cc:2776
void CustomData_set_layer_flag(struct CustomData *data, int type, int flag)
Definition: customdata.cc:2626
void * CustomData_duplicate_referenced_layer(struct CustomData *data, int type, int totelem)
Definition: customdata.cc:2976
void * CustomData_duplicate_referenced_layer_n(struct CustomData *data, int type, int n, int totelem)
Definition: customdata.cc:2984
@ DT_MULTILAYER_INDEX_MAX
@ DT_MULTILAYER_INDEX_MDEFORMVERT
@ DT_MULTILAYER_INDEX_INVALID
@ DT_MULTILAYER_INDEX_SHAPEKEY
@ DT_MULTILAYER_INDEX_UV
@ DT_MULTILAYER_INDEX_VCOL_VERT
@ DT_MULTILAYER_INDEX_VCOL_LOOP
@ DT_LAYERS_ALL_SRC
@ DT_LAYERS_ACTIVE_SRC
#define DT_DATATYPE_IS_POLY(_dt)
#define DT_TYPE_MAX
#define DT_DATATYPE_IS_LOOP(_dt)
#define DT_DATATYPE_IS_EDGE(_dt)
@ DT_LAYERS_ACTIVE_DST
@ DT_LAYERS_INDEX_DST
@ DT_LAYERS_NAME_DST
@ 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.
void BKE_defvert_extract_vgroup_to_polyweights(const struct MDeformVert *dvert, int defgroup, int num_verts, struct MLoop *loops, int num_loops, struct MPoly *polys, int num_polys, bool invert_vgroup, float *r_weights)
void BKE_defvert_extract_vgroup_to_edgeweights(const struct MDeformVert *dvert, int defgroup, int num_verts, struct MEdge *edges, int num_edges, bool invert_vgroup, float *r_weights)
int BKE_id_defgroup_name_index(const struct ID *id, const char *name)
void BKE_defvert_extract_vgroup_to_loopweights(const struct MDeformVert *dvert, int defgroup, int num_verts, struct MLoop *loops, int num_loops, bool invert_vgroup, float *r_weights)
void BKE_defvert_extract_vgroup_to_vertweights(const struct MDeformVert *dvert, int defgroup, int num_verts, bool invert_vgroup, float *r_weights)
const float(* BKE_mesh_poly_normals_ensure(const struct Mesh *mesh))[3]
void BKE_mesh_normals_loop_custom_set(const struct MVert *mverts, const float(*vert_normals)[3], int numVerts, struct MEdge *medges, int numEdges, struct MLoop *mloops, float(*r_custom_loopnors)[3], int numLoops, struct MPoly *mpolys, const float(*polynors)[3], int numPolys, short(*r_clnors_data)[2])
const float(* BKE_mesh_vertex_normals_ensure(const struct Mesh *mesh))[3]
bool BKE_mesh_vertex_normals_are_dirty(const struct Mesh *mesh)
void BKE_mesh_normals_loop_split(const struct MVert *mverts, const float(*vert_normals)[3], int numVerts, struct MEdge *medges, int numEdges, struct MLoop *mloops, float(*r_loopnors)[3], int numLoops, struct MPoly *mpolys, const float(*polynors)[3], int numPolys, bool use_split_normals, float split_angle, MLoopNorSpaceArray *r_lnors_spacearr, short(*clnors_data)[2], int *r_loop_to_poly)
bool(* MeshRemapIslandsCalc)(struct MVert *verts, int totvert, struct MEdge *edges, int totedge, struct MPoly *polys, int totpoly, struct MLoop *loops, int totloop, struct MeshIslandStore *r_island_store)
bool BKE_mesh_calc_islands_loop_poly_edgeseam(struct MVert *verts, int totvert, struct MEdge *edges, int totedge, struct MPoly *polys, int totpoly, struct MLoop *loops, int totloop, MeshIslandStore *r_island_store)
void BKE_mesh_remap_calc_edges_from_mesh(int mode, const struct SpaceTransform *space_transform, float max_dist, float ray_radius, const struct MVert *verts_dst, int numverts_dst, const struct MEdge *edges_dst, int numedges_dst, bool dirty_nors_dst, struct Mesh *me_src, struct Mesh *me_dst, MeshPairRemap *r_map)
void BKE_mesh_remap_calc_verts_from_mesh(int mode, const struct SpaceTransform *space_transform, float max_dist, float ray_radius, const struct MVert *verts_dst, int numverts_dst, bool dirty_nors_dst, struct Mesh *me_src, struct Mesh *me_dst, MeshPairRemap *r_map)
void BKE_mesh_remap_free(MeshPairRemap *map)
Definition: mesh_remap.c:338
void BKE_mesh_remap_find_best_match_from_mesh(const struct MVert *verts_dst, int numverts_dst, struct Mesh *me_src, struct SpaceTransform *r_space_transform)
void BKE_mesh_remap_calc_source_cddata_masks_from_map_modes(int vert_mode, int edge_mode, int loop_mode, int poly_mode, struct CustomData_MeshMasks *cddata_mask)
void BKE_mesh_remap_calc_polys_from_mesh(int mode, const struct SpaceTransform *space_transform, float max_dist, float ray_radius, struct Mesh *mesh_dst, struct MVert *verts_dst, struct MLoop *loops_dst, struct MPoly *polys_dst, int numpolys_dst, struct Mesh *me_src, struct MeshPairRemap *r_map)
void BKE_mesh_remap_calc_loops_from_mesh(int mode, const struct SpaceTransform *space_transform, float max_dist, float ray_radius, struct Mesh *mesh_dst, struct MVert *verts_dst, int numverts_dst, struct MEdge *edges_dst, int numedges_dst, struct MLoop *loops_dst, int numloops_dst, struct MPoly *polys_dst, int numpolys_dst, struct CustomData *ldata_dst, bool use_split_nors_dst, float split_angle_dst, bool dirty_nors_dst, struct Mesh *me_src, MeshRemapIslandsCalc gen_islands_src, float islands_precision_src, struct MeshPairRemap *r_map)
@ MREMAP_MODE_TOPOLOGY
@ MREMAP_USE_POLY
@ MREMAP_USE_EDGE
struct Mesh * mesh_get_eval_final(struct Depsgraph *depsgraph, const struct Scene *scene, struct Object *ob, const struct CustomData_MeshMasks *dataMask)
void BKE_mesh_wrapper_ensure_mdata(struct Mesh *me)
Definition: mesh_wrapper.cc:94
struct Mesh * BKE_modifier_get_evaluated_mesh_from_evaluated_object(struct Object *ob_eval)
General operations, lookup, etc. for blender objects.
Functions for dealing with objects and deform verts, used by painting and tools.
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition: report.c:83
#define BLI_assert_unreachable()
Definition: BLI_assert.h:93
#define BLI_assert(a)
Definition: BLI_assert.h:46
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:466
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:80
MINLINE float interpf(float a, float b, float t)
#define UNUSED(x)
#define ELEM(...)
#define CLOG_WARN(clg_ref,...)
Definition: CLG_log.h:189
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:35
#define CD_MASK_NORMAL
@ CD_FLAG_TEMPORARY
#define CD_MASK_MDEFORMVERT
@ CD_PROP_BYTE_COLOR
@ CD_MVERT_SKIN
@ CD_CUSTOMLOOPNORMAL
@ CD_MDEFORMVERT
@ CD_PROP_COLOR
@ CD_FREESTYLE_EDGE
@ CD_FREESTYLE_FACE
@ CD_MLOOPUV
#define CD_MASK_CUSTOMLOOPNORMAL
#define CD_MASK_MLOOPUV
@ ME_AUTOSMOOTH
@ ME_CDFLAG_EDGE_CREASE
@ ME_CDFLAG_VERT_BWEIGHT
@ ME_CDFLAG_EDGE_BWEIGHT
@ FREESTYLE_EDGE_MARK
@ ME_SMOOTH
@ FREESTYLE_FACE_MARK
@ ME_SEAM
@ ME_SHARP
Object is a sort of wrapper for general info.
@ OB_MESH
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position CLAMP
void customdata_data_transfer_interp_normal_normals(const CustomDataTransferLayerMap *laymap, void *data_dst, const void **sources, const float *weights, const int count, const float mix_factor)
Definition: customdata.cc:4952
void data_transfer_layersmapping_add_item(ListBase *r_map, const int cddata_type, const int mix_mode, const float mix_factor, const float *mix_weights, const void *data_src, void *data_dst, const int data_src_n, const int data_dst_n, const size_t elem_size, const size_t data_size, const size_t data_offset, const uint64_t data_flag, cd_datatransfer_interp interp, void *interp_data)
static MeshRemapIslandsCalc data_transfer_get_loop_islands_generator(const int cddata_type)
static bool data_transfer_layersmapping_generate(ListBase *r_map, Object *ob_src, Object *ob_dst, Mesh *me_src, Mesh *me_dst, const int elem_type, int cddata_type, int mix_mode, float mix_factor, const float *mix_weights, const int num_elem_dst, const bool use_create, const bool use_delete, const int fromlayers, const int tolayers, SpaceTransform *space_transform)
int BKE_object_data_transfer_dttype_to_srcdst_index(const int dtdata_type)
int BKE_object_data_transfer_get_dttypes_item_types(const int dtdata_types)
static bool data_transfer_layersmapping_cdlayers(ListBase *r_map, const int cddata_type, const int mix_mode, const float mix_factor, const float *mix_weights, const int num_elem_dst, const bool use_create, const bool use_delete, CustomData *cd_src, CustomData *cd_dst, const bool use_dupref_dst, const int fromlayers, const int tolayers, cd_datatransfer_interp interp, void *interp_data)
static bool data_transfer_layersmapping_cdlayers_multisrc_to_dst(ListBase *r_map, const int cddata_type, const int mix_mode, const float mix_factor, const float *mix_weights, const int num_elem_dst, const bool use_create, const bool use_delete, CustomData *cd_src, CustomData *cd_dst, const bool use_dupref_dst, const int tolayers, const bool *use_layers_src, const int num_layers_src, cd_datatransfer_interp interp, void *interp_data)
bool BKE_object_data_transfer_get_dttypes_capacity(const int dtdata_types, bool *r_advanced_mixing, bool *r_threshold)
Definition: data_transfer.c:80
#define DATAMAX
#define EDATA
static void data_transfer_dtdata_type_postprocess(Object *UNUSED(ob_src), Object *UNUSED(ob_dst), Mesh *UNUSED(me_src), Mesh *me_dst, const int dtdata_type, const bool changed)
bool BKE_object_data_transfer_mesh(struct Depsgraph *depsgraph, Scene *scene, Object *ob_src, 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, 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, ReportList *reports)
int BKE_object_data_transfer_dttype_to_cdtype(const int dtdata_type)
float data_transfer_interp_float_do(const int mix_mode, const float val_dst, const float val_src, const float mix_factor)
#define VDATA
void BKE_object_data_transfer_dttypes_to_cdmask(const int dtdata_types, CustomData_MeshMasks *r_data_masks)
Definition: data_transfer.c:40
static CLG_LogRef LOG
Definition: data_transfer.c:38
static void data_transfer_dtdata_type_preprocess(Mesh *me_src, Mesh *me_dst, const int dtdata_type, const bool dirty_nors_dst)
#define LDATA
static void data_transfer_layersmapping_add_item_cd(ListBase *r_map, const int cddata_type, const int mix_mode, const float mix_factor, const float *mix_weights, const void *data_src, void *data_dst, cd_datatransfer_interp interp, void *interp_data)
static void data_transfer_interp_char(const CustomDataTransferLayerMap *laymap, void *dest, const void **sources, const float *weights, const int count, const float mix_factor)
void BKE_object_data_transfer_layout(struct Depsgraph *depsgraph, Scene *scene, Object *ob_src, 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 PDATA
bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph, Scene *scene, Object *ob_src, Object *ob_dst, Mesh *me_dst, const int data_types, bool use_create, const int map_vert_mode, const int map_edge_mode, const int map_loop_mode, const int map_poly_mode, 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, ReportList *reports)
bool data_transfer_layersmapping_vgroups(struct ListBase *r_map, int mix_mode, float mix_factor, const float *mix_weights, int num_elem_dst, bool use_create, bool use_delete, struct Object *ob_src, struct Object *ob_dst, struct CustomData *cd_src, struct CustomData *cd_dst, bool use_dupref_dst, int fromlayers, int tolayers)
Definition: deform.c:1335
Scene scene
const Depsgraph * depsgraph
SyclQueue void void size_t num_bytes void
SyclQueue void * dest
int count
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
ccl_device_inline float2 interp(const float2 &a, const float2 &b, float t)
Definition: math_float2.h:232
return ret
unsigned __int64 uint64_t
Definition: stdint.h:90
struct CustomDataTransferLayerMap * next
cd_datatransfer_interp interp
void * first
Definition: DNA_listBase.h:31
struct MEdge * medge
float smoothresh
CustomData vdata
struct MVert * mvert
uint16_t flag
struct MDeformVert * dvert
int totedge
char cd_flag
int totvert
struct MLoop * mloop
CustomData pdata
int totpoly
CustomData edata
int totloop
struct MPoly * mpoly
CustomData ldata
CustomData_MeshMasks last_data_mask
Object_Runtime runtime
void * data