Blender V5.0
data_transfer.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2014 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include "MEM_guardedalloc.h"
10
12#include "DNA_mesh_types.h"
13#include "DNA_meshdata_types.h"
14#include "DNA_object_types.h"
15
16#include "BLI_listbase.h"
17#include "BLI_math_base.h"
18#include "BLI_math_matrix.h"
19#include "BLI_string.h"
20#include "BLI_utildefines.h"
21
22#include "BKE_attribute.hh"
23#include "BKE_customdata.hh"
24#include "BKE_data_transfer.h"
25#include "BKE_deform.hh"
26#include "BKE_mesh.hh"
27#include "BKE_mesh_mapping.hh"
28#include "BKE_mesh_remap.hh"
29#include "BKE_mesh_runtime.hh"
30#include "BKE_mesh_wrapper.hh"
31#include "BKE_modifier.hh"
32#include "BKE_object.hh"
33#include "BKE_report.hh"
34
36
38
40
42 CustomData_MeshMasks *r_data_masks)
43{
44 for (int i = 0; i < DT_TYPE_MAX; i++) {
45 const int dtdata_type = 1 << i;
46 int cddata_type;
47
48 if (!(dtdata_types & dtdata_type)) {
49 continue;
50 }
51
52 cddata_type = BKE_object_data_transfer_dttype_to_cdtype(dtdata_type);
53 if (!(cddata_type & CD_FAKE)) {
54 if (DT_DATATYPE_IS_VERT(dtdata_type)) {
55 r_data_masks->vmask |= 1LL << cddata_type;
56 }
57 else if (DT_DATATYPE_IS_EDGE(dtdata_type)) {
58 r_data_masks->emask |= 1LL << cddata_type;
59 }
60 else if (DT_DATATYPE_IS_LOOP(dtdata_type)) {
61 r_data_masks->lmask |= 1LL << cddata_type;
62 }
63 else if (DT_DATATYPE_IS_FACE(dtdata_type)) {
64 r_data_masks->pmask |= 1LL << cddata_type;
65 }
66 }
67 else if (cddata_type == CD_FAKE_MDEFORMVERT) {
68 r_data_masks->vmask |= CD_MASK_MDEFORMVERT; /* Exception for vgroups :/ */
69 }
70 else if (cddata_type == CD_FAKE_UV) {
71 r_data_masks->lmask |= CD_MASK_PROP_FLOAT2;
72 }
73 }
74}
75
77 bool *r_advanced_mixing,
78 bool *r_threshold)
79{
80 bool ret = false;
81
82 *r_advanced_mixing = false;
83 *r_threshold = false;
84
85 for (int i = 0; (i < DT_TYPE_MAX) && !(ret && *r_advanced_mixing && *r_threshold); i++) {
86 const int dtdata_type = 1 << i;
87
88 if (!(dtdata_types & dtdata_type)) {
89 continue;
90 }
91
92 switch (dtdata_type) {
93 /* Vertex data */
95 *r_advanced_mixing = true;
96 *r_threshold = true;
97 ret = true;
98 break;
99 case DT_TYPE_SKIN:
100 *r_threshold = true;
101 ret = true;
102 break;
104 ret = true;
105 break;
106 /* Edge data */
108 *r_threshold = true;
109 ret = true;
110 break;
111 case DT_TYPE_SEAM:
112 *r_threshold = true;
113 ret = true;
114 break;
115 case DT_TYPE_CREASE:
116 ret = true;
117 break;
119 ret = true;
120 break;
122 *r_threshold = true;
123 ret = true;
124 break;
125 /* Loop/Poly data */
126 case DT_TYPE_UV:
127 ret = true;
128 break;
133 *r_advanced_mixing = true;
134 *r_threshold = true;
135 ret = true;
136 break;
137 case DT_TYPE_LNOR:
138 *r_advanced_mixing = true;
139 ret = true;
140 break;
142 *r_threshold = true;
143 ret = true;
144 break;
146 *r_threshold = true;
147 ret = true;
148 break;
149 }
150 }
151
152 return ret;
153}
154
156{
157 int i, ret = 0;
158
159 for (i = 0; (i < DT_TYPE_MAX) && (ret ^ (ME_VERT | ME_EDGE | ME_LOOP | ME_POLY)); i++) {
160 const int dtdata_type = 1 << i;
161
162 if (!(dtdata_types & dtdata_type)) {
163 continue;
164 }
165
166 if (DT_DATATYPE_IS_VERT(dtdata_type)) {
167 ret |= ME_VERT;
168 }
169 if (DT_DATATYPE_IS_EDGE(dtdata_type)) {
170 ret |= ME_EDGE;
171 }
172 if (DT_DATATYPE_IS_LOOP(dtdata_type)) {
173 ret |= ME_LOOP;
174 }
175 if (DT_DATATYPE_IS_FACE(dtdata_type)) {
176 ret |= ME_POLY;
177 }
178 }
179
180 return ret;
181}
182
184{
185 switch (dtdata_type) {
187 return CD_FAKE_MDEFORMVERT;
188 case DT_TYPE_SKIN:
189 return CD_MVERT_SKIN;
191 return CD_FAKE_BWEIGHT;
192
194 return CD_FAKE_SHARP;
195 case DT_TYPE_SEAM:
196 return CD_FAKE_SEAM;
197 case DT_TYPE_CREASE:
198 return CD_FAKE_CREASE;
200 return CD_FAKE_BWEIGHT;
203
204 case DT_TYPE_UV:
205 return CD_FAKE_UV;
207 return CD_FAKE_SHARP;
210 case DT_TYPE_LNOR:
211 return CD_FAKE_LNOR;
214 return CD_PROP_BYTE_COLOR;
217 return CD_PROP_COLOR;
218 default:
220 }
221 return 0; /* Should never be reached! */
222}
223
243
244/* ********** */
245
252 Mesh *mesh_dst, const Mesh *mesh_src, const AttrDomainMask mask_domain, const int data_type)
253{
254 if (mesh_dst->active_color_attribute) {
255 return;
256 }
257
258 const AttributeOwner owner_src = AttributeOwner::from_id(const_cast<ID *>(&mesh_src->id));
259 AttributeOwner owner_dst = AttributeOwner::from_id(&mesh_dst->id);
260
261 const StringRef active_color_src =
262 BKE_id_attributes_active_color_name(&mesh_src->id).value_or("");
263
264 if ((data_type == CD_PROP_COLOR) &&
266 owner_src, active_color_src, CD_MASK_PROP_COLOR, ATTR_DOMAIN_MASK_COLOR))
267 {
268 return;
269 }
270 if ((data_type == CD_PROP_BYTE_COLOR) &&
272 owner_src, active_color_src, CD_MASK_PROP_BYTE_COLOR, ATTR_DOMAIN_MASK_COLOR))
273 {
274 return;
275 }
276
277 if ((data_type == CD_PROP_COLOR) &&
279 owner_dst, active_color_src, CD_MASK_PROP_COLOR, ATTR_DOMAIN_MASK_COLOR))
280 {
281 mesh_dst->active_color_attribute = BLI_strdupn(active_color_src.data(),
282 active_color_src.size());
283 }
284 else if ((data_type == CD_PROP_BYTE_COLOR) &&
286 owner_dst, active_color_src, CD_MASK_PROP_BYTE_COLOR, ATTR_DOMAIN_MASK_COLOR))
287 {
288 mesh_dst->active_color_attribute = BLI_strdupn(active_color_src.data(),
289 active_color_src.size());
290 }
291 else {
292 CustomDataLayer *first_color_layer = BKE_attribute_from_index(
293 owner_dst, 0, mask_domain, CD_MASK_COLOR_ALL);
294 if (first_color_layer != nullptr) {
295 mesh_dst->active_color_attribute = BLI_strdup(first_color_layer->name);
296 }
297 }
298}
299
306 Mesh *mesh_dst, const Mesh *mesh_src, const AttrDomainMask mask_domain, const int data_type)
307{
308 if (mesh_dst->default_color_attribute) {
309 return;
310 }
311
312 const AttributeOwner owner_src = AttributeOwner::from_id(const_cast<ID *>(&mesh_src->id));
313 AttributeOwner owner_dst = AttributeOwner::from_id(&mesh_dst->id);
314
315 const StringRef default_color_src =
316 BKE_id_attributes_default_color_name(&mesh_src->id).value_or("");
317
318 if ((data_type == CD_PROP_COLOR) &&
320 owner_src, default_color_src, CD_MASK_PROP_COLOR, ATTR_DOMAIN_MASK_COLOR))
321 {
322 return;
323 }
324 if ((data_type == CD_PROP_BYTE_COLOR) &&
326 owner_src, default_color_src, CD_MASK_PROP_BYTE_COLOR, ATTR_DOMAIN_MASK_COLOR))
327 {
328 return;
329 }
330
331 if ((data_type == CD_PROP_COLOR) &&
333 owner_dst, default_color_src, CD_MASK_PROP_COLOR, ATTR_DOMAIN_MASK_COLOR))
334 {
335 mesh_dst->default_color_attribute = BLI_strdupn(default_color_src.data(),
336 default_color_src.size());
337 }
338 else if ((data_type == CD_PROP_BYTE_COLOR) &&
340 owner_dst, default_color_src, CD_MASK_PROP_BYTE_COLOR, ATTR_DOMAIN_MASK_COLOR))
341 {
342 mesh_dst->default_color_attribute = BLI_strdupn(default_color_src.data(),
343 default_color_src.size());
344 }
345 else {
346 CustomDataLayer *first_color_layer = BKE_attribute_from_index(
347 owner_dst, 0, mask_domain, CD_MASK_COLOR_ALL);
348 if (first_color_layer != nullptr) {
349 mesh_dst->default_color_attribute = BLI_strdup(first_color_layer->name);
350 }
351 }
352}
353
354/* ********** */
355
357 const int dtdata_type,
358 const bool changed)
359{
360 using namespace blender;
361 if (dtdata_type == DT_TYPE_LNOR) {
362 if (!changed) {
363 return;
364 }
365 /* Bake edited destination loop normals into custom normals again. */
366 CustomData *ldata_dst = &me_dst->corner_data;
367
368 blender::float3 *loop_nors_dst = static_cast<blender::float3 *>(
370
371 bke::MutableAttributeAccessor attributes = me_dst->attributes_for_write();
373 "custom_normal", bke::AttrDomain::Corner);
374 if (!custom_nors_dst) {
375 return;
376 }
378 "sharp_edge", bke::AttrDomain::Edge);
379 const VArraySpan sharp_faces = *attributes.lookup<bool>("sharp_face", bke::AttrDomain::Face);
380 /* Note loop_nors_dst contains our custom normals as transferred from source... */
381 blender::bke::mesh::normals_corner_custom_set(me_dst->vert_positions(),
382 me_dst->faces(),
383 me_dst->corner_verts(),
384 me_dst->corner_edges(),
385 me_dst->vert_to_face_map(),
386 me_dst->vert_normals(),
387 me_dst->face_normals_true(),
388 sharp_faces,
389 sharp_edges.span,
390 {loop_nors_dst, me_dst->corners_num},
391 custom_nors_dst.span);
392 custom_nors_dst.finish();
393 sharp_edges.finish();
395 }
396}
397
398/* ********** */
399
401{
402 switch (cddata_type) {
403 case CD_FAKE_UV:
405 default:
406 break;
407 }
408 return nullptr;
409}
410
411float data_transfer_interp_float_do(const int mix_mode,
412 const float val_dst,
413 const float val_src,
414 const float mix_factor)
415{
416 float val_ret;
417
418 if ((mix_mode == CDT_MIX_REPLACE_ABOVE_THRESHOLD && (val_dst < mix_factor)) ||
419 (mix_mode == CDT_MIX_REPLACE_BELOW_THRESHOLD && (val_dst > mix_factor)))
420 {
421 return val_dst; /* Do not affect destination. */
422 }
423
424 switch (mix_mode) {
427 return val_src;
428 case CDT_MIX_MIX:
429 val_ret = (val_dst + val_src) * 0.5f;
430 break;
431 case CDT_MIX_ADD:
432 val_ret = val_dst + val_src;
433 break;
434 case CDT_MIX_SUB:
435 val_ret = val_dst - val_src;
436 break;
437 case CDT_MIX_MUL:
438 val_ret = val_dst * val_src;
439 break;
440 case CDT_MIX_TRANSFER:
441 default:
442 val_ret = val_src;
443 break;
444 }
445 return interpf(val_ret, val_dst, mix_factor);
446}
447
448/* Helpers to match sources and destinations data layers
449 * (also handles 'conversions' in CD_FAKE cases). */
450
452 const int cddata_type,
453 const int mix_mode,
454 const float mix_factor,
455 const float *mix_weights,
456 const void *data_src,
457 void *data_dst,
458 const int data_src_n,
459 const int data_dst_n,
460 const size_t elem_size,
461 const size_t data_size,
462 const size_t data_offset,
463 const uint64_t data_flag,
465 void *interp_data)
466{
468
469 BLI_assert(data_dst != nullptr);
470
471 item->data_type = eCustomDataType(cddata_type);
472 item->mix_mode = mix_mode;
473 item->mix_factor = mix_factor;
474 item->mix_weights = mix_weights;
475
476 item->data_src = data_src;
477 item->data_dst = data_dst;
478 item->data_src_n = data_src_n;
479 item->data_dst_n = data_dst_n;
480 item->elem_size = elem_size;
481
482 item->data_size = data_size;
483 item->data_offset = data_offset;
484 item->data_flag = data_flag;
485
486 item->interp = interp;
487 item->interp_data = interp_data;
488
489 BLI_addtail(r_map, item);
490}
491
493 const int cddata_type,
494 const int mix_mode,
495 const float mix_factor,
496 const float *mix_weights,
497 const void *data_src,
498 void *data_dst,
500 void *interp_data)
501{
503 cddata_type,
504 mix_mode,
505 mix_factor,
506 mix_weights,
507 data_src,
508 data_dst,
509 0,
510 0,
511 0,
512 0,
513 0,
514 0,
515 interp,
516 interp_data);
517}
518
527 const eCustomDataType cddata_type,
528 const int mix_mode,
529 const float mix_factor,
530 const float *mix_weights,
531 const int num_elem_dst,
532 const bool use_create,
533 const bool use_delete,
534 const CustomData &cd_src,
535 CustomData &cd_dst,
536 const int tolayers,
537 const bool *use_layers_src,
538 const int num_layers_src)
539{
540 const void *data_src;
541 void *data_dst = nullptr;
542 int idx_src = num_layers_src;
543 int idx_dst, tot_dst = CustomData_number_of_layers(&cd_dst, cddata_type);
544 bool *data_dst_to_delete = nullptr;
545
546 if (!use_layers_src) {
547 /* No source at all, we can only delete all destination if requested. */
548 if (use_delete) {
549 idx_dst = tot_dst;
550 while (idx_dst--) {
551 CustomData_free_layer(&cd_dst, cddata_type, idx_dst);
552 }
553 }
554 return true;
555 }
556
557 switch (tolayers) {
559 idx_dst = tot_dst;
560
561 /* Find last source actually used! */
562 while (idx_src-- && !use_layers_src[idx_src]) {
563 /* pass */
564 }
565 idx_src++;
566
567 if (idx_dst < idx_src) {
568 if (use_create) {
569 /* Create as much data layers as necessary! */
570 for (; idx_dst < idx_src; idx_dst++) {
572 &cd_dst, eCustomDataType(cddata_type), CD_SET_DEFAULT, num_elem_dst);
573 }
574 }
575 else {
576 /* Otherwise, just try to map what we can with existing dst data layers. */
577 idx_src = idx_dst;
578 }
579 }
580 else if (use_delete && idx_dst > idx_src) {
581 while (idx_dst-- > idx_src) {
582 CustomData_free_layer(&cd_dst, cddata_type, idx_dst);
583 }
584 }
585 if (r_map) {
586 while (idx_src--) {
587 if (!use_layers_src[idx_src]) {
588 continue;
589 }
590 data_src = CustomData_get_layer_n(&cd_src, cddata_type, idx_src);
591 data_dst = CustomData_get_layer_n_for_write(&cd_dst, cddata_type, idx_src, num_elem_dst);
593 cddata_type,
594 mix_mode,
595 mix_factor,
596 mix_weights,
597 data_src,
598 data_dst,
599 nullptr,
600 nullptr);
601 }
602 }
603 break;
605 if (use_delete) {
606 if (tot_dst) {
607 data_dst_to_delete = MEM_malloc_arrayN<bool>(size_t(tot_dst), __func__);
608 memset(data_dst_to_delete, true, sizeof(*data_dst_to_delete) * size_t(tot_dst));
609 }
610 }
611
612 while (idx_src--) {
613 const char *name;
614
615 if (!use_layers_src[idx_src]) {
616 continue;
617 }
618
619 name = CustomData_get_layer_name(&cd_src, cddata_type, idx_src);
620 data_src = CustomData_get_layer_n(&cd_src, cddata_type, idx_src);
621 idx_dst = CustomData_get_named_layer(&cd_dst, cddata_type, name);
622 if (idx_dst == -1) {
623 if (use_create) {
625 &cd_dst, eCustomDataType(cddata_type), CD_SET_DEFAULT, num_elem_dst, name);
626 idx_dst = CustomData_get_named_layer(&cd_dst, cddata_type, name);
627 }
628 else {
629 /* If we are not allowed to create missing dst data layers,
630 * just skip matching src one. */
631 continue;
632 }
633 }
634 else if (data_dst_to_delete) {
635 data_dst_to_delete[idx_dst] = false;
636 }
637 if (r_map) {
638 data_dst = CustomData_get_layer_n_for_write(&cd_dst, cddata_type, idx_dst, num_elem_dst);
640 cddata_type,
641 mix_mode,
642 mix_factor,
643 mix_weights,
644 data_src,
645 data_dst,
646 nullptr,
647 nullptr);
648 }
649 }
650
651 if (data_dst_to_delete) {
652 /* NOTE:
653 * This won't affect newly created layers, if any, since tot_dst has not been updated!
654 * Also, looping backward ensures us we do not suffer
655 * from index shifting when deleting a layer. */
656 for (idx_dst = tot_dst; idx_dst--;) {
657 if (data_dst_to_delete[idx_dst]) {
658 CustomData_free_layer(&cd_dst, cddata_type, idx_dst);
659 }
660 }
661
662 MEM_freeN(data_dst_to_delete);
663 }
664 break;
665 default:
666 return false;
667 }
668
669 return true;
670}
671
673 const eCustomDataType cddata_type,
674 const int mix_mode,
675 const float mix_factor,
676 const float *mix_weights,
677 const int num_elem_dst,
678 const bool use_create,
679 const bool use_delete,
680 const CustomData &cd_src,
681 CustomData &cd_dst,
682 const int fromlayers,
683 const int tolayers)
684{
685 void *data_dst = nullptr;
686
687 if (CustomData_layertype_is_singleton(cddata_type)) {
688 const void *data_src = CustomData_get_layer(&cd_src, cddata_type);
689 if (!data_src) {
690 if (use_delete) {
691 CustomData_free_layer(&cd_dst, cddata_type, 0);
692 }
693 return true;
694 }
695
696 data_dst = CustomData_get_layer_for_write(&cd_dst, cddata_type, num_elem_dst);
697 if (!data_dst) {
698 if (!use_create) {
699 return true;
700 }
701 data_dst = CustomData_add_layer(
702 &cd_dst, eCustomDataType(cddata_type), CD_SET_DEFAULT, num_elem_dst);
703 }
704
705 if (r_map) {
707 cddata_type,
708 mix_mode,
709 mix_factor,
710 mix_weights,
711 data_src,
712 data_dst,
713 nullptr,
714 nullptr);
715 }
716 }
717 else if (fromlayers == DT_LAYERS_ACTIVE_SRC || fromlayers >= 0) {
718 /* NOTE: use_delete has not much meaning in this case, ignored. */
719
720 int idx_src;
721 if (fromlayers >= 0) { /* Real-layer index */
722 idx_src = fromlayers;
723 }
724 else {
725 idx_src = CustomData_get_active_layer(&cd_src, cddata_type);
726 if (idx_src == -1) {
727 return true;
728 }
729 }
730 const void *data_src = CustomData_get_layer_n(&cd_src, cddata_type, idx_src);
731 if (!data_src) {
732 return true;
733 }
734
735 int idx_dst;
736 if (tolayers >= 0) { /* Real-layer index */
737 idx_dst = tolayers;
738 data_dst = CustomData_get_layer_n_for_write(&cd_dst, cddata_type, idx_dst, num_elem_dst);
739 }
740 else if (tolayers == DT_LAYERS_ACTIVE_DST) {
741 idx_dst = CustomData_get_active_layer(&cd_dst, cddata_type);
742 if (idx_dst == -1) {
743 if (!use_create) {
744 return true;
745 }
746 data_dst = CustomData_add_layer(
747 &cd_dst, eCustomDataType(cddata_type), CD_SET_DEFAULT, num_elem_dst);
748 }
749 else {
750 data_dst = CustomData_get_layer_n_for_write(&cd_dst, cddata_type, idx_dst, num_elem_dst);
751 }
752 }
753 else if (tolayers == DT_LAYERS_INDEX_DST) {
754 int num = CustomData_number_of_layers(&cd_dst, cddata_type);
755 idx_dst = idx_src;
756 if (num <= idx_dst) {
757 if (!use_create) {
758 return true;
759 }
760 /* Create as much data layers as necessary! */
761 for (; num <= idx_dst; num++) {
763 &cd_dst, eCustomDataType(cddata_type), CD_SET_DEFAULT, num_elem_dst);
764 }
765 }
766 data_dst = CustomData_get_layer_n_for_write(&cd_dst, cddata_type, idx_dst, num_elem_dst);
767 }
768 else if (tolayers == DT_LAYERS_NAME_DST) {
769 const char *name = CustomData_get_layer_name(&cd_src, cddata_type, idx_src);
770 idx_dst = CustomData_get_named_layer(&cd_dst, cddata_type, name);
771 if (idx_dst == -1) {
772 if (!use_create) {
773 return true;
774 }
776 &cd_dst, eCustomDataType(cddata_type), CD_SET_DEFAULT, num_elem_dst, name);
777 idx_dst = CustomData_get_named_layer(&cd_dst, cddata_type, name);
778 }
779 data_dst = CustomData_get_layer_n_for_write(&cd_dst, cddata_type, idx_dst, num_elem_dst);
780 }
781 else {
782 return false;
783 }
784
785 if (!data_dst) {
786 return false;
787 }
788
789 if (r_map) {
791 cddata_type,
792 mix_mode,
793 mix_factor,
794 mix_weights,
795 data_src,
796 data_dst,
797 nullptr,
798 nullptr);
799 }
800 }
801 else if (fromlayers == DT_LAYERS_ALL_SRC) {
802 int num_src = CustomData_number_of_layers(&cd_src, eCustomDataType(cddata_type));
803 bool *use_layers_src = num_src ? MEM_malloc_arrayN<bool>(size_t(num_src), __func__) : nullptr;
804 bool ret;
805
806 if (use_layers_src) {
807 memset(use_layers_src, true, sizeof(*use_layers_src) * num_src);
808 }
809
811 cddata_type,
812 mix_mode,
813 mix_factor,
814 mix_weights,
815 num_elem_dst,
816 use_create,
817 use_delete,
818 cd_src,
819 cd_dst,
820 tolayers,
821 use_layers_src,
822 num_src);
823
824 if (use_layers_src) {
825 MEM_freeN(use_layers_src);
826 }
827 return ret;
828 }
829 else {
830 return false;
831 }
832
833 return true;
834}
835
837 Object *ob_src,
838 Object *ob_dst,
839 const Mesh *me_src,
840 Mesh *me_dst,
841 const int elem_type,
842 int cddata_type,
843 int mix_mode,
844 float mix_factor,
845 const float *mix_weights,
846 const int num_elem_dst,
847 const bool use_create,
848 const bool use_delete,
849 const int fromlayers,
850 const int tolayers,
851 SpaceTransform *space_transform)
852{
853 using namespace blender;
854
855 if (elem_type == ME_VERT) {
856 if (!(cddata_type & CD_FAKE)) {
858 eCustomDataType(cddata_type),
859 mix_mode,
860 mix_factor,
861 mix_weights,
862 num_elem_dst,
863 use_create,
864 use_delete,
865 me_src->vert_data,
866 me_dst->vert_data,
867 fromlayers,
868 tolayers))
869 {
870 /* We handle specific source selection cases here. */
871 return false;
872 }
873 return true;
874 }
875 if (cddata_type == CD_FAKE_MDEFORMVERT) {
877 mix_mode,
878 mix_factor,
879 mix_weights,
880 use_create,
881 use_delete,
882 ob_src,
883 ob_dst,
884 *me_src,
885 *me_dst,
886 me_dst != ob_dst->data,
887 fromlayers,
888 tolayers);
889 }
890 if (r_map && cddata_type == CD_FAKE_BWEIGHT) {
891 if (!CustomData_get_layer_named(&me_dst->vert_data, CD_PROP_FLOAT, "bevel_weight_vert")) {
895 me_dst->verts_num,
896 "bevel_weight_vert");
897 }
899 r_map,
901 mix_mode,
902 mix_factor,
903 mix_weights,
904 CustomData_get_layer_named(&me_src->vert_data, CD_PROP_FLOAT, "bevel_weight_vert"),
906 &me_dst->vert_data, CD_PROP_FLOAT, "bevel_weight_vert", me_dst->verts_num),
907 nullptr,
908 nullptr);
909 return true;
910 }
911 }
912 else if (elem_type == ME_EDGE) {
913 if (r_map && cddata_type == CD_FAKE_SEAM) {
914 if (!CustomData_has_layer_named(&me_dst->edge_data, CD_PROP_BOOL, "uv_seam")) {
916 &me_dst->edge_data, CD_PROP_BOOL, CD_SET_DEFAULT, me_dst->edges_num, "uv_seam");
917 }
919 r_map,
921 mix_mode,
922 mix_factor,
923 mix_weights,
926 &me_dst->edge_data, CD_PROP_BOOL, "uv_seam", me_dst->edges_num),
927 nullptr,
928 nullptr);
929 return true;
930 }
931 if (r_map && cddata_type == CD_FAKE_SHARP) {
932 if (!CustomData_has_layer_named(&me_dst->edge_data, CD_PROP_BOOL, "sharp_edge")) {
934 &me_dst->edge_data, CD_PROP_BOOL, CD_SET_DEFAULT, me_dst->edges_num, "sharp_edge");
935 }
937 r_map,
939 mix_mode,
940 mix_factor,
941 mix_weights,
942 CustomData_get_layer_named(&me_src->edge_data, CD_PROP_BOOL, "sharp_edge"),
944 &me_dst->edge_data, CD_PROP_BOOL, "sharp_edge", me_dst->edges_num),
945 nullptr,
946 nullptr);
947 return true;
948 }
949 if (r_map && cddata_type == CD_FAKE_BWEIGHT) {
950 if (!CustomData_get_layer_named(&me_dst->edge_data, CD_PROP_FLOAT, "bevel_weight_edge")) {
954 me_dst->edges_num,
955 "bevel_weight_edge");
956 }
958 r_map,
960 mix_mode,
961 mix_factor,
962 mix_weights,
963 CustomData_get_layer_named(&me_src->edge_data, CD_PROP_FLOAT, "bevel_weight_edge"),
965 &me_dst->edge_data, CD_PROP_FLOAT, "bevel_weight_edge", me_dst->edges_num),
966 nullptr,
967 nullptr);
968 return true;
969 }
970 if (r_map && cddata_type == CD_FAKE_CREASE) {
971 if (!CustomData_get_layer_named(&me_dst->edge_data, CD_PROP_FLOAT, "crease_edge")) {
973 &me_dst->edge_data, CD_PROP_FLOAT, CD_SET_DEFAULT, me_dst->edges_num, "crease_edge");
974 }
976 r_map,
978 mix_mode,
979 mix_factor,
980 mix_weights,
981 CustomData_get_layer_named(&me_src->edge_data, CD_PROP_FLOAT, "crease_edge"),
983 &me_dst->edge_data, CD_PROP_FLOAT, "crease_edge", me_dst->edges_num),
984 nullptr,
985 nullptr);
986 return true;
987 }
988 if (r_map && cddata_type == CD_FAKE_FREESTYLE_EDGE) {
989 if (!CustomData_get_layer_named(&me_dst->edge_data, CD_PROP_BOOL, "freestyle_edge")) {
991 &me_dst->edge_data, CD_PROP_BOOL, CD_SET_DEFAULT, me_dst->edges_num, "freestyle_edge");
992 }
994 r_map,
996 mix_mode,
997 mix_factor,
998 mix_weights,
999 CustomData_get_layer_named(&me_src->edge_data, CD_PROP_BOOL, "freestyle_edge"),
1001 &me_dst->edge_data, CD_PROP_BOOL, "freestyle_edge", me_dst->edges_num),
1002 nullptr,
1003 nullptr);
1004 return true;
1005 }
1006
1007 return false;
1008 }
1009 else if (elem_type == ME_LOOP) {
1010 if (cddata_type == CD_FAKE_UV) {
1011 cddata_type = CD_PROP_FLOAT2;
1012 }
1013 else if (cddata_type == CD_FAKE_LNOR) {
1014 if (r_map) {
1015 /* Use #CD_NORMAL as a temporary storage for custom normals in 3D vector form.
1016 * A post-process step will convert this layer to "custom_normal". */
1017 float3 *dst_data = static_cast<float3 *>(
1019 if (!dst_data) {
1020 dst_data = static_cast<float3 *>(CustomData_add_layer(
1021 &me_dst->corner_data, CD_NORMAL, CD_SET_DEFAULT, me_dst->corners_num));
1022 }
1023 if (mix_factor != 1.0f || mix_weights) {
1024 MutableSpan(dst_data, me_dst->corners_num).copy_from(me_dst->corner_normals());
1025 }
1026 /* Post-process will convert it back to "custom_normal". */
1028 CD_NORMAL,
1029 mix_mode,
1030 mix_factor,
1031 mix_weights,
1032 me_src->corner_normals().data(),
1033 dst_data,
1035 space_transform);
1036 }
1037 return true;
1038 }
1039
1040 if (!(cddata_type & CD_FAKE)) {
1042 eCustomDataType(cddata_type),
1043 mix_mode,
1044 mix_factor,
1045 mix_weights,
1046 num_elem_dst,
1047 use_create,
1048 use_delete,
1049 me_src->corner_data,
1050 me_dst->corner_data,
1051 fromlayers,
1052 tolayers))
1053 {
1054 /* We handle specific source selection cases here. */
1055 return false;
1056 }
1057 return true;
1058 }
1059
1060 return false;
1061 }
1062 else if (elem_type == ME_POLY) {
1063 if (r_map && cddata_type == CD_FAKE_SHARP) {
1064 if (!CustomData_has_layer_named(&me_dst->face_data, CD_PROP_BOOL, "sharp_face")) {
1066 &me_dst->face_data, CD_PROP_BOOL, CD_SET_DEFAULT, me_dst->faces_num, "sharp_face");
1067 }
1069 r_map,
1071 mix_mode,
1072 mix_factor,
1073 mix_weights,
1074 CustomData_get_layer_named(&me_src->face_data, CD_PROP_BOOL, "sharp_face"),
1076 &me_dst->face_data, CD_PROP_BOOL, "sharp_face", num_elem_dst),
1077 nullptr,
1078 nullptr);
1079 return true;
1080 }
1081 if (r_map && cddata_type == CD_FAKE_FREESTYLE_FACE) {
1082 if (!CustomData_has_layer_named(&me_dst->face_data, CD_PROP_BOOL, "freestyle_face")) {
1084 &me_dst->face_data, CD_PROP_BOOL, CD_SET_DEFAULT, me_dst->faces_num, "freestyle_face");
1085 }
1087 r_map,
1089 mix_mode,
1090 mix_factor,
1091 mix_weights,
1092 CustomData_get_layer_named(&me_src->face_data, CD_PROP_BOOL, "freestyle_face"),
1094 &me_dst->face_data, CD_PROP_BOOL, "freestyle_face", me_dst->faces_num),
1095 nullptr,
1096 nullptr);
1097 return true;
1098 }
1099
1100 return false;
1101 }
1102
1103 return false;
1104}
1105
1107 Object *ob_src,
1108 Object *ob_dst,
1109 const int data_types,
1110 const bool use_delete,
1111 const int fromlayers_select[DT_MULTILAYER_INDEX_MAX],
1112 const int tolayers_select[DT_MULTILAYER_INDEX_MAX])
1113{
1114 Mesh *me_dst;
1115
1116 const bool use_create = true; /* We always create needed layers here. */
1117
1118 BLI_assert((ob_src != ob_dst) && (ob_src->type == OB_MESH) && (ob_dst->type == OB_MESH));
1119
1120 me_dst = static_cast<Mesh *>(ob_dst->data);
1121
1122 /* Get source evaluated mesh. */
1123 const Object *ob_src_eval = DEG_get_evaluated(depsgraph, ob_src);
1124 const Mesh *me_src = BKE_object_get_evaluated_mesh(ob_src_eval);
1125 if (!me_src) {
1126 return;
1127 }
1128
1129 /* Check all possible data types. */
1130 for (int i = 0; i < DT_TYPE_MAX; i++) {
1131 const int dtdata_type = 1 << i;
1132 int cddata_type;
1133 int fromlayers, tolayers, fromto_idx;
1134
1135 if (!(data_types & dtdata_type)) {
1136 continue;
1137 }
1138
1139 cddata_type = BKE_object_data_transfer_dttype_to_cdtype(dtdata_type);
1140
1141 fromto_idx = BKE_object_data_transfer_dttype_to_srcdst_index(dtdata_type);
1142
1143 if (fromto_idx != DT_MULTILAYER_INDEX_INVALID) {
1144 fromlayers = fromlayers_select[fromto_idx];
1145 tolayers = tolayers_select[fromto_idx];
1146 }
1147 else {
1148 fromlayers = tolayers = 0;
1149 }
1150
1151 if (DT_DATATYPE_IS_VERT(dtdata_type)) {
1152 const int num_elem_dst = me_dst->verts_num;
1153
1155 ob_src,
1156 ob_dst,
1157 me_src,
1158 me_dst,
1159 ME_VERT,
1160 cddata_type,
1161 0,
1162 0.0f,
1163 nullptr,
1164 num_elem_dst,
1165 use_create,
1166 use_delete,
1167 fromlayers,
1168 tolayers,
1169 nullptr);
1170 /* Make sure we have active/default color layers if none existed before.
1171 * Use the active/default from src (if it was transferred), otherwise the first. */
1172 if (ELEM(cddata_type, CD_PROP_COLOR, CD_PROP_BYTE_COLOR)) {
1174 me_dst, me_src, ATTR_DOMAIN_MASK_POINT, cddata_type);
1176 me_dst, me_src, ATTR_DOMAIN_MASK_POINT, cddata_type);
1177 }
1178 }
1179 if (DT_DATATYPE_IS_EDGE(dtdata_type)) {
1180 const int num_elem_dst = me_dst->edges_num;
1181
1183 ob_src,
1184 ob_dst,
1185 me_src,
1186 me_dst,
1187 ME_EDGE,
1188 cddata_type,
1189 0,
1190 0.0f,
1191 nullptr,
1192 num_elem_dst,
1193 use_create,
1194 use_delete,
1195 fromlayers,
1196 tolayers,
1197 nullptr);
1198 }
1199 if (DT_DATATYPE_IS_LOOP(dtdata_type)) {
1200 const int num_elem_dst = me_dst->corners_num;
1201
1203 ob_src,
1204 ob_dst,
1205 me_src,
1206 me_dst,
1207 ME_LOOP,
1208 cddata_type,
1209 0,
1210 0.0f,
1211 nullptr,
1212 num_elem_dst,
1213 use_create,
1214 use_delete,
1215 fromlayers,
1216 tolayers,
1217 nullptr);
1218 /* Make sure we have active/default color layers if none existed before.
1219 * Use the active/default from src (if it was transferred), otherwise the first. */
1220 if (ELEM(cddata_type, CD_PROP_COLOR, CD_PROP_BYTE_COLOR)) {
1222 me_dst, me_src, ATTR_DOMAIN_MASK_CORNER, cddata_type);
1224 me_dst, me_src, ATTR_DOMAIN_MASK_CORNER, cddata_type);
1225 }
1226 }
1227 if (DT_DATATYPE_IS_FACE(dtdata_type)) {
1228 const int num_elem_dst = me_dst->faces_num;
1229
1231 ob_src,
1232 ob_dst,
1233 me_src,
1234 me_dst,
1235 ME_POLY,
1236 cddata_type,
1237 0,
1238 0.0f,
1239 nullptr,
1240 num_elem_dst,
1241 use_create,
1242 use_delete,
1243 fromlayers,
1244 tolayers,
1245 nullptr);
1246 }
1247 }
1248}
1249
1251 Object *ob_src,
1252 Object *ob_dst,
1253 Mesh *me_dst,
1254 const int data_types,
1255 bool use_create,
1256 const int map_vert_mode,
1257 const int map_edge_mode,
1258 const int map_loop_mode,
1259 const int map_face_mode,
1260 SpaceTransform *space_transform,
1261 const bool auto_transform,
1262 const float max_distance,
1263 const float ray_radius,
1264 const float islands_handling_precision,
1265 const int fromlayers_select[DT_MULTILAYER_INDEX_MAX],
1266 const int tolayers_select[DT_MULTILAYER_INDEX_MAX],
1267 const int mix_mode,
1268 const float mix_factor,
1269 const char *vgroup_name,
1270 const bool invert_vgroup,
1271 ReportList *reports)
1272{
1273#define VDATA 0
1274#define EDATA 1
1275#define LDATA 2
1276#define PDATA 3
1277#define DATAMAX 4
1278
1279 SpaceTransform auto_space_transform;
1280
1281 const Mesh *me_src;
1282
1283 const MDeformVert *mdef = nullptr;
1284 int vg_idx = -1;
1285 float *weights[DATAMAX] = {nullptr};
1286
1287 MeshPairRemap geom_map[DATAMAX] = {{0}};
1288 bool geom_map_init[DATAMAX] = {false};
1289 ListBase lay_map = {nullptr};
1290 bool changed = false;
1291 bool is_modifier = false;
1292
1293 const bool use_delete = false; /* We never delete data layers from destination here. */
1294
1295 BLI_assert((ob_src != ob_dst) && (ob_src->type == OB_MESH) && (ob_dst->type == OB_MESH));
1296
1297 if (me_dst) {
1298 /* Never create needed custom layers on passed destination mesh
1299 * (assumed to *not* be ob_dst->data, aka modifier case). */
1300 use_create = false;
1301 is_modifier = true;
1302 }
1303 else {
1304 me_dst = static_cast<Mesh *>(ob_dst->data);
1305 }
1306
1307 if (vgroup_name) {
1308 mdef = me_dst->deform_verts().data();
1309 if (mdef) {
1310 vg_idx = BKE_id_defgroup_name_index(&me_dst->id, vgroup_name);
1311 }
1312 }
1313
1314 /* Get source evaluated mesh. */
1315 if (is_modifier) {
1317 }
1318 else {
1319 const Object *ob_eval = DEG_get_evaluated(depsgraph, ob_src);
1320 me_src = BKE_object_get_evaluated_mesh(ob_eval);
1321 }
1322 if (!me_src) {
1323 return changed;
1324 }
1325 BKE_mesh_wrapper_ensure_mdata(const_cast<Mesh *>(me_src));
1326
1327 if (auto_transform) {
1328 if (space_transform == nullptr) {
1329 space_transform = &auto_space_transform;
1330 }
1331
1332 BKE_mesh_remap_find_best_match_from_mesh(me_dst->vert_positions(), me_src, space_transform);
1333 }
1334
1335 /* Check all possible data types.
1336 * Note item mappings and destination mix weights are cached. */
1337 for (int i = 0; i < DT_TYPE_MAX; i++) {
1338 const int dtdata_type = 1 << i;
1339 int cddata_type;
1340 int fromlayers, tolayers, fromto_idx;
1341
1342 if (!(data_types & dtdata_type)) {
1343 continue;
1344 }
1345
1346 cddata_type = BKE_object_data_transfer_dttype_to_cdtype(dtdata_type);
1347
1348 fromto_idx = BKE_object_data_transfer_dttype_to_srcdst_index(dtdata_type);
1349 if (fromto_idx != DT_MULTILAYER_INDEX_INVALID) {
1350 fromlayers = fromlayers_select[fromto_idx];
1351 tolayers = tolayers_select[fromto_idx];
1352 }
1353 else {
1354 fromlayers = tolayers = 0;
1355 }
1356
1357 if (DT_DATATYPE_IS_VERT(dtdata_type)) {
1358 blender::MutableSpan<blender::float3> positions_dst = me_dst->vert_positions_for_write();
1359 const int num_verts_dst = me_dst->verts_num;
1360
1361 if (!geom_map_init[VDATA]) {
1362 const int num_verts_src = me_src->verts_num;
1363
1364 if ((map_vert_mode == MREMAP_MODE_TOPOLOGY) && (num_verts_dst != num_verts_src)) {
1365 BKE_report(reports,
1366 RPT_ERROR,
1367 "Source and destination meshes do not have the same number of vertices, "
1368 "'Topology' mapping cannot be used in this case");
1369 continue;
1370 }
1371 if ((map_vert_mode & MREMAP_USE_EDGE) && (me_src->edges_num == 0)) {
1372 BKE_report(reports,
1373 RPT_ERROR,
1374 "Source mesh does not have any edges, "
1375 "none of the 'Edge' mappings can be used in this case");
1376 continue;
1377 }
1378 if ((map_vert_mode & MREMAP_USE_POLY) && (me_src->faces_num == 0)) {
1379 BKE_report(reports,
1380 RPT_ERROR,
1381 "Source mesh does not have any faces, "
1382 "none of the 'Face' mappings can be used in this case");
1383 continue;
1384 }
1385 if (ELEM(0, num_verts_dst, num_verts_src)) {
1386 BKE_report(reports,
1387 RPT_ERROR,
1388 "Source or destination meshes do not have any vertices, cannot transfer "
1389 "vertex data");
1390 continue;
1391 }
1392
1394 space_transform,
1395 max_distance,
1396 ray_radius,
1397 positions_dst,
1398 me_src,
1399 me_dst,
1400 &geom_map[VDATA]);
1401 geom_map_init[VDATA] = true;
1402 }
1403
1404 if (mdef && vg_idx != -1 && !weights[VDATA]) {
1405 weights[VDATA] = MEM_malloc_arrayN<float>(size_t(num_verts_dst), __func__);
1407 mdef, vg_idx, num_verts_dst, invert_vgroup, weights[VDATA]);
1408 }
1409
1411 ob_src,
1412 ob_dst,
1413 me_src,
1414 me_dst,
1415 ME_VERT,
1416 cddata_type,
1417 mix_mode,
1418 mix_factor,
1419 weights[VDATA],
1420 num_verts_dst,
1421 use_create,
1422 use_delete,
1423 fromlayers,
1424 tolayers,
1425 space_transform))
1426 {
1427 changed |= (lay_map.first != nullptr);
1428
1429 LISTBASE_FOREACH (CustomDataTransferLayerMap *, lay_mapit, &lay_map) {
1430 CustomData_data_transfer(&geom_map[VDATA], lay_mapit);
1431 }
1432
1433 BLI_freelistN(&lay_map);
1434 }
1435 }
1436 if (DT_DATATYPE_IS_EDGE(dtdata_type)) {
1437 blender::MutableSpan<blender::float3> positions_dst = me_dst->vert_positions_for_write();
1438
1439 const int num_verts_dst = me_dst->verts_num;
1440 const blender::Span<blender::int2> edges_dst = me_dst->edges();
1441
1442 if (!geom_map_init[EDATA]) {
1443 const int num_edges_src = me_src->edges_num;
1444
1445 if ((map_edge_mode == MREMAP_MODE_TOPOLOGY) && (edges_dst.size() != num_edges_src)) {
1446 BKE_report(reports,
1447 RPT_ERROR,
1448 "Source and destination meshes do not have the same number of edges, "
1449 "'Topology' mapping cannot be used in this case");
1450 continue;
1451 }
1452 if ((map_edge_mode & MREMAP_USE_POLY) && (me_src->faces_num == 0)) {
1453 BKE_report(reports,
1454 RPT_ERROR,
1455 "Source mesh does not have any faces, "
1456 "none of the 'Face' mappings can be used in this case");
1457 continue;
1458 }
1459 if (ELEM(0, edges_dst.size(), num_edges_src)) {
1460 BKE_report(
1461 reports,
1462 RPT_ERROR,
1463 "Source or destination meshes do not have any edges, cannot transfer edge data");
1464 continue;
1465 }
1466
1468 space_transform,
1469 max_distance,
1470 ray_radius,
1471 positions_dst,
1472 edges_dst,
1473 me_src,
1474 me_dst,
1475 &geom_map[EDATA]);
1476 geom_map_init[EDATA] = true;
1477 }
1478
1479 if (mdef && vg_idx != -1 && !weights[EDATA]) {
1480 weights[EDATA] = MEM_malloc_arrayN<float>(size_t(edges_dst.size()), __func__);
1482 mdef, vg_idx, num_verts_dst, edges_dst, invert_vgroup, weights[EDATA]);
1483 }
1484
1486 ob_src,
1487 ob_dst,
1488 me_src,
1489 me_dst,
1490 ME_EDGE,
1491 cddata_type,
1492 mix_mode,
1493 mix_factor,
1494 weights[EDATA],
1495 edges_dst.size(),
1496 use_create,
1497 use_delete,
1498 fromlayers,
1499 tolayers,
1500 space_transform))
1501 {
1502 changed |= (lay_map.first != nullptr);
1503
1504 LISTBASE_FOREACH (CustomDataTransferLayerMap *, lay_mapit, &lay_map) {
1505 CustomData_data_transfer(&geom_map[EDATA], lay_mapit);
1506 }
1507
1508 BLI_freelistN(&lay_map);
1509 }
1510 }
1511 if (DT_DATATYPE_IS_LOOP(dtdata_type)) {
1512 const blender::Span<blender::float3> positions_dst = me_dst->vert_positions();
1513 const int num_verts_dst = me_dst->verts_num;
1514 const blender::OffsetIndices faces_dst = me_dst->faces();
1515 const blender::Span<int> corner_verts_dst = me_dst->corner_verts();
1516
1518
1519 if (!geom_map_init[LDATA]) {
1520 const int num_loops_src = me_src->corners_num;
1521
1522 if ((map_loop_mode == MREMAP_MODE_TOPOLOGY) && (corner_verts_dst.size() != num_loops_src))
1523 {
1524 BKE_report(reports,
1525 RPT_ERROR,
1526 "Source and destination meshes do not have the same number of face corners, "
1527 "'Topology' mapping cannot be used in this case");
1528 continue;
1529 }
1530 if ((map_loop_mode & MREMAP_USE_EDGE) && (me_src->edges_num == 0)) {
1531 BKE_report(reports,
1532 RPT_ERROR,
1533 "Source mesh does not have any edges, "
1534 "none of the 'Edge' mappings can be used in this case");
1535 continue;
1536 }
1537 if (ELEM(0, corner_verts_dst.size(), num_loops_src)) {
1538 BKE_report(
1539 reports,
1540 RPT_ERROR,
1541 "Source or destination meshes do not have any faces, cannot transfer corner data");
1542 continue;
1543 }
1544
1546 space_transform,
1547 max_distance,
1548 ray_radius,
1549 me_dst,
1550 positions_dst,
1551 corner_verts_dst,
1552 faces_dst,
1553 me_src,
1554 island_callback,
1555 islands_handling_precision,
1556 &geom_map[LDATA]);
1557 geom_map_init[LDATA] = true;
1558 }
1559
1560 if (mdef && vg_idx != -1 && !weights[LDATA]) {
1561 weights[LDATA] = MEM_malloc_arrayN<float>(size_t(corner_verts_dst.size()), __func__);
1563 mdef, vg_idx, num_verts_dst, corner_verts_dst, invert_vgroup, weights[LDATA]);
1564 }
1565
1567 ob_src,
1568 ob_dst,
1569 me_src,
1570 me_dst,
1571 ME_LOOP,
1572 cddata_type,
1573 mix_mode,
1574 mix_factor,
1575 weights[LDATA],
1576 corner_verts_dst.size(),
1577 use_create,
1578 use_delete,
1579 fromlayers,
1580 tolayers,
1581 space_transform))
1582 {
1583 changed |= (lay_map.first != nullptr);
1584
1585 LISTBASE_FOREACH (CustomDataTransferLayerMap *, lay_mapit, &lay_map) {
1586 CustomData_data_transfer(&geom_map[LDATA], lay_mapit);
1587 }
1588
1589 BLI_freelistN(&lay_map);
1590 }
1591 }
1592 if (DT_DATATYPE_IS_FACE(dtdata_type)) {
1593 const blender::Span<blender::float3> positions_dst = me_dst->vert_positions();
1594 const int num_verts_dst = me_dst->verts_num;
1595 const blender::OffsetIndices faces_dst = me_dst->faces();
1596 const blender::Span<int> corner_verts_dst = me_dst->corner_verts();
1597
1598 if (!geom_map_init[PDATA]) {
1599 const int num_faces_src = me_src->faces_num;
1600
1601 if ((map_face_mode == MREMAP_MODE_TOPOLOGY) && (faces_dst.size() != num_faces_src)) {
1602 BKE_report(reports,
1603 RPT_ERROR,
1604 "Source and destination meshes do not have the same number of faces, "
1605 "'Topology' mapping cannot be used in this case");
1606 continue;
1607 }
1608 if ((map_face_mode & MREMAP_USE_EDGE) && (me_src->edges_num == 0)) {
1609 BKE_report(reports,
1610 RPT_ERROR,
1611 "Source mesh does not have any edges, "
1612 "none of the 'Edge' mappings can be used in this case");
1613 continue;
1614 }
1615 if (ELEM(0, faces_dst.size(), num_faces_src)) {
1616 BKE_report(
1617 reports,
1618 RPT_ERROR,
1619 "Source or destination meshes do not have any faces, cannot transfer face data");
1620 continue;
1621 }
1622
1624 space_transform,
1625 max_distance,
1626 ray_radius,
1627 me_dst,
1628 positions_dst,
1629 corner_verts_dst,
1630 faces_dst,
1631 me_src,
1632 &geom_map[PDATA]);
1633 geom_map_init[PDATA] = true;
1634 }
1635
1636 if (mdef && vg_idx != -1 && !weights[PDATA]) {
1637 weights[PDATA] = MEM_malloc_arrayN<float>(size_t(faces_dst.size()), __func__);
1639 vg_idx,
1640 num_verts_dst,
1641 corner_verts_dst,
1642 faces_dst,
1643 invert_vgroup,
1644 weights[PDATA]);
1645 }
1646
1648 ob_src,
1649 ob_dst,
1650 me_src,
1651 me_dst,
1652 ME_POLY,
1653 cddata_type,
1654 mix_mode,
1655 mix_factor,
1656 weights[PDATA],
1657 faces_dst.size(),
1658 use_create,
1659 use_delete,
1660 fromlayers,
1661 tolayers,
1662 space_transform))
1663 {
1664 changed |= (lay_map.first != nullptr);
1665
1666 LISTBASE_FOREACH (CustomDataTransferLayerMap *, lay_mapit, &lay_map) {
1667 CustomData_data_transfer(&geom_map[PDATA], lay_mapit);
1668 }
1669
1670 BLI_freelistN(&lay_map);
1671 }
1672 }
1673
1674 data_transfer_dtdata_type_postprocess(me_dst, dtdata_type, changed);
1675 }
1676
1677 for (int i = 0; i < DATAMAX; i++) {
1678 BKE_mesh_remap_free(&geom_map[i]);
1679 MEM_SAFE_FREE(weights[i]);
1680 }
1681
1682 return changed;
1683
1684#undef VDATA
1685#undef EDATA
1686#undef LDATA
1687#undef PDATA
1688#undef DATAMAX
1689}
1690
1692 Object *ob_src,
1693 Object *ob_dst,
1694 const int data_types,
1695 const bool use_create,
1696 const int map_vert_mode,
1697 const int map_edge_mode,
1698 const int map_loop_mode,
1699 const int map_face_mode,
1700 SpaceTransform *space_transform,
1701 const bool auto_transform,
1702 const float max_distance,
1703 const float ray_radius,
1704 const float islands_handling_precision,
1705 const int fromlayers_select[DT_MULTILAYER_INDEX_MAX],
1706 const int tolayers_select[DT_MULTILAYER_INDEX_MAX],
1707 const int mix_mode,
1708 const float mix_factor,
1709 const char *vgroup_name,
1710 const bool invert_vgroup,
1711 ReportList *reports)
1712{
1714 ob_src,
1715 ob_dst,
1716 nullptr,
1717 data_types,
1718 use_create,
1719 map_vert_mode,
1720 map_edge_mode,
1721 map_loop_mode,
1722 map_face_mode,
1723 space_transform,
1724 auto_transform,
1725 max_distance,
1726 ray_radius,
1727 islands_handling_precision,
1728 fromlayers_select,
1729 tolayers_select,
1730 mix_mode,
1731 mix_factor,
1732 vgroup_name,
1733 invert_vgroup,
1734 reports);
1735}
std::optional< blender::StringRef > BKE_id_attributes_default_color_name(const struct ID *id)
CustomDataLayer * BKE_attribute_from_index(AttributeOwner &owner, int lookup_index, AttrDomainMask domain_mask, eCustomDataMask layer_mask)
Definition attribute.cc:898
AttrDomainMask
@ ATTR_DOMAIN_MASK_POINT
@ ATTR_DOMAIN_MASK_CORNER
const struct CustomDataLayer * BKE_attribute_search(const AttributeOwner &owner, blender::StringRef name, eCustomDataMask type, AttrDomainMask domain_mask)
Definition attribute.cc:639
std::optional< blender::StringRef > BKE_id_attributes_active_color_name(const struct ID *id)
#define ATTR_DOMAIN_MASK_COLOR
CustomData interface, see also DNA_customdata_types.h.
void * CustomData_get_layer_named_for_write(CustomData *data, eCustomDataType type, blender::StringRef name, int totelem)
const void * CustomData_get_layer_n(const CustomData *data, eCustomDataType type, int n)
int CustomData_get_named_layer(const CustomData *data, eCustomDataType type, blender::StringRef name)
const void * CustomData_get_layer(const CustomData *data, eCustomDataType type)
@ ME_VERT
@ ME_POLY
@ ME_LOOP
@ ME_EDGE
@ CD_SET_DEFAULT
const void * CustomData_get_layer_named(const CustomData *data, eCustomDataType type, blender::StringRef name)
void * CustomData_add_layer_named(CustomData *data, eCustomDataType type, eCDAllocType alloctype, int totelem, blender::StringRef name)
bool CustomData_free_layer(CustomData *data, eCustomDataType type, int index)
bool CustomData_has_layer_named(const CustomData *data, eCustomDataType type, blender::StringRef name)
const char * CustomData_get_layer_name(const CustomData *data, eCustomDataType type, int n)
void(*)(const CustomDataTransferLayerMap *laymap, void *dest, const void **sources, const float *weights, int count, float mix_factor) cd_datatransfer_interp
void CustomData_free_layers(CustomData *data, eCustomDataType type)
void CustomData_data_transfer(const MeshPairRemap *me_remap, const CustomDataTransferLayerMap *laymap)
int CustomData_get_active_layer(const CustomData *data, eCustomDataType type)
void * CustomData_get_layer_for_write(CustomData *data, eCustomDataType type, int totelem)
void * CustomData_add_layer(CustomData *data, eCustomDataType type, eCDAllocType alloctype, int totelem)
bool CustomData_layertype_is_singleton(eCustomDataType type)
int CustomData_number_of_layers(const CustomData *data, eCustomDataType type)
void * CustomData_get_layer_n_for_write(CustomData *data, eCustomDataType type, int n, int totelem)
support for deformation groups and hooks.
void BKE_defvert_extract_vgroup_to_edgeweights(const MDeformVert *dvert, int defgroup, int verts_num, blender::Span< blender::int2 > edges, bool invert_vgroup, float *r_weights)
Definition deform.cc:1108
void BKE_defvert_extract_vgroup_to_loopweights(const MDeformVert *dvert, int defgroup, int verts_num, blender::Span< int > corner_verts, bool invert_vgroup, float *r_weights)
Definition deform.cc:1135
void BKE_defvert_extract_vgroup_to_faceweights(const MDeformVert *dvert, int defgroup, int verts_num, const blender::Span< int > corner_verts, blender::OffsetIndices< int > faces, bool invert_vgroup, float *r_weights)
Definition deform.cc:1160
int BKE_id_defgroup_name_index(const ID *id, blender::StringRef name)
Definition deform.cc:549
void BKE_defvert_extract_vgroup_to_vertweights(const MDeformVert *dvert, int defgroup, int verts_num, bool invert_vgroup, float *r_weights)
Definition deform.cc:1089
bool(*)(blender::Span< blender::float3 > vert_positions, blender::Span< blender::int2 > edges, blender::Span< bool > uv_seams, blender::OffsetIndices< int > faces, blender::Span< int > corner_verts, blender::Span< int > corner_edges, MeshIslandStore *r_island_store) MeshRemapIslandsCalc
bool BKE_mesh_calc_islands_loop_face_edgeseam(blender::Span< blender::float3 > vert_positions, blender::Span< blender::int2 > edges, blender::Span< bool > uv_seams, blender::OffsetIndices< int > faces, blender::Span< int > corner_verts, blender::Span< int > corner_edges, MeshIslandStore *r_island_store)
void BKE_mesh_remap_find_best_match_from_mesh(blender::Span< blender::float3 > vert_positions_dst, const Mesh *me_src, SpaceTransform *r_space_transform)
void BKE_mesh_remap_free(MeshPairRemap *map)
void BKE_mesh_remap_calc_verts_from_mesh(int mode, const SpaceTransform *space_transform, float max_dist, float ray_radius, blender::Span< blender::float3 > vert_positions_dst, const Mesh *me_src, Mesh *me_dst, MeshPairRemap *r_map)
void BKE_mesh_remap_calc_faces_from_mesh(int mode, const SpaceTransform *space_transform, float max_dist, float ray_radius, const Mesh *mesh_dst, blender::Span< blender::float3 > vert_positions_dst, blender::Span< int > corner_verts, const blender::OffsetIndices< int > faces_dst, const Mesh *me_src, MeshPairRemap *r_map)
void BKE_mesh_remap_calc_edges_from_mesh(int mode, const SpaceTransform *space_transform, float max_dist, float ray_radius, blender::Span< blender::float3 > vert_positions_dst, blender::Span< blender::int2 > edges_dst, const Mesh *me_src, Mesh *me_dst, MeshPairRemap *r_map)
void BKE_mesh_remap_calc_loops_from_mesh(int mode, const SpaceTransform *space_transform, float max_dist, float ray_radius, const Mesh *mesh_dst, blender::Span< blender::float3 > vert_positions_dst, blender::Span< int > corner_verts_dst, const blender::OffsetIndices< int > faces_dst, const Mesh *me_src, MeshRemapIslandsCalc gen_islands_src, float islands_precision_src, MeshPairRemap *r_map)
void BKE_mesh_wrapper_ensure_mdata(Mesh *mesh)
Mesh * BKE_modifier_get_evaluated_mesh_from_evaluated_object(Object *ob_eval)
General operations, lookup, etc. for blender objects.
Mesh * BKE_object_get_evaluated_mesh(const Object *object_eval)
@ RPT_ERROR
Definition BKE_report.hh:39
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition report.cc:153
#define BLI_assert_unreachable()
Definition BLI_assert.h:93
#define BLI_assert(a)
Definition BLI_assert.h:46
#define LISTBASE_FOREACH(type, var, list)
void void BLI_freelistN(ListBase *listbase) ATTR_NONNULL(1)
Definition listbase.cc:497
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:111
MINLINE float interpf(float target, float origin, float t)
ATTR_WARN_UNUSED_RESULT const size_t num
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC
Definition string.cc:41
char * BLI_strdupn(const char *str, size_t len) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition string.cc:30
#define ELEM(...)
T * DEG_get_evaluated(const Depsgraph *depsgraph, T *id)
#define CD_MASK_PROP_BYTE_COLOR
#define CD_MASK_PROP_COLOR
#define CD_MASK_MDEFORMVERT
#define CD_MASK_PROP_FLOAT2
#define CD_MASK_COLOR_ALL
@ CD_PROP_BYTE_COLOR
@ CD_MVERT_SKIN
@ CD_PROP_FLOAT
@ CD_PROP_COLOR
@ CD_PROP_FLOAT2
#define DT_TYPE_MAX
@ DT_LAYERS_ALL_SRC
@ DT_LAYERS_ACTIVE_SRC
@ DT_LAYERS_ACTIVE_DST
@ DT_LAYERS_INDEX_DST
@ DT_LAYERS_NAME_DST
@ DT_MULTILAYER_INDEX_MAX
@ DT_MULTILAYER_INDEX_MDEFORMVERT
@ DT_MULTILAYER_INDEX_INVALID
@ DT_MULTILAYER_INDEX_UV
@ DT_MULTILAYER_INDEX_VCOL_VERT
@ DT_MULTILAYER_INDEX_VCOL_LOOP
#define DT_DATATYPE_IS_LOOP(_dt)
@ MREMAP_MODE_TOPOLOGY
@ MREMAP_USE_POLY
@ MREMAP_USE_EDGE
#define DT_DATATYPE_IS_EDGE(_dt)
@ DT_TYPE_MLOOPCOL_LOOP
@ DT_TYPE_SKIN
@ DT_TYPE_UV
@ DT_TYPE_MPROPCOL_VERT
@ DT_TYPE_BWEIGHT_VERT
@ DT_TYPE_FREESTYLE_FACE
@ 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_FACE(_dt)
@ CDT_MIX_SUB
@ CDT_MIX_REPLACE_BELOW_THRESHOLD
@ CDT_MIX_REPLACE_ABOVE_THRESHOLD
@ CDT_MIX_ADD
@ CDT_MIX_MUL
@ CDT_MIX_TRANSFER
@ CDT_MIX_MIX
#define DT_DATATYPE_IS_VERT(_dt)
Object is a sort of wrapper for general info.
@ OB_MESH
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
BPy_StructRNA * depsgraph
unsigned long long int uint64_t
static AttributeOwner from_id(ID *id)
Definition attribute.cc:44
constexpr void copy_from(Span< T > values) const
Definition BLI_span.hh:739
constexpr int64_t size() const
Definition BLI_span.hh:252
constexpr int64_t size() const
constexpr const char * data() const
GAttributeReader lookup(const StringRef attribute_id) const
GSpanAttributeWriter lookup_or_add_for_write_span(StringRef attribute_id, AttrDomain domain, AttrType data_type, const AttributeInit &initializer=AttributeInitDefaultValue())
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)
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)
bool BKE_object_data_transfer_ex(Depsgraph *depsgraph, 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_face_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 BKE_object_data_transfer_mesh(Depsgraph *depsgraph, 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_face_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)
static bool data_transfer_layersmapping_cdlayers_multisrc_to_dst(ListBase *r_map, const eCustomDataType 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, const CustomData &cd_src, CustomData &cd_dst, const int tolayers, const bool *use_layers_src, const int num_layers_src)
void BKE_object_data_transfer_layout(Depsgraph *depsgraph, 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])
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 eCustomDataType 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, const CustomData &cd_src, CustomData &cd_dst, const int fromlayers, const int tolayers)
static void data_transfer_mesh_attributes_transfer_active_color_string(Mesh *mesh_dst, const Mesh *mesh_src, const AttrDomainMask mask_domain, const int data_type)
bool BKE_object_data_transfer_get_dttypes_capacity(const int dtdata_types, bool *r_advanced_mixing, bool *r_threshold)
#define DATAMAX
#define EDATA
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
static void data_transfer_dtdata_type_postprocess(Mesh *me_dst, const int dtdata_type, const bool changed)
void BKE_object_data_transfer_dttypes_to_cdmask(const int dtdata_types, CustomData_MeshMasks *r_data_masks)
#define LDATA
static void data_transfer_mesh_attributes_transfer_default_color_string(Mesh *mesh_dst, const Mesh *mesh_src, const AttrDomainMask mask_domain, const int data_type)
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 bool data_transfer_layersmapping_generate(ListBase *r_map, Object *ob_src, Object *ob_dst, const 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)
#define PDATA
bool data_transfer_layersmapping_vgroups(ListBase *r_map, int mix_mode, float mix_factor, const float *mix_weights, bool use_create, bool use_delete, Object *ob_src, Object *ob_dst, const Mesh &mesh_src, Mesh &mesh_dst, bool use_dupref_dst, int fromlayers, int tolayers)
Definition deform.cc:1394
@ CD_FAKE_CREASE
@ CD_FAKE_FREESTYLE_EDGE
@ CD_FAKE_FREESTYLE_FACE
@ CD_FAKE_SHARP
@ CD_FAKE_BWEIGHT
@ CD_FAKE_MDEFORMVERT
VecBase< short, 2 > short2
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
Definition mallocn.cc:133
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
ccl_device_inline float interp(const float a, const float b, const float t)
Definition math_base.h:502
void normals_corner_custom_set(Span< float3 > vert_positions, OffsetIndices< int > faces, Span< int > corner_verts, Span< int > corner_edges, GroupedSpan< int > vert_to_face_map, Span< float3 > vert_normals, Span< float3 > face_normals, Span< bool > sharp_faces, MutableSpan< bool > sharp_edges, MutableSpan< float3 > r_custom_corner_normals, MutableSpan< short2 > r_clnors_data)
VecBase< float, 3 > float3
const char * name
return ret
cd_datatransfer_interp interp
Definition DNA_ID.h:414
void * first
int corners_num
CustomData edge_data
int edges_num
CustomData corner_data
CustomData face_data
char * default_color_attribute
CustomData vert_data
int faces_num
int verts_num
char * active_color_attribute
i
Definition text_draw.cc:230