Blender V4.3
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
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#include "DNA_scene_types.h"
16
17#include "BLI_blenlib.h"
18#include "BLI_math_matrix.h"
19#include "BLI_utildefines.h"
20
21#include "BKE_attribute.hh"
22#include "BKE_customdata.hh"
23#include "BKE_data_transfer.h"
24#include "BKE_deform.hh"
25#include "BKE_mesh.hh"
26#include "BKE_mesh_mapping.hh"
27#include "BKE_mesh_remap.hh"
28#include "BKE_mesh_runtime.hh"
29#include "BKE_mesh_wrapper.hh"
30#include "BKE_modifier.hh"
31#include "BKE_object.hh"
32#include "BKE_object_deform.h"
33#include "BKE_report.hh"
34
36
38
40 CustomData_MeshMasks *r_data_masks)
41{
42 for (int i = 0; i < DT_TYPE_MAX; i++) {
43 const int dtdata_type = 1 << i;
44 int cddata_type;
45
46 if (!(dtdata_types & dtdata_type)) {
47 continue;
48 }
49
50 cddata_type = BKE_object_data_transfer_dttype_to_cdtype(dtdata_type);
51 if (!(cddata_type & CD_FAKE)) {
52 if (DT_DATATYPE_IS_VERT(dtdata_type)) {
53 r_data_masks->vmask |= 1LL << cddata_type;
54 }
55 else if (DT_DATATYPE_IS_EDGE(dtdata_type)) {
56 r_data_masks->emask |= 1LL << cddata_type;
57 }
58 else if (DT_DATATYPE_IS_LOOP(dtdata_type)) {
59 r_data_masks->lmask |= 1LL << cddata_type;
60 }
61 else if (DT_DATATYPE_IS_FACE(dtdata_type)) {
62 r_data_masks->pmask |= 1LL << cddata_type;
63 }
64 }
65 else if (cddata_type == CD_FAKE_MDEFORMVERT) {
66 r_data_masks->vmask |= CD_MASK_MDEFORMVERT; /* Exception for vgroups :/ */
67 }
68 else if (cddata_type == CD_FAKE_UV) {
69 r_data_masks->lmask |= CD_MASK_PROP_FLOAT2;
70 }
71 else if (cddata_type == CD_FAKE_LNOR) {
72 r_data_masks->lmask |= CD_MASK_CUSTOMLOOPNORMAL;
73 }
74 }
75}
76
78 bool *r_advanced_mixing,
79 bool *r_threshold)
80{
81 bool ret = false;
82
83 *r_advanced_mixing = false;
84 *r_threshold = false;
85
86 for (int i = 0; (i < DT_TYPE_MAX) && !(ret && *r_advanced_mixing && *r_threshold); i++) {
87 const int dtdata_type = 1 << i;
88
89 if (!(dtdata_types & dtdata_type)) {
90 continue;
91 }
92
93 switch (dtdata_type) {
94 /* Vertex data */
96 *r_advanced_mixing = true;
97 *r_threshold = true;
98 ret = true;
99 break;
100 case DT_TYPE_SKIN:
101 *r_threshold = true;
102 ret = true;
103 break;
105 ret = true;
106 break;
107 /* Edge data */
109 *r_threshold = true;
110 ret = true;
111 break;
112 case DT_TYPE_SEAM:
113 *r_threshold = true;
114 ret = true;
115 break;
116 case DT_TYPE_CREASE:
117 ret = true;
118 break;
120 ret = true;
121 break;
123 *r_threshold = true;
124 ret = true;
125 break;
126 /* Loop/Poly data */
127 case DT_TYPE_UV:
128 ret = true;
129 break;
134 *r_advanced_mixing = true;
135 *r_threshold = true;
136 ret = true;
137 break;
138 case DT_TYPE_LNOR:
139 *r_advanced_mixing = true;
140 ret = true;
141 break;
143 *r_threshold = true;
144 ret = true;
145 break;
147 *r_threshold = true;
148 ret = true;
149 break;
150 }
151 }
152
153 return ret;
154}
155
157{
158 int i, ret = 0;
159
160 for (i = 0; (i < DT_TYPE_MAX) && (ret ^ (ME_VERT | ME_EDGE | ME_LOOP | ME_POLY)); i++) {
161 const int dtdata_type = 1 << i;
162
163 if (!(dtdata_types & dtdata_type)) {
164 continue;
165 }
166
167 if (DT_DATATYPE_IS_VERT(dtdata_type)) {
168 ret |= ME_VERT;
169 }
170 if (DT_DATATYPE_IS_EDGE(dtdata_type)) {
171 ret |= ME_EDGE;
172 }
173 if (DT_DATATYPE_IS_LOOP(dtdata_type)) {
174 ret |= ME_LOOP;
175 }
176 if (DT_DATATYPE_IS_FACE(dtdata_type)) {
177 ret |= ME_POLY;
178 }
179 }
180
181 return ret;
182}
183
185{
186 switch (dtdata_type) {
188 return CD_FAKE_MDEFORMVERT;
189 case DT_TYPE_SHAPEKEY:
190 return CD_FAKE_SHAPEKEY;
191 case DT_TYPE_SKIN:
192 return CD_MVERT_SKIN;
194 return CD_FAKE_BWEIGHT;
195
197 return CD_FAKE_SHARP;
198 case DT_TYPE_SEAM:
199 return CD_FAKE_SEAM;
200 case DT_TYPE_CREASE:
201 return CD_FAKE_CREASE;
203 return CD_FAKE_BWEIGHT;
205 return CD_FREESTYLE_EDGE;
206
207 case DT_TYPE_UV:
208 return CD_FAKE_UV;
210 return CD_FAKE_SHARP;
212 return CD_FREESTYLE_FACE;
213 case DT_TYPE_LNOR:
214 return CD_FAKE_LNOR;
217 return CD_PROP_BYTE_COLOR;
220 return CD_PROP_COLOR;
221 default:
223 }
224 return 0; /* Should never be reached! */
225}
226
248
249/* ********** */
250
257 Mesh *mesh_dst, const Mesh *mesh_src, const AttrDomainMask mask_domain, const int data_type)
258{
259 if (mesh_dst->active_color_attribute) {
260 return;
261 }
262
263 const AttributeOwner owner_src = AttributeOwner::from_id(const_cast<ID *>(&mesh_src->id));
264 AttributeOwner owner_dst = AttributeOwner::from_id(&mesh_dst->id);
265
266 const char *active_color_src = BKE_id_attributes_active_color_name(&mesh_src->id);
267
268 if ((data_type == CD_PROP_COLOR) &&
270 owner_src, active_color_src, CD_MASK_PROP_COLOR, ATTR_DOMAIN_MASK_COLOR))
271 {
272 return;
273 }
274 if ((data_type == CD_PROP_BYTE_COLOR) &&
276 owner_src, active_color_src, CD_MASK_PROP_BYTE_COLOR, ATTR_DOMAIN_MASK_COLOR))
277 {
278 return;
279 }
280
281 if ((data_type == CD_PROP_COLOR) &&
283 owner_dst, active_color_src, CD_MASK_PROP_COLOR, ATTR_DOMAIN_MASK_COLOR))
284 {
285 mesh_dst->active_color_attribute = BLI_strdup(active_color_src);
286 }
287 else if ((data_type == CD_PROP_BYTE_COLOR) &&
289 owner_dst, active_color_src, CD_MASK_PROP_BYTE_COLOR, ATTR_DOMAIN_MASK_COLOR))
290 {
291 mesh_dst->active_color_attribute = BLI_strdup(active_color_src);
292 }
293 else {
294 CustomDataLayer *first_color_layer = BKE_attribute_from_index(
295 owner_dst, 0, mask_domain, CD_MASK_COLOR_ALL);
296 if (first_color_layer != nullptr) {
297 mesh_dst->active_color_attribute = BLI_strdup(first_color_layer->name);
298 }
299 }
300}
301
308 Mesh *mesh_dst, const Mesh *mesh_src, const AttrDomainMask mask_domain, const int data_type)
309{
310 if (mesh_dst->default_color_attribute) {
311 return;
312 }
313
314 const AttributeOwner owner_src = AttributeOwner::from_id(const_cast<ID *>(&mesh_src->id));
315 AttributeOwner owner_dst = AttributeOwner::from_id(&mesh_dst->id);
316
317 const char *default_color_src = BKE_id_attributes_default_color_name(&mesh_src->id);
318
319 if ((data_type == CD_PROP_COLOR) &&
321 owner_src, default_color_src, CD_MASK_PROP_COLOR, ATTR_DOMAIN_MASK_COLOR))
322 {
323 return;
324 }
325 if ((data_type == CD_PROP_BYTE_COLOR) &&
327 owner_src, default_color_src, CD_MASK_PROP_BYTE_COLOR, ATTR_DOMAIN_MASK_COLOR))
328 {
329 return;
330 }
331
332 if ((data_type == CD_PROP_COLOR) &&
334 owner_dst, default_color_src, CD_MASK_PROP_COLOR, ATTR_DOMAIN_MASK_COLOR))
335 {
336 mesh_dst->default_color_attribute = BLI_strdup(default_color_src);
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_strdup(default_color_src);
343 }
344 else {
345 CustomDataLayer *first_color_layer = BKE_attribute_from_index(
346 owner_dst, 0, mask_domain, CD_MASK_COLOR_ALL);
347 if (first_color_layer != nullptr) {
348 mesh_dst->default_color_attribute = BLI_strdup(first_color_layer->name);
349 }
350 }
351}
352
353/* ********** */
354
356 const int dtdata_type,
357 const bool changed)
358{
359 using namespace blender;
360 if (dtdata_type == DT_TYPE_LNOR) {
361 if (!changed) {
362 return;
363 }
364 /* Bake edited destination loop normals into custom normals again. */
365 CustomData *ldata_dst = &me_dst->corner_data;
366
367 blender::float3 *loop_nors_dst = static_cast<blender::float3 *>(
369 blender::short2 *custom_nors_dst = static_cast<blender::short2 *>(
371
372 if (!custom_nors_dst) {
373 custom_nors_dst = static_cast<blender::short2 *>(CustomData_add_layer(
374 ldata_dst, CD_CUSTOMLOOPNORMAL, CD_SET_DEFAULT, me_dst->corners_num));
375 }
376
377 bke::MutableAttributeAccessor attributes = me_dst->attributes_for_write();
378 bke::SpanAttributeWriter<bool> sharp_edges = attributes.lookup_or_add_for_write_span<bool>(
379 "sharp_edge", bke::AttrDomain::Edge);
380 const VArraySpan sharp_faces = *attributes.lookup<bool>("sharp_face", bke::AttrDomain::Face);
381 /* Note loop_nors_dst contains our custom normals as transferred from source... */
382 blender::bke::mesh::normals_corner_custom_set(me_dst->vert_positions(),
383 me_dst->edges(),
384 me_dst->faces(),
385 me_dst->corner_verts(),
386 me_dst->corner_edges(),
387 me_dst->vert_normals(),
388 me_dst->face_normals(),
389 sharp_faces,
390 sharp_edges.span,
391 {loop_nors_dst, me_dst->corners_num},
392 {custom_nors_dst, me_dst->corners_num});
393 sharp_edges.finish();
394 CustomData_free_layers(ldata_dst, CD_NORMAL, me_dst->corners_num);
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{
467 CustomDataTransferLayerMap *item = MEM_cnew<CustomDataTransferLayerMap>(__func__);
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{
502 uint64_t data_flag = 0;
503
504 if (cddata_type == CD_FREESTYLE_EDGE) {
505 data_flag = FREESTYLE_EDGE_MARK;
506 }
507 else if (cddata_type == CD_FREESTYLE_FACE) {
508 data_flag = FREESTYLE_FACE_MARK;
509 }
510
512 cddata_type,
513 mix_mode,
514 mix_factor,
515 mix_weights,
516 data_src,
517 data_dst,
518 0,
519 0,
520 0,
521 0,
522 0,
523 data_flag,
524 interp,
525 interp_data);
526}
527
536 const eCustomDataType cddata_type,
537 const int mix_mode,
538 const float mix_factor,
539 const float *mix_weights,
540 const int num_elem_dst,
541 const bool use_create,
542 const bool use_delete,
543 const CustomData *cd_src,
544 CustomData *cd_dst,
545 const int tolayers,
546 const bool *use_layers_src,
547 const int num_layers_src,
549 void *interp_data)
550{
551 const void *data_src;
552 void *data_dst = nullptr;
553 int idx_src = num_layers_src;
554 int idx_dst, tot_dst = CustomData_number_of_layers(cd_dst, cddata_type);
555 bool *data_dst_to_delete = nullptr;
556
557 if (!use_layers_src) {
558 /* No source at all, we can only delete all destination if requested. */
559 if (use_delete) {
560 idx_dst = tot_dst;
561 while (idx_dst--) {
562 CustomData_free_layer(cd_dst, cddata_type, num_elem_dst, idx_dst);
563 }
564 }
565 return true;
566 }
567
568 switch (tolayers) {
570 idx_dst = tot_dst;
571
572 /* Find last source actually used! */
573 while (idx_src-- && !use_layers_src[idx_src]) {
574 /* pass */
575 }
576 idx_src++;
577
578 if (idx_dst < idx_src) {
579 if (use_create) {
580 /* Create as much data layers as necessary! */
581 for (; idx_dst < idx_src; idx_dst++) {
583 cd_dst, eCustomDataType(cddata_type), CD_SET_DEFAULT, num_elem_dst);
584 }
585 }
586 else {
587 /* Otherwise, just try to map what we can with existing dst data layers. */
588 idx_src = idx_dst;
589 }
590 }
591 else if (use_delete && idx_dst > idx_src) {
592 while (idx_dst-- > idx_src) {
593 CustomData_free_layer(cd_dst, cddata_type, num_elem_dst, idx_dst);
594 }
595 }
596 if (r_map) {
597 while (idx_src--) {
598 if (!use_layers_src[idx_src]) {
599 continue;
600 }
601 data_src = CustomData_get_layer_n(cd_src, cddata_type, idx_src);
602 data_dst = CustomData_get_layer_n_for_write(cd_dst, cddata_type, idx_src, num_elem_dst);
604 cddata_type,
605 mix_mode,
606 mix_factor,
607 mix_weights,
608 data_src,
609 data_dst,
610 interp,
611 interp_data);
612 }
613 }
614 break;
616 if (use_delete) {
617 if (tot_dst) {
618 data_dst_to_delete = static_cast<bool *>(
619 MEM_mallocN(sizeof(*data_dst_to_delete) * size_t(tot_dst), __func__));
620 memset(data_dst_to_delete, true, sizeof(*data_dst_to_delete) * size_t(tot_dst));
621 }
622 }
623
624 while (idx_src--) {
625 const char *name;
626
627 if (!use_layers_src[idx_src]) {
628 continue;
629 }
630
631 name = CustomData_get_layer_name(cd_src, cddata_type, idx_src);
632 data_src = CustomData_get_layer_n(cd_src, cddata_type, idx_src);
633
634 if ((idx_dst = CustomData_get_named_layer(cd_dst, cddata_type, name)) == -1) {
635 if (use_create) {
637 cd_dst, eCustomDataType(cddata_type), CD_SET_DEFAULT, num_elem_dst, name);
638 idx_dst = CustomData_get_named_layer(cd_dst, cddata_type, name);
639 }
640 else {
641 /* If we are not allowed to create missing dst data layers,
642 * just skip matching src one. */
643 continue;
644 }
645 }
646 else if (data_dst_to_delete) {
647 data_dst_to_delete[idx_dst] = false;
648 }
649 if (r_map) {
650 data_dst = CustomData_get_layer_n_for_write(cd_dst, cddata_type, idx_dst, num_elem_dst);
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 eCustomDataType 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 const CustomData *cd_src,
693 CustomData *cd_dst,
694 const int fromlayers,
695 const int tolayers,
697 void *interp_data)
698{
699 int idx_src, idx_dst;
700 const void *data_src;
701 void *data_dst = nullptr;
702
703 if (CustomData_layertype_is_singleton(cddata_type)) {
704 if (!(data_src = CustomData_get_layer(cd_src, cddata_type))) {
705 if (use_delete) {
706 CustomData_free_layer(cd_dst, cddata_type, num_elem_dst, 0);
707 }
708 return true;
709 }
710
711 data_dst = CustomData_get_layer_for_write(cd_dst, cddata_type, num_elem_dst);
712 if (!data_dst) {
713 if (!use_create) {
714 return true;
715 }
716 data_dst = CustomData_add_layer(
717 cd_dst, eCustomDataType(cddata_type), CD_SET_DEFAULT, num_elem_dst);
718 }
719
720 if (r_map) {
722 cddata_type,
723 mix_mode,
724 mix_factor,
725 mix_weights,
726 data_src,
727 data_dst,
728 interp,
729 interp_data);
730 }
731 }
732 else if (fromlayers == DT_LAYERS_ACTIVE_SRC || fromlayers >= 0) {
733 /* NOTE: use_delete has not much meaning in this case, ignored. */
734
735 if (fromlayers >= 0) { /* Real-layer index */
736 idx_src = fromlayers;
737 }
738 else {
739 if ((idx_src = CustomData_get_active_layer(cd_src, cddata_type)) == -1) {
740 return true;
741 }
742 }
743 data_src = CustomData_get_layer_n(cd_src, cddata_type, idx_src);
744 if (!data_src) {
745 return true;
746 }
747
748 if (tolayers >= 0) { /* Real-layer index */
749 idx_dst = tolayers;
750 data_dst = CustomData_get_layer_n_for_write(cd_dst, cddata_type, idx_dst, num_elem_dst);
751 }
752 else if (tolayers == DT_LAYERS_ACTIVE_DST) {
753 if ((idx_dst = CustomData_get_active_layer(cd_dst, cddata_type)) == -1) {
754 if (!use_create) {
755 return true;
756 }
757 data_dst = CustomData_add_layer(
758 cd_dst, eCustomDataType(cddata_type), CD_SET_DEFAULT, num_elem_dst);
759 }
760 else {
761 data_dst = CustomData_get_layer_n_for_write(cd_dst, cddata_type, idx_dst, num_elem_dst);
762 }
763 }
764 else if (tolayers == DT_LAYERS_INDEX_DST) {
765 int num = CustomData_number_of_layers(cd_dst, cddata_type);
766 idx_dst = idx_src;
767 if (num <= idx_dst) {
768 if (!use_create) {
769 return true;
770 }
771 /* Create as much data layers as necessary! */
772 for (; num <= idx_dst; num++) {
773 CustomData_add_layer(cd_dst, eCustomDataType(cddata_type), CD_SET_DEFAULT, num_elem_dst);
774 }
775 }
776 data_dst = CustomData_get_layer_n_for_write(cd_dst, cddata_type, idx_dst, num_elem_dst);
777 }
778 else if (tolayers == DT_LAYERS_NAME_DST) {
779 const char *name = CustomData_get_layer_name(cd_src, cddata_type, idx_src);
780 if ((idx_dst = CustomData_get_named_layer(cd_dst, cddata_type, name)) == -1) {
781 if (!use_create) {
782 return true;
783 }
785 cd_dst, eCustomDataType(cddata_type), CD_SET_DEFAULT, num_elem_dst, name);
786 idx_dst = CustomData_get_named_layer(cd_dst, cddata_type, name);
787 }
788 data_dst = CustomData_get_layer_n_for_write(cd_dst, cddata_type, idx_dst, num_elem_dst);
789 }
790 else {
791 return false;
792 }
793
794 if (!data_dst) {
795 return false;
796 }
797
798 if (r_map) {
800 cddata_type,
801 mix_mode,
802 mix_factor,
803 mix_weights,
804 data_src,
805 data_dst,
806 interp,
807 interp_data);
808 }
809 }
810 else if (fromlayers == DT_LAYERS_ALL_SRC) {
811 int num_src = CustomData_number_of_layers(cd_src, eCustomDataType(cddata_type));
812 bool *use_layers_src = num_src ? static_cast<bool *>(MEM_mallocN(
813 sizeof(*use_layers_src) * size_t(num_src), __func__)) :
814 nullptr;
815 bool ret;
816
817 if (use_layers_src) {
818 memset(use_layers_src, true, sizeof(*use_layers_src) * num_src);
819 }
820
822 cddata_type,
823 mix_mode,
824 mix_factor,
825 mix_weights,
826 num_elem_dst,
827 use_create,
828 use_delete,
829 cd_src,
830 cd_dst,
831 tolayers,
832 use_layers_src,
833 num_src,
834 interp,
835 interp_data);
836
837 if (use_layers_src) {
838 MEM_freeN(use_layers_src);
839 }
840 return ret;
841 }
842 else {
843 return false;
844 }
845
846 return true;
847}
848
850 Object *ob_src,
851 Object *ob_dst,
852 const Mesh *me_src,
853 Mesh *me_dst,
854 const int elem_type,
855 int cddata_type,
856 int mix_mode,
857 float mix_factor,
858 const float *mix_weights,
859 const int num_elem_dst,
860 const bool use_create,
861 const bool use_delete,
862 const int fromlayers,
863 const int tolayers,
864 SpaceTransform *space_transform)
865{
866 using namespace blender;
867 const CustomData *cd_src;
868 CustomData *cd_dst;
869
871 void *interp_data = nullptr;
872
873 if (elem_type == ME_VERT) {
874 if (!(cddata_type & CD_FAKE)) {
875 cd_src = &me_src->vert_data;
876 cd_dst = &me_dst->vert_data;
877
879 eCustomDataType(cddata_type),
880 mix_mode,
881 mix_factor,
882 mix_weights,
883 num_elem_dst,
884 use_create,
885 use_delete,
886 cd_src,
887 cd_dst,
888 fromlayers,
889 tolayers,
890 interp,
891 interp_data))
892 {
893 /* We handle specific source selection cases here. */
894 return false;
895 }
896 return true;
897 }
898 if (cddata_type == CD_FAKE_MDEFORMVERT) {
899 bool ret;
900
901 cd_src = &me_src->vert_data;
902 cd_dst = &me_dst->vert_data;
903
905 mix_mode,
906 mix_factor,
907 mix_weights,
908 num_elem_dst,
909 use_create,
910 use_delete,
911 ob_src,
912 ob_dst,
913 cd_src,
914 cd_dst,
915 me_dst != ob_dst->data,
916 fromlayers,
917 tolayers);
918 return ret;
919 }
920 if (cddata_type == CD_FAKE_SHAPEKEY) {
921 /* TODO: leaving shape-keys aside for now, quite specific case,
922 * since we can't access them from mesh vertices :/ */
923 return false;
924 }
925 if (r_map && cddata_type == CD_FAKE_BWEIGHT) {
926 if (!CustomData_get_layer_named(&me_dst->vert_data, CD_PROP_FLOAT, "bevel_weight_vert")) {
930 me_dst->verts_num,
931 "bevel_weight_vert");
932 }
934 r_map,
936 mix_mode,
937 mix_factor,
938 mix_weights,
939 CustomData_get_layer_named(&me_src->vert_data, CD_PROP_FLOAT, "bevel_weight_vert"),
941 &me_dst->vert_data, CD_PROP_FLOAT, "bevel_weight_vert", me_dst->verts_num),
942 interp,
943 interp_data);
944 return true;
945 }
946 }
947 else if (elem_type == ME_EDGE) {
948 if (!(cddata_type & CD_FAKE)) { /* Unused for edges, currently... */
949 cd_src = &me_src->edge_data;
950 cd_dst = &me_dst->edge_data;
951
953 eCustomDataType(cddata_type),
954 mix_mode,
955 mix_factor,
956 mix_weights,
957 num_elem_dst,
958 use_create,
959 use_delete,
960 cd_src,
961 cd_dst,
962 fromlayers,
963 tolayers,
964 interp,
965 interp_data))
966 {
967 /* We handle specific source selection cases here. */
968 return false;
969 }
970 return true;
971 }
972 if (r_map && cddata_type == CD_FAKE_SEAM) {
973 if (!CustomData_has_layer_named(&me_dst->edge_data, CD_PROP_BOOL, ".uv_seam")) {
975 &me_dst->edge_data, CD_PROP_BOOL, CD_SET_DEFAULT, me_dst->edges_num, ".uv_seam");
976 }
978 r_map,
980 mix_mode,
981 mix_factor,
982 mix_weights,
985 &me_dst->edge_data, CD_PROP_BOOL, ".uv_seam", me_dst->edges_num),
986 interp,
987 interp_data);
988 return true;
989 }
990 if (r_map && cddata_type == CD_FAKE_SHARP) {
991 if (!CustomData_has_layer_named(&me_dst->edge_data, CD_PROP_BOOL, "sharp_edge")) {
993 &me_dst->edge_data, CD_PROP_BOOL, CD_SET_DEFAULT, me_dst->edges_num, "sharp_edge");
994 }
996 r_map,
998 mix_mode,
999 mix_factor,
1000 mix_weights,
1001 CustomData_get_layer_named(&me_src->edge_data, CD_PROP_BOOL, "sharp_edge"),
1003 &me_dst->edge_data, CD_PROP_BOOL, "sharp_edge", me_dst->edges_num),
1004 interp,
1005 interp_data);
1006 return true;
1007 }
1008 if (r_map && cddata_type == CD_FAKE_BWEIGHT) {
1009 if (!CustomData_get_layer_named(&me_dst->edge_data, CD_PROP_FLOAT, "bevel_weight_edge")) {
1013 me_dst->edges_num,
1014 "bevel_weight_edge");
1015 }
1017 r_map,
1019 mix_mode,
1020 mix_factor,
1021 mix_weights,
1022 CustomData_get_layer_named(&me_src->edge_data, CD_PROP_FLOAT, "bevel_weight_edge"),
1024 &me_dst->edge_data, CD_PROP_FLOAT, "bevel_weight_edge", me_dst->edges_num),
1025 interp,
1026 interp_data);
1027 return true;
1028 }
1029 if (r_map && cddata_type == CD_FAKE_CREASE) {
1030 if (!CustomData_get_layer_named(&me_dst->edge_data, CD_PROP_FLOAT, "crease_edge")) {
1032 &me_dst->edge_data, CD_PROP_FLOAT, CD_SET_DEFAULT, me_dst->edges_num, "crease_edge");
1033 }
1035 r_map,
1037 mix_mode,
1038 mix_factor,
1039 mix_weights,
1040 CustomData_get_layer_named(&me_src->edge_data, CD_PROP_FLOAT, "crease_edge"),
1042 &me_dst->edge_data, CD_PROP_FLOAT, "crease_edge", me_dst->edges_num),
1043 interp,
1044 interp_data);
1045 return true;
1046 }
1047
1048 return false;
1049 }
1050 else if (elem_type == ME_LOOP) {
1051 if (cddata_type == CD_FAKE_UV) {
1052 cddata_type = CD_PROP_FLOAT2;
1053 }
1054 else if (cddata_type == CD_FAKE_LNOR) {
1055 if (r_map) {
1056 /* Use #CD_NORMAL as a temporary storage for custom normals in 3D vector form.
1057 * A post-process step will convert this layer to #CD_CUSTOMLOOPNORMAL. */
1058 float3 *dst_data = static_cast<float3 *>(
1060 if (!dst_data) {
1061 dst_data = static_cast<float3 *>(CustomData_add_layer(
1062 &me_dst->corner_data, CD_NORMAL, CD_SET_DEFAULT, me_dst->corners_num));
1063 }
1064 if (mix_factor != 1.0f || mix_weights) {
1065 MutableSpan(dst_data, me_dst->corners_num).copy_from(me_dst->corner_normals());
1066 }
1067 /* Post-process will convert it back to CD_CUSTOMLOOPNORMAL. */
1069 CD_NORMAL,
1070 mix_mode,
1071 mix_factor,
1072 mix_weights,
1073 me_src->corner_normals().data(),
1074 dst_data,
1076 space_transform);
1077 }
1078 return true;
1079 }
1080
1081 if (!(cddata_type & CD_FAKE)) {
1082 cd_src = &me_src->corner_data;
1083 cd_dst = &me_dst->corner_data;
1084
1086 eCustomDataType(cddata_type),
1087 mix_mode,
1088 mix_factor,
1089 mix_weights,
1090 num_elem_dst,
1091 use_create,
1092 use_delete,
1093 cd_src,
1094 cd_dst,
1095 fromlayers,
1096 tolayers,
1097 interp,
1098 interp_data))
1099 {
1100 /* We handle specific source selection cases here. */
1101 return false;
1102 }
1103 return true;
1104 }
1105
1106 return false;
1107 }
1108 else if (elem_type == ME_POLY) {
1109 if (cddata_type == CD_FAKE_UV) {
1110 cddata_type = CD_PROP_FLOAT2;
1111 }
1112
1113 if (!(cddata_type & CD_FAKE)) {
1114 cd_src = &me_src->face_data;
1115 cd_dst = &me_dst->face_data;
1116
1118 eCustomDataType(cddata_type),
1119 mix_mode,
1120 mix_factor,
1121 mix_weights,
1122 num_elem_dst,
1123 use_create,
1124 use_delete,
1125 cd_src,
1126 cd_dst,
1127 fromlayers,
1128 tolayers,
1129 interp,
1130 interp_data))
1131 {
1132 /* We handle specific source selection cases here. */
1133 return false;
1134 }
1135 return true;
1136 }
1137 if (r_map && cddata_type == CD_FAKE_SHARP) {
1138 if (!CustomData_has_layer_named(&me_dst->face_data, CD_PROP_BOOL, "sharp_face")) {
1140 &me_dst->face_data, CD_PROP_BOOL, CD_SET_DEFAULT, me_dst->faces_num, "sharp_face");
1141 }
1143 r_map,
1145 mix_mode,
1146 mix_factor,
1147 mix_weights,
1148 CustomData_get_layer_named(&me_src->face_data, CD_PROP_BOOL, "sharp_face"),
1150 &me_dst->face_data, CD_PROP_BOOL, "sharp_face", num_elem_dst),
1151 interp,
1152 interp_data);
1153 return true;
1154 }
1155
1156 return false;
1157 }
1158
1159 return false;
1160}
1161
1163 Object *ob_src,
1164 Object *ob_dst,
1165 const int data_types,
1166 const bool use_delete,
1167 const int fromlayers_select[DT_MULTILAYER_INDEX_MAX],
1168 const int tolayers_select[DT_MULTILAYER_INDEX_MAX])
1169{
1170 Mesh *me_dst;
1171
1172 const bool use_create = true; /* We always create needed layers here. */
1173
1174 BLI_assert((ob_src != ob_dst) && (ob_src->type == OB_MESH) && (ob_dst->type == OB_MESH));
1175
1176 me_dst = static_cast<Mesh *>(ob_dst->data);
1177
1178 /* Get source evaluated mesh. */
1179 const Object *ob_src_eval = DEG_get_evaluated_object(depsgraph, ob_src);
1180 const Mesh *me_src = BKE_object_get_evaluated_mesh(ob_src_eval);
1181 if (!me_src) {
1182 return;
1183 }
1184
1185 /* Check all possible data types. */
1186 for (int i = 0; i < DT_TYPE_MAX; i++) {
1187 const int dtdata_type = 1 << i;
1188 int cddata_type;
1189 int fromlayers, tolayers, fromto_idx;
1190
1191 if (!(data_types & dtdata_type)) {
1192 continue;
1193 }
1194
1195 cddata_type = BKE_object_data_transfer_dttype_to_cdtype(dtdata_type);
1196
1197 fromto_idx = BKE_object_data_transfer_dttype_to_srcdst_index(dtdata_type);
1198
1199 if (fromto_idx != DT_MULTILAYER_INDEX_INVALID) {
1200 fromlayers = fromlayers_select[fromto_idx];
1201 tolayers = tolayers_select[fromto_idx];
1202 }
1203 else {
1204 fromlayers = tolayers = 0;
1205 }
1206
1207 if (DT_DATATYPE_IS_VERT(dtdata_type)) {
1208 const int num_elem_dst = me_dst->verts_num;
1209
1211 ob_src,
1212 ob_dst,
1213 me_src,
1214 me_dst,
1215 ME_VERT,
1216 cddata_type,
1217 0,
1218 0.0f,
1219 nullptr,
1220 num_elem_dst,
1221 use_create,
1222 use_delete,
1223 fromlayers,
1224 tolayers,
1225 nullptr);
1226 /* Make sure we have active/default color layers if none existed before.
1227 * Use the active/default from src (if it was transferred), otherwise the first. */
1228 if (ELEM(cddata_type, CD_PROP_COLOR, CD_PROP_BYTE_COLOR)) {
1230 me_dst, me_src, ATTR_DOMAIN_MASK_POINT, cddata_type);
1232 me_dst, me_src, ATTR_DOMAIN_MASK_POINT, cddata_type);
1233 }
1234 }
1235 if (DT_DATATYPE_IS_EDGE(dtdata_type)) {
1236 const int num_elem_dst = me_dst->edges_num;
1237
1239 ob_src,
1240 ob_dst,
1241 me_src,
1242 me_dst,
1243 ME_EDGE,
1244 cddata_type,
1245 0,
1246 0.0f,
1247 nullptr,
1248 num_elem_dst,
1249 use_create,
1250 use_delete,
1251 fromlayers,
1252 tolayers,
1253 nullptr);
1254 }
1255 if (DT_DATATYPE_IS_LOOP(dtdata_type)) {
1256 const int num_elem_dst = me_dst->corners_num;
1257
1259 ob_src,
1260 ob_dst,
1261 me_src,
1262 me_dst,
1263 ME_LOOP,
1264 cddata_type,
1265 0,
1266 0.0f,
1267 nullptr,
1268 num_elem_dst,
1269 use_create,
1270 use_delete,
1271 fromlayers,
1272 tolayers,
1273 nullptr);
1274 /* Make sure we have active/default color layers if none existed before.
1275 * Use the active/default from src (if it was transferred), otherwise the first. */
1276 if (ELEM(cddata_type, CD_PROP_COLOR, CD_PROP_BYTE_COLOR)) {
1278 me_dst, me_src, ATTR_DOMAIN_MASK_CORNER, cddata_type);
1280 me_dst, me_src, ATTR_DOMAIN_MASK_CORNER, cddata_type);
1281 }
1282 }
1283 if (DT_DATATYPE_IS_FACE(dtdata_type)) {
1284 const int num_elem_dst = me_dst->faces_num;
1285
1287 ob_src,
1288 ob_dst,
1289 me_src,
1290 me_dst,
1291 ME_POLY,
1292 cddata_type,
1293 0,
1294 0.0f,
1295 nullptr,
1296 num_elem_dst,
1297 use_create,
1298 use_delete,
1299 fromlayers,
1300 tolayers,
1301 nullptr);
1302 }
1303 }
1304}
1305
1307 Object *ob_src,
1308 Object *ob_dst,
1309 Mesh *me_dst,
1310 const int data_types,
1311 bool use_create,
1312 const int map_vert_mode,
1313 const int map_edge_mode,
1314 const int map_loop_mode,
1315 const int map_face_mode,
1316 SpaceTransform *space_transform,
1317 const bool auto_transform,
1318 const float max_distance,
1319 const float ray_radius,
1320 const float islands_handling_precision,
1321 const int fromlayers_select[DT_MULTILAYER_INDEX_MAX],
1322 const int tolayers_select[DT_MULTILAYER_INDEX_MAX],
1323 const int mix_mode,
1324 const float mix_factor,
1325 const char *vgroup_name,
1326 const bool invert_vgroup,
1327 ReportList *reports)
1328{
1329#define VDATA 0
1330#define EDATA 1
1331#define LDATA 2
1332#define PDATA 3
1333#define DATAMAX 4
1334
1335 SpaceTransform auto_space_transform;
1336
1337 const Mesh *me_src;
1338
1339 const MDeformVert *mdef = nullptr;
1340 int vg_idx = -1;
1341 float *weights[DATAMAX] = {nullptr};
1342
1343 MeshPairRemap geom_map[DATAMAX] = {{0}};
1344 bool geom_map_init[DATAMAX] = {false};
1345 ListBase lay_map = {nullptr};
1346 bool changed = false;
1347 bool is_modifier = false;
1348
1349 const bool use_delete = false; /* We never delete data layers from destination here. */
1350
1351 BLI_assert((ob_src != ob_dst) && (ob_src->type == OB_MESH) && (ob_dst->type == OB_MESH));
1352
1353 if (me_dst) {
1354 /* Never create needed custom layers on passed destination mesh
1355 * (assumed to *not* be ob_dst->data, aka modifier case). */
1356 use_create = false;
1357 is_modifier = true;
1358 }
1359 else {
1360 me_dst = static_cast<Mesh *>(ob_dst->data);
1361 }
1362
1363 if (vgroup_name) {
1364 mdef = static_cast<const MDeformVert *>(
1366 if (mdef) {
1367 vg_idx = BKE_id_defgroup_name_index(&me_dst->id, vgroup_name);
1368 }
1369 }
1370
1371 /* Get source evaluated mesh. */
1372 if (is_modifier) {
1374 }
1375 else {
1376 const Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob_src);
1377 me_src = BKE_object_get_evaluated_mesh(ob_eval);
1378 }
1379 if (!me_src) {
1380 return changed;
1381 }
1382 BKE_mesh_wrapper_ensure_mdata(const_cast<Mesh *>(me_src));
1383
1384 if (auto_transform) {
1385 if (space_transform == nullptr) {
1386 space_transform = &auto_space_transform;
1387 }
1388
1390 reinterpret_cast<const float(*)[3]>(me_dst->vert_positions().data()),
1391 me_dst->verts_num,
1392 me_src,
1393 space_transform);
1394 }
1395
1396 /* Check all possible data types.
1397 * Note item mappings and destination mix weights are cached. */
1398 for (int i = 0; i < DT_TYPE_MAX; i++) {
1399 const int dtdata_type = 1 << i;
1400 int cddata_type;
1401 int fromlayers, tolayers, fromto_idx;
1402
1403 if (!(data_types & dtdata_type)) {
1404 continue;
1405 }
1406
1407 cddata_type = BKE_object_data_transfer_dttype_to_cdtype(dtdata_type);
1408
1409 fromto_idx = BKE_object_data_transfer_dttype_to_srcdst_index(dtdata_type);
1410 if (fromto_idx != DT_MULTILAYER_INDEX_INVALID) {
1411 fromlayers = fromlayers_select[fromto_idx];
1412 tolayers = tolayers_select[fromto_idx];
1413 }
1414 else {
1415 fromlayers = tolayers = 0;
1416 }
1417
1418 if (DT_DATATYPE_IS_VERT(dtdata_type)) {
1419 blender::MutableSpan<blender::float3> positions_dst = me_dst->vert_positions_for_write();
1420 const int num_verts_dst = me_dst->verts_num;
1421
1422 if (!geom_map_init[VDATA]) {
1423 const int num_verts_src = me_src->verts_num;
1424
1425 if ((map_vert_mode == MREMAP_MODE_TOPOLOGY) && (num_verts_dst != num_verts_src)) {
1426 BKE_report(reports,
1427 RPT_ERROR,
1428 "Source and destination meshes do not have the same number of vertices, "
1429 "'Topology' mapping cannot be used in this case");
1430 continue;
1431 }
1432 if ((map_vert_mode & MREMAP_USE_EDGE) && (me_src->edges_num == 0)) {
1433 BKE_report(reports,
1434 RPT_ERROR,
1435 "Source mesh does not have any edges, "
1436 "none of the 'Edge' mappings can be used in this case");
1437 continue;
1438 }
1439 if ((map_vert_mode & MREMAP_USE_POLY) && (me_src->faces_num == 0)) {
1440 BKE_report(reports,
1441 RPT_ERROR,
1442 "Source mesh does not have any faces, "
1443 "none of the 'Face' mappings can be used in this case");
1444 continue;
1445 }
1446 if (ELEM(0, num_verts_dst, num_verts_src)) {
1447 BKE_report(reports,
1448 RPT_ERROR,
1449 "Source or destination meshes do not have any vertices, cannot transfer "
1450 "vertex data");
1451 continue;
1452 }
1453
1455 map_vert_mode,
1456 space_transform,
1457 max_distance,
1458 ray_radius,
1459 reinterpret_cast<const float(*)[3]>(positions_dst.data()),
1460 num_verts_dst,
1461 me_src,
1462 me_dst,
1463 &geom_map[VDATA]);
1464 geom_map_init[VDATA] = true;
1465 }
1466
1467 if (mdef && vg_idx != -1 && !weights[VDATA]) {
1468 weights[VDATA] = static_cast<float *>(
1469 MEM_mallocN(sizeof(*(weights[VDATA])) * size_t(num_verts_dst), __func__));
1471 mdef, vg_idx, num_verts_dst, invert_vgroup, weights[VDATA]);
1472 }
1473
1475 ob_src,
1476 ob_dst,
1477 me_src,
1478 me_dst,
1479 ME_VERT,
1480 cddata_type,
1481 mix_mode,
1482 mix_factor,
1483 weights[VDATA],
1484 num_verts_dst,
1485 use_create,
1486 use_delete,
1487 fromlayers,
1488 tolayers,
1489 space_transform))
1490 {
1491 changed |= (lay_map.first != nullptr);
1492
1493 LISTBASE_FOREACH (CustomDataTransferLayerMap *, lay_mapit, &lay_map) {
1494 CustomData_data_transfer(&geom_map[VDATA], lay_mapit);
1495 }
1496
1497 BLI_freelistN(&lay_map);
1498 }
1499 }
1500 if (DT_DATATYPE_IS_EDGE(dtdata_type)) {
1501 blender::MutableSpan<blender::float3> positions_dst = me_dst->vert_positions_for_write();
1502
1503 const int num_verts_dst = me_dst->verts_num;
1504 const blender::Span<blender::int2> edges_dst = me_dst->edges();
1505
1506 if (!geom_map_init[EDATA]) {
1507 const int num_edges_src = me_src->edges_num;
1508
1509 if ((map_edge_mode == MREMAP_MODE_TOPOLOGY) && (edges_dst.size() != num_edges_src)) {
1510 BKE_report(reports,
1511 RPT_ERROR,
1512 "Source and destination meshes do not have the same number of edges, "
1513 "'Topology' mapping cannot be used in this case");
1514 continue;
1515 }
1516 if ((map_edge_mode & MREMAP_USE_POLY) && (me_src->faces_num == 0)) {
1517 BKE_report(reports,
1518 RPT_ERROR,
1519 "Source mesh does not have any faces, "
1520 "none of the 'Face' mappings can be used in this case");
1521 continue;
1522 }
1523 if (ELEM(0, edges_dst.size(), num_edges_src)) {
1524 BKE_report(
1525 reports,
1526 RPT_ERROR,
1527 "Source or destination meshes do not have any edges, cannot transfer edge data");
1528 continue;
1529 }
1530
1532 map_edge_mode,
1533 space_transform,
1534 max_distance,
1535 ray_radius,
1536 reinterpret_cast<const float(*)[3]>(positions_dst.data()),
1537 num_verts_dst,
1538 edges_dst.data(),
1539 edges_dst.size(),
1540 me_src,
1541 me_dst,
1542 &geom_map[EDATA]);
1543 geom_map_init[EDATA] = true;
1544 }
1545
1546 if (mdef && vg_idx != -1 && !weights[EDATA]) {
1547 weights[EDATA] = static_cast<float *>(
1548 MEM_mallocN(sizeof(*weights[EDATA]) * size_t(edges_dst.size()), __func__));
1550 vg_idx,
1551 num_verts_dst,
1552 edges_dst.data(),
1553 edges_dst.size(),
1554 invert_vgroup,
1555 weights[EDATA]);
1556 }
1557
1559 ob_src,
1560 ob_dst,
1561 me_src,
1562 me_dst,
1563 ME_EDGE,
1564 cddata_type,
1565 mix_mode,
1566 mix_factor,
1567 weights[EDATA],
1568 edges_dst.size(),
1569 use_create,
1570 use_delete,
1571 fromlayers,
1572 tolayers,
1573 space_transform))
1574 {
1575 changed |= (lay_map.first != nullptr);
1576
1577 LISTBASE_FOREACH (CustomDataTransferLayerMap *, lay_mapit, &lay_map) {
1578 CustomData_data_transfer(&geom_map[EDATA], lay_mapit);
1579 }
1580
1581 BLI_freelistN(&lay_map);
1582 }
1583 }
1584 if (DT_DATATYPE_IS_LOOP(dtdata_type)) {
1585 const blender::Span<blender::float3> positions_dst = me_dst->vert_positions();
1586 const int num_verts_dst = me_dst->verts_num;
1587 const blender::OffsetIndices faces_dst = me_dst->faces();
1588 const blender::Span<int> corner_verts_dst = me_dst->corner_verts();
1589
1591
1592 if (!geom_map_init[LDATA]) {
1593 const int num_loops_src = me_src->corners_num;
1594
1595 if ((map_loop_mode == MREMAP_MODE_TOPOLOGY) && (corner_verts_dst.size() != num_loops_src))
1596 {
1597 BKE_report(reports,
1598 RPT_ERROR,
1599 "Source and destination meshes do not have the same number of face corners, "
1600 "'Topology' mapping cannot be used in this case");
1601 continue;
1602 }
1603 if ((map_loop_mode & MREMAP_USE_EDGE) && (me_src->edges_num == 0)) {
1604 BKE_report(reports,
1605 RPT_ERROR,
1606 "Source mesh does not have any edges, "
1607 "none of the 'Edge' mappings can be used in this case");
1608 continue;
1609 }
1610 if (ELEM(0, corner_verts_dst.size(), num_loops_src)) {
1611 BKE_report(
1612 reports,
1613 RPT_ERROR,
1614 "Source or destination meshes do not have any faces, cannot transfer corner data");
1615 continue;
1616 }
1617
1619 map_loop_mode,
1620 space_transform,
1621 max_distance,
1622 ray_radius,
1623 me_dst,
1624 reinterpret_cast<const float(*)[3]>(positions_dst.data()),
1625 num_verts_dst,
1626 corner_verts_dst.data(),
1627 corner_verts_dst.size(),
1628 faces_dst,
1629 me_src,
1630 island_callback,
1631 islands_handling_precision,
1632 &geom_map[LDATA]);
1633 geom_map_init[LDATA] = true;
1634 }
1635
1636 if (mdef && vg_idx != -1 && !weights[LDATA]) {
1637 weights[LDATA] = static_cast<float *>(
1638 MEM_mallocN(sizeof(*weights[LDATA]) * size_t(corner_verts_dst.size()), __func__));
1640 vg_idx,
1641 num_verts_dst,
1642 corner_verts_dst.data(),
1643 corner_verts_dst.size(),
1644 invert_vgroup,
1645 weights[LDATA]);
1646 }
1647
1649 ob_src,
1650 ob_dst,
1651 me_src,
1652 me_dst,
1653 ME_LOOP,
1654 cddata_type,
1655 mix_mode,
1656 mix_factor,
1657 weights[LDATA],
1658 corner_verts_dst.size(),
1659 use_create,
1660 use_delete,
1661 fromlayers,
1662 tolayers,
1663 space_transform))
1664 {
1665 changed |= (lay_map.first != nullptr);
1666
1667 LISTBASE_FOREACH (CustomDataTransferLayerMap *, lay_mapit, &lay_map) {
1668 CustomData_data_transfer(&geom_map[LDATA], lay_mapit);
1669 }
1670
1671 BLI_freelistN(&lay_map);
1672 }
1673 }
1674 if (DT_DATATYPE_IS_FACE(dtdata_type)) {
1675 const blender::Span<blender::float3> positions_dst = me_dst->vert_positions();
1676 const int num_verts_dst = me_dst->verts_num;
1677 const blender::OffsetIndices faces_dst = me_dst->faces();
1678 const blender::Span<int> corner_verts_dst = me_dst->corner_verts();
1679
1680 if (!geom_map_init[PDATA]) {
1681 const int num_faces_src = me_src->faces_num;
1682
1683 if ((map_face_mode == MREMAP_MODE_TOPOLOGY) && (faces_dst.size() != num_faces_src)) {
1684 BKE_report(reports,
1685 RPT_ERROR,
1686 "Source and destination meshes do not have the same number of faces, "
1687 "'Topology' mapping cannot be used in this case");
1688 continue;
1689 }
1690 if ((map_face_mode & MREMAP_USE_EDGE) && (me_src->edges_num == 0)) {
1691 BKE_report(reports,
1692 RPT_ERROR,
1693 "Source mesh does not have any edges, "
1694 "none of the 'Edge' mappings can be used in this case");
1695 continue;
1696 }
1697 if (ELEM(0, faces_dst.size(), num_faces_src)) {
1698 BKE_report(
1699 reports,
1700 RPT_ERROR,
1701 "Source or destination meshes do not have any faces, cannot transfer face data");
1702 continue;
1703 }
1704
1706 map_face_mode,
1707 space_transform,
1708 max_distance,
1709 ray_radius,
1710 me_dst,
1711 reinterpret_cast<const float(*)[3]>(positions_dst.data()),
1712 num_verts_dst,
1713 corner_verts_dst.data(),
1714 faces_dst,
1715 me_src,
1716 &geom_map[PDATA]);
1717 geom_map_init[PDATA] = true;
1718 }
1719
1720 if (mdef && vg_idx != -1 && !weights[PDATA]) {
1721 weights[PDATA] = static_cast<float *>(
1722 MEM_mallocN(sizeof(*weights[PDATA]) * faces_dst.size(), __func__));
1724 vg_idx,
1725 num_verts_dst,
1726 corner_verts_dst.data(),
1727 corner_verts_dst.size(),
1728 faces_dst,
1729 invert_vgroup,
1730 weights[PDATA]);
1731 }
1732
1734 ob_src,
1735 ob_dst,
1736 me_src,
1737 me_dst,
1738 ME_POLY,
1739 cddata_type,
1740 mix_mode,
1741 mix_factor,
1742 weights[PDATA],
1743 faces_dst.size(),
1744 use_create,
1745 use_delete,
1746 fromlayers,
1747 tolayers,
1748 space_transform))
1749 {
1750 changed |= (lay_map.first != nullptr);
1751
1752 LISTBASE_FOREACH (CustomDataTransferLayerMap *, lay_mapit, &lay_map) {
1753 CustomData_data_transfer(&geom_map[PDATA], lay_mapit);
1754 }
1755
1756 BLI_freelistN(&lay_map);
1757 }
1758 }
1759
1760 data_transfer_dtdata_type_postprocess(me_dst, dtdata_type, changed);
1761 }
1762
1763 for (int i = 0; i < DATAMAX; i++) {
1764 BKE_mesh_remap_free(&geom_map[i]);
1765 MEM_SAFE_FREE(weights[i]);
1766 }
1767
1768 return changed;
1769
1770#undef VDATA
1771#undef EDATA
1772#undef LDATA
1773#undef PDATA
1774#undef DATAMAX
1775}
1776
1778 Object *ob_src,
1779 Object *ob_dst,
1780 const int data_types,
1781 const bool use_create,
1782 const int map_vert_mode,
1783 const int map_edge_mode,
1784 const int map_loop_mode,
1785 const int map_face_mode,
1786 SpaceTransform *space_transform,
1787 const bool auto_transform,
1788 const float max_distance,
1789 const float ray_radius,
1790 const float islands_handling_precision,
1791 const int fromlayers_select[DT_MULTILAYER_INDEX_MAX],
1792 const int tolayers_select[DT_MULTILAYER_INDEX_MAX],
1793 const int mix_mode,
1794 const float mix_factor,
1795 const char *vgroup_name,
1796 const bool invert_vgroup,
1797 ReportList *reports)
1798{
1800 ob_src,
1801 ob_dst,
1802 nullptr,
1803 data_types,
1804 use_create,
1805 map_vert_mode,
1806 map_edge_mode,
1807 map_loop_mode,
1808 map_face_mode,
1809 space_transform,
1810 auto_transform,
1811 max_distance,
1812 ray_radius,
1813 islands_handling_precision,
1814 fromlayers_select,
1815 tolayers_select,
1816 mix_mode,
1817 mix_factor,
1818 vgroup_name,
1819 invert_vgroup,
1820 reports);
1821}
const char * BKE_id_attributes_default_color_name(const struct ID *id)
const char * BKE_id_attributes_active_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:878
AttrDomainMask
@ ATTR_DOMAIN_MASK_POINT
@ ATTR_DOMAIN_MASK_CORNER
#define ATTR_DOMAIN_MASK_COLOR
const struct CustomDataLayer * BKE_attribute_search(const AttributeOwner &owner, const char *name, eCustomDataMask type, AttrDomainMask domain_mask)
Definition attribute.cc:636
CustomData interface, see also DNA_customdata_types.h.
@ ME_VERT
@ ME_POLY
@ ME_LOOP
@ ME_EDGE
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)
@ CDT_MIX_SUB
@ CDT_MIX_REPLACE_BELOW_THRESHOLD
@ CDT_MIX_REPLACE_ABOVE_THRESHOLD
@ CDT_MIX_ADD
@ CDT_MIX_MUL
@ CDT_MIX_TRANSFER
@ CDT_MIX_MIX
const void * CustomData_get_layer(const CustomData *data, eCustomDataType type)
void(*)(const CustomDataTransferLayerMap *laymap, void *dest, const void **sources, const float *weights, int count, float mix_factor) cd_datatransfer_interp
@ 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_has_layer_named(const CustomData *data, eCustomDataType type, blender::StringRef name)
const char * CustomData_get_layer_name(const CustomData *data, eCustomDataType type, int n)
bool CustomData_free_layer(CustomData *data, eCustomDataType type, int totelem, int index)
void CustomData_free_layers(CustomData *data, eCustomDataType type, int totelem)
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)
@ 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_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)
#define DT_TYPE_MAX
@ DT_LAYERS_ACTIVE_DST
@ DT_LAYERS_INDEX_DST
@ DT_LAYERS_NAME_DST
#define DT_DATATYPE_IS_LOOP(_dt)
@ DT_LAYERS_ALL_SRC
@ DT_LAYERS_ACTIVE_SRC
#define DT_DATATYPE_IS_EDGE(_dt)
@ 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
#define DT_DATATYPE_IS_FACE(_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_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_faceweights(const MDeformVert *dvert, int defgroup, int verts_num, const int *corner_verts, int loops_num, blender::OffsetIndices< int > faces, bool invert_vgroup, float *r_weights)
Definition deform.cc:1156
void BKE_defvert_extract_vgroup_to_edgeweights(const MDeformVert *dvert, int defgroup, int verts_num, const blender::int2 *edges, int edges_num, bool invert_vgroup, float *r_weights)
Definition deform.cc:1100
void BKE_defvert_extract_vgroup_to_loopweights(const MDeformVert *dvert, int defgroup, int verts_num, const int *corner_verts, int loops_num, bool invert_vgroup, float *r_weights)
Definition deform.cc:1129
int BKE_id_defgroup_name_index(const ID *id, blender::StringRef name)
Definition deform.cc:543
void BKE_defvert_extract_vgroup_to_vertweights(const MDeformVert *dvert, int defgroup, int verts_num, bool invert_vgroup, float *r_weights)
Definition deform.cc:1081
bool(*)(const float(*vert_positions)[3], int totvert, const blender::int2 *edges, int totedge, const bool *uv_seams, blender::OffsetIndices< int > faces, const int *corner_verts, const int *corner_edges, int corners_num, MeshIslandStore *r_island_store) MeshRemapIslandsCalc
bool BKE_mesh_calc_islands_loop_face_edgeseam(const float(*vert_positions)[3], int totvert, const blender::int2 *edges, int totedge, const bool *uv_seams, blender::OffsetIndices< int > faces, const int *corner_verts, const int *corner_edges, int corners_num, MeshIslandStore *r_island_store)
void BKE_mesh_remap_calc_loops_from_mesh(int mode, const SpaceTransform *space_transform, float max_dist, float ray_radius, const Mesh *mesh_dst, const float(*vert_positions_dst)[3], int numverts_dst, const int *corner_verts_dst, int numloops_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_remap_calc_edges_from_mesh(int mode, const SpaceTransform *space_transform, float max_dist, float ray_radius, const float(*vert_positions_dst)[3], int numverts_dst, const blender::int2 *edges_dst, int numedges_dst, const Mesh *me_src, Mesh *me_dst, MeshPairRemap *r_map)
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, const float(*vert_positions_dst)[3], int numverts_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, const float(*vert_positions_dst)[3], int numverts_dst, const int *corner_verts, const blender::OffsetIndices< int > faces_dst, const Mesh *me_src, MeshPairRemap *r_map)
void BKE_mesh_remap_find_best_match_from_mesh(const float(*vert_positions_dst)[3], int numverts_dst, const Mesh *me_src, SpaceTransform *r_space_transform)
@ MREMAP_MODE_TOPOLOGY
@ MREMAP_USE_POLY
@ MREMAP_USE_EDGE
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)
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.cc:125
#define BLI_assert_unreachable()
Definition BLI_assert.h:97
#define BLI_assert(a)
Definition BLI_assert.h:50
#define LISTBASE_FOREACH(type, var, list)
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition listbase.cc:496
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:110
MINLINE float interpf(float target, float origin, float t)
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC
Definition string.c:40
#define ELEM(...)
Object * DEG_get_evaluated_object(const Depsgraph *depsgraph, Object *object)
#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_CUSTOMLOOPNORMAL
@ CD_MDEFORMVERT
@ CD_PROP_COLOR
@ CD_PROP_FLOAT2
@ CD_FREESTYLE_EDGE
@ CD_FREESTYLE_FACE
#define CD_MASK_CUSTOMLOOPNORMAL
@ FREESTYLE_FACE_MARK
@ FREESTYLE_EDGE_MARK
Object is a sort of wrapper for general info.
@ OB_MESH
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
static AttributeOwner from_id(ID *id)
Definition attribute.cc:43
constexpr T * data() const
Definition BLI_span.hh:540
constexpr void copy_from(Span< T > values) const
Definition BLI_span.hh:726
constexpr const T * data() const
Definition BLI_span.hh:216
constexpr int64_t size() const
Definition BLI_span.hh:253
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 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, 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)
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 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)
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, cd_datatransfer_interp interp, void *interp_data)
#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(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, const struct CustomData *cd_src, struct CustomData *cd_dst, bool use_dupref_dst, int fromlayers, int tolayers)
const Depsgraph * depsgraph
void *(* MEM_mallocN)(size_t len, const char *str)
Definition mallocn.cc:44
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
ccl_device_inline float2 interp(const float2 a, const float2 b, float t)
void normals_corner_custom_set(Span< float3 > vert_positions, Span< int2 > edges, OffsetIndices< int > faces, Span< int > corner_verts, Span< int > corner_edges, 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)
return ret
unsigned __int64 uint64_t
Definition stdint.h:90
cd_datatransfer_interp interp
Definition DNA_ID.h:413
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