Blender
V3.3
|
#include "CLG_log.h"
#include "MEM_guardedalloc.h"
#include "DNA_customdata_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "BKE_attribute.h"
#include "BKE_customdata.h"
#include "BKE_data_transfer.h"
#include "BKE_deform.h"
#include "BKE_mesh.h"
#include "BKE_mesh_mapping.h"
#include "BKE_mesh_remap.h"
#include "BKE_mesh_runtime.h"
#include "BKE_mesh_wrapper.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
#include "BKE_object_deform.h"
#include "BKE_report.h"
#include "data_transfer_intern.h"
Go to the source code of this file.
Macros | |
#define | VDATA 0 |
#define | EDATA 1 |
#define | LDATA 2 |
#define | PDATA 3 |
#define | DATAMAX 4 |
Functions | |
void | BKE_object_data_transfer_dttypes_to_cdmask (const int dtdata_types, CustomData_MeshMasks *r_data_masks) |
bool | BKE_object_data_transfer_get_dttypes_capacity (const int dtdata_types, bool *r_advanced_mixing, bool *r_threshold) |
int | BKE_object_data_transfer_get_dttypes_item_types (const int dtdata_types) |
int | BKE_object_data_transfer_dttype_to_cdtype (const int dtdata_type) |
int | BKE_object_data_transfer_dttype_to_srcdst_index (const int dtdata_type) |
static void | data_transfer_dtdata_type_preprocess (Mesh *me_src, Mesh *me_dst, const int dtdata_type, const bool dirty_nors_dst) |
static void | data_transfer_dtdata_type_postprocess (Object *UNUSED(ob_src), Object *UNUSED(ob_dst), Mesh *UNUSED(me_src), Mesh *me_dst, const int dtdata_type, const bool changed) |
static MeshRemapIslandsCalc | data_transfer_get_loop_islands_generator (const int cddata_type) |
float | data_transfer_interp_float_do (const int mix_mode, const float val_dst, const float val_src, const float mix_factor) |
static void | data_transfer_interp_char (const CustomDataTransferLayerMap *laymap, void *dest, const void **sources, const float *weights, const int count, const float mix_factor) |
void | 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 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_cdlayers_multisrc_to_dst (ListBase *r_map, const int cddata_type, const int mix_mode, const float mix_factor, const float *mix_weights, const int num_elem_dst, const bool use_create, const bool use_delete, CustomData *cd_src, CustomData *cd_dst, const bool use_dupref_dst, const int tolayers, const bool *use_layers_src, const int num_layers_src, cd_datatransfer_interp interp, void *interp_data) |
static bool | data_transfer_layersmapping_cdlayers (ListBase *r_map, const int cddata_type, const int mix_mode, const float mix_factor, const float *mix_weights, const int num_elem_dst, const bool use_create, const bool use_delete, CustomData *cd_src, CustomData *cd_dst, const bool use_dupref_dst, const int fromlayers, const int tolayers, cd_datatransfer_interp interp, void *interp_data) |
static bool | data_transfer_layersmapping_generate (ListBase *r_map, Object *ob_src, Object *ob_dst, Mesh *me_src, Mesh *me_dst, const int elem_type, int cddata_type, int mix_mode, float mix_factor, const float *mix_weights, const int num_elem_dst, const bool use_create, const bool use_delete, const int fromlayers, const int tolayers, SpaceTransform *space_transform) |
void | BKE_object_data_transfer_layout (struct Depsgraph *depsgraph, Scene *scene, Object *ob_src, Object *ob_dst, const int data_types, const bool use_delete, const int fromlayers_select[DT_MULTILAYER_INDEX_MAX], const int tolayers_select[DT_MULTILAYER_INDEX_MAX]) |
bool | BKE_object_data_transfer_ex (struct Depsgraph *depsgraph, Scene *scene, Object *ob_src, Object *ob_dst, Mesh *me_dst, const int data_types, bool use_create, const int map_vert_mode, const int map_edge_mode, const int map_loop_mode, const int map_poly_mode, SpaceTransform *space_transform, const bool auto_transform, const float max_distance, const float ray_radius, const float islands_handling_precision, const int fromlayers_select[DT_MULTILAYER_INDEX_MAX], const int tolayers_select[DT_MULTILAYER_INDEX_MAX], const int mix_mode, const float mix_factor, const char *vgroup_name, const bool invert_vgroup, ReportList *reports) |
bool | BKE_object_data_transfer_mesh (struct Depsgraph *depsgraph, Scene *scene, Object *ob_src, Object *ob_dst, const int data_types, const bool use_create, const int map_vert_mode, const int map_edge_mode, const int map_loop_mode, const int map_poly_mode, SpaceTransform *space_transform, const bool auto_transform, const float max_distance, const float ray_radius, const float islands_handling_precision, const int fromlayers_select[DT_MULTILAYER_INDEX_MAX], const int tolayers_select[DT_MULTILAYER_INDEX_MAX], const int mix_mode, const float mix_factor, const char *vgroup_name, const bool invert_vgroup, ReportList *reports) |
Variables | |
static CLG_LogRef | LOG = {"bke.data_transfer"} |
#define DATAMAX 4 |
#define EDATA 1 |
#define LDATA 2 |
#define PDATA 3 |
#define VDATA 0 |
int BKE_object_data_transfer_dttype_to_cdtype | ( | const int | dtdata_type | ) |
Definition at line 187 of file data_transfer.c.
References BLI_assert_unreachable, CD_FAKE_BWEIGHT, CD_FAKE_CREASE, CD_FAKE_LNOR, CD_FAKE_MDEFORMVERT, CD_FAKE_SEAM, CD_FAKE_SHAPEKEY, CD_FAKE_SHARP, CD_FAKE_UV, CD_FREESTYLE_EDGE, CD_FREESTYLE_FACE, CD_MVERT_SKIN, CD_PROP_BYTE_COLOR, CD_PROP_COLOR, DT_TYPE_BWEIGHT_EDGE, DT_TYPE_BWEIGHT_VERT, DT_TYPE_CREASE, DT_TYPE_FREESTYLE_EDGE, DT_TYPE_FREESTYLE_FACE, DT_TYPE_LNOR, DT_TYPE_MDEFORMVERT, DT_TYPE_MLOOPCOL_LOOP, DT_TYPE_MLOOPCOL_VERT, DT_TYPE_MPROPCOL_LOOP, DT_TYPE_MPROPCOL_VERT, DT_TYPE_SEAM, DT_TYPE_SHAPEKEY, DT_TYPE_SHARP_EDGE, DT_TYPE_SHARP_FACE, DT_TYPE_SKIN, and DT_TYPE_UV.
Referenced by BKE_object_data_transfer_dttypes_to_cdmask(), BKE_object_data_transfer_ex(), and BKE_object_data_transfer_layout().
int BKE_object_data_transfer_dttype_to_srcdst_index | ( | const int | dtdata_type | ) |
Definition at line 230 of file data_transfer.c.
References DT_MULTILAYER_INDEX_INVALID, DT_MULTILAYER_INDEX_MDEFORMVERT, DT_MULTILAYER_INDEX_SHAPEKEY, DT_MULTILAYER_INDEX_UV, DT_MULTILAYER_INDEX_VCOL_LOOP, DT_MULTILAYER_INDEX_VCOL_VERT, DT_TYPE_MDEFORMVERT, DT_TYPE_MLOOPCOL_LOOP, DT_TYPE_MLOOPCOL_VERT, DT_TYPE_MPROPCOL_LOOP, DT_TYPE_MPROPCOL_VERT, DT_TYPE_SHAPEKEY, and DT_TYPE_UV.
Referenced by BKE_object_data_transfer_ex(), BKE_object_data_transfer_layout(), data_transfer_exec(), and datalayout_transfer_exec().
void BKE_object_data_transfer_dttypes_to_cdmask | ( | const int | dtdata_types, |
CustomData_MeshMasks * | r_data_masks | ||
) |
Definition at line 40 of file data_transfer.c.
References BKE_object_data_transfer_dttype_to_cdtype(), CD_FAKE, CD_FAKE_LNOR, CD_FAKE_MDEFORMVERT, CD_FAKE_UV, CD_MASK_CUSTOMLOOPNORMAL, CD_MASK_MDEFORMVERT, CD_MASK_MLOOPUV, CD_MASK_NORMAL, DT_DATATYPE_IS_EDGE, DT_DATATYPE_IS_LOOP, DT_DATATYPE_IS_POLY, DT_DATATYPE_IS_VERT, DT_TYPE_MAX, CustomData_MeshMasks::emask, CustomData_MeshMasks::lmask, CustomData_MeshMasks::pmask, and CustomData_MeshMasks::vmask.
Referenced by BKE_object_data_transfer_ex(), BKE_object_data_transfer_layout(), requiredDataMask(), and updateDepsgraph().
bool BKE_object_data_transfer_ex | ( | struct Depsgraph * | depsgraph, |
Scene * | scene, | ||
Object * | ob_src, | ||
Object * | ob_dst, | ||
Mesh * | me_dst, | ||
const int | data_types, | ||
bool | use_create, | ||
const int | map_vert_mode, | ||
const int | map_edge_mode, | ||
const int | map_loop_mode, | ||
const int | map_poly_mode, | ||
SpaceTransform * | space_transform, | ||
const bool | auto_transform, | ||
const float | max_distance, | ||
const float | ray_radius, | ||
const float | islands_handling_precision, | ||
const int | fromlayers_select[DT_MULTILAYER_INDEX_MAX], | ||
const int | tolayers_select[DT_MULTILAYER_INDEX_MAX], | ||
const int | mix_mode, | ||
const float | mix_factor, | ||
const char * | vgroup_name, | ||
const bool | invert_vgroup, | ||
ReportList * | reports | ||
) |
Definition at line 1340 of file data_transfer.c.
References BKE_defvert_extract_vgroup_to_edgeweights(), BKE_defvert_extract_vgroup_to_loopweights(), BKE_defvert_extract_vgroup_to_polyweights(), BKE_defvert_extract_vgroup_to_vertweights(), BKE_id_defgroup_name_index(), BKE_mesh_remap_calc_edges_from_mesh(), BKE_mesh_remap_calc_loops_from_mesh(), BKE_mesh_remap_calc_polys_from_mesh(), BKE_mesh_remap_calc_source_cddata_masks_from_map_modes(), BKE_mesh_remap_calc_verts_from_mesh(), BKE_mesh_remap_find_best_match_from_mesh(), BKE_mesh_remap_free(), BKE_mesh_vertex_normals_are_dirty(), BKE_mesh_wrapper_ensure_mdata(), BKE_modifier_get_evaluated_mesh_from_evaluated_object(), BKE_object_data_transfer_dttype_to_cdtype(), BKE_object_data_transfer_dttype_to_srcdst_index(), BKE_object_data_transfer_dttypes_to_cdmask(), BKE_report(), BLI_assert, BLI_freelistN(), CD_MASK_BAREMESH, CD_MDEFORMVERT, CLOG_WARN, CustomData_data_transfer(), CustomData_get_layer(), CustomData_MeshMasks_are_matching(), Object::data, data_transfer_dtdata_type_postprocess(), data_transfer_dtdata_type_preprocess(), data_transfer_get_loop_islands_generator(), data_transfer_layersmapping_generate(), DATAMAX, depsgraph, DT_DATATYPE_IS_EDGE, DT_DATATYPE_IS_LOOP, DT_DATATYPE_IS_POLY, DT_DATATYPE_IS_VERT, DT_MULTILAYER_INDEX_INVALID, DT_TYPE_MAX, EDATA, ELEM, ListBase::first, Mesh::flag, Mesh::id, Object_Runtime::last_data_mask, LDATA, Mesh::ldata, LOG, ME_AUTOSMOOTH, ME_EDGE, ME_LOOP, ME_POLY, ME_VERT, Mesh::medge, MEM_mallocN, MEM_SAFE_FREE, mesh_get_eval_final(), Mesh::mloop, Mesh::mpoly, MREMAP_MODE_TOPOLOGY, MREMAP_USE_EDGE, MREMAP_USE_POLY, Mesh::mvert, CustomDataTransferLayerMap::next, NULL, OB_MESH, PDATA, RPT_ERROR, Object::runtime, scene, Mesh::smoothresh, Mesh::totedge, Mesh::totloop, Mesh::totpoly, Mesh::totvert, Object::type, VDATA, and Mesh::vdata.
Referenced by BKE_object_data_transfer_mesh(), and modifyMesh().
bool BKE_object_data_transfer_get_dttypes_capacity | ( | int | dtdata_types, |
bool * | r_advanced_mixing, | ||
bool * | r_threshold | ||
) |
Check what can do each layer type (if it is actually handled by transfer-data, if it supports advanced mixing.
Definition at line 80 of file data_transfer.c.
References DT_TYPE_BWEIGHT_EDGE, DT_TYPE_BWEIGHT_VERT, DT_TYPE_CREASE, DT_TYPE_FREESTYLE_EDGE, DT_TYPE_FREESTYLE_FACE, DT_TYPE_LNOR, DT_TYPE_MAX, DT_TYPE_MDEFORMVERT, DT_TYPE_MLOOPCOL_LOOP, DT_TYPE_MLOOPCOL_VERT, DT_TYPE_MPROPCOL_LOOP, DT_TYPE_MPROPCOL_VERT, DT_TYPE_SEAM, DT_TYPE_SHARP_EDGE, DT_TYPE_SHARP_FACE, DT_TYPE_SKIN, DT_TYPE_UV, and ret.
Referenced by dt_mix_mode_itemf().
int BKE_object_data_transfer_get_dttypes_item_types | ( | const int | dtdata_types | ) |
Definition at line 159 of file data_transfer.c.
References DT_DATATYPE_IS_EDGE, DT_DATATYPE_IS_LOOP, DT_DATATYPE_IS_POLY, DT_DATATYPE_IS_VERT, DT_TYPE_MAX, ME_EDGE, ME_LOOP, ME_POLY, ME_VERT, and ret.
Referenced by dependsOnNormals().
void BKE_object_data_transfer_layout | ( | struct Depsgraph * | depsgraph, |
struct Scene * | scene, | ||
struct Object * | ob_src, | ||
struct Object * | ob_dst, | ||
int | data_types, | ||
bool | use_delete, | ||
const int | fromlayers_select[DT_MULTILAYER_INDEX_MAX], | ||
const int | tolayers_select[DT_MULTILAYER_INDEX_MAX] | ||
) |
Transfer data layout of selected types from source to destination object. By default, it only creates new data layers if needed on ob_dst. If use_delete is true, it will also delete data layers on ob_dst that do not match those from ob_src, to get (as much as possible) exact copy of source data layout.
Definition at line 1208 of file data_transfer.c.
References BKE_object_data_transfer_dttype_to_cdtype(), BKE_object_data_transfer_dttype_to_srcdst_index(), BKE_object_data_transfer_dttypes_to_cdmask(), BLI_assert, CD_MASK_BAREMESH, Object::data, data_transfer_layersmapping_generate(), depsgraph, DT_DATATYPE_IS_EDGE, DT_DATATYPE_IS_LOOP, DT_DATATYPE_IS_POLY, DT_DATATYPE_IS_VERT, DT_MULTILAYER_INDEX_INVALID, DT_TYPE_MAX, ME_EDGE, ME_LOOP, ME_POLY, ME_VERT, mesh_get_eval_final(), NULL, OB_MESH, scene, Mesh::totedge, Mesh::totloop, Mesh::totpoly, Mesh::totvert, and Object::type.
Referenced by datalayout_transfer_exec().
bool BKE_object_data_transfer_mesh | ( | struct Depsgraph * | depsgraph, |
Scene * | scene, | ||
Object * | ob_src, | ||
Object * | ob_dst, | ||
const int | data_types, | ||
const bool | use_create, | ||
const int | map_vert_mode, | ||
const int | map_edge_mode, | ||
const int | map_loop_mode, | ||
const int | map_poly_mode, | ||
SpaceTransform * | space_transform, | ||
const bool | auto_transform, | ||
const float | max_distance, | ||
const float | ray_radius, | ||
const float | islands_handling_precision, | ||
const int | fromlayers_select[DT_MULTILAYER_INDEX_MAX], | ||
const int | tolayers_select[DT_MULTILAYER_INDEX_MAX], | ||
const int | mix_mode, | ||
const float | mix_factor, | ||
const char * | vgroup_name, | ||
const bool | invert_vgroup, | ||
ReportList * | reports | ||
) |
Definition at line 1825 of file data_transfer.c.
References BKE_object_data_transfer_ex(), depsgraph, NULL, and scene.
Referenced by data_transfer_exec().
|
static |
Definition at line 311 of file data_transfer.c.
References BKE_mesh_normals_loop_custom_set(), BKE_mesh_poly_normals_ensure(), BKE_mesh_vertex_normals_ensure(), CD_CALLOC, CD_CUSTOMLOOPNORMAL, CD_NORMAL, CustomData_add_layer(), CustomData_get_layer(), DT_TYPE_LNOR, float(), Mesh::ldata, Mesh::medge, Mesh::mloop, Mesh::mpoly, Mesh::mvert, NULL, Mesh::totedge, Mesh::totloop, Mesh::totpoly, and Mesh::totvert.
Referenced by BKE_object_data_transfer_ex().
|
static |
Definition at line 256 of file data_transfer.c.
References BKE_mesh_normals_loop_split(), BKE_mesh_poly_normals_ensure(), BKE_mesh_vertex_normals_ensure(), BLI_assert, CD_CALLOC, CD_CUSTOMLOOPNORMAL, CD_FLAG_TEMPORARY, CD_NORMAL, CustomData_add_layer(), CustomData_get_layer(), CustomData_set_layer_flag(), DT_TYPE_LNOR, Mesh::flag, float(), Mesh::ldata, ME_AUTOSMOOTH, Mesh::medge, Mesh::mloop, Mesh::mpoly, Mesh::mvert, NULL, Mesh::smoothresh, Mesh::totedge, Mesh::totloop, Mesh::totpoly, Mesh::totvert, and void.
Referenced by BKE_object_data_transfer_ex().
|
static |
Definition at line 361 of file data_transfer.c.
References BKE_mesh_calc_islands_loop_poly_edgeseam(), CD_FAKE_UV, and NULL.
Referenced by BKE_object_data_transfer_ex().
|
static |
Definition at line 408 of file data_transfer.c.
References CLAMP, count, data_transfer_interp_float_do(), dest, float(), and CustomDataTransferLayerMap::mix_mode.
Referenced by data_transfer_layersmapping_generate().
float data_transfer_interp_float_do | ( | const int | mix_mode, |
const float | val_dst, | ||
const float | val_src, | ||
const float | mix_factor | ||
) |
Definition at line 372 of file data_transfer.c.
References CDT_MIX_ADD, CDT_MIX_MIX, CDT_MIX_MUL, CDT_MIX_REPLACE_ABOVE_THRESHOLD, CDT_MIX_REPLACE_BELOW_THRESHOLD, CDT_MIX_SUB, CDT_MIX_TRANSFER, and interpf().
Referenced by data_transfer_interp_char(), and vgroups_datatransfer_interp().
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 | ||
) |
Definition at line 436 of file data_transfer.c.
References BLI_addtail(), BLI_assert, CustomDataTransferLayerMap::data_dst, CustomDataTransferLayerMap::data_dst_n, CustomDataTransferLayerMap::data_flag, CustomDataTransferLayerMap::data_offset, CustomDataTransferLayerMap::data_size, CustomDataTransferLayerMap::data_src, CustomDataTransferLayerMap::data_src_n, CustomDataTransferLayerMap::data_type, CustomDataTransferLayerMap::elem_size, interp(), CustomDataTransferLayerMap::interp, CustomDataTransferLayerMap::interp_data, MEM_mallocN, CustomDataTransferLayerMap::mix_factor, CustomDataTransferLayerMap::mix_mode, CustomDataTransferLayerMap::mix_weights, and NULL.
Referenced by data_transfer_layersmapping_add_item_cd(), data_transfer_layersmapping_generate(), data_transfer_layersmapping_vgroups(), and data_transfer_layersmapping_vgroups_multisrc_to_dst().
|
static |
Definition at line 477 of file data_transfer.c.
References CD_FREESTYLE_EDGE, CD_FREESTYLE_FACE, data_transfer_layersmapping_add_item(), FREESTYLE_EDGE_MARK, FREESTYLE_FACE_MARK, and interp().
Referenced by data_transfer_layersmapping_cdlayers(), and data_transfer_layersmapping_cdlayers_multisrc_to_dst().
|
static |
Definition at line 684 of file data_transfer.c.
References CD_CALLOC, CustomData_add_layer(), CustomData_add_layer_named(), CustomData_duplicate_referenced_layer(), CustomData_duplicate_referenced_layer_n(), CustomData_free_layer(), CustomData_get_active_layer(), CustomData_get_layer(), CustomData_get_layer_n(), CustomData_get_layer_name(), CustomData_get_named_layer(), CustomData_layertype_is_singleton(), CustomData_number_of_layers(), data_transfer_layersmapping_add_item_cd(), data_transfer_layersmapping_cdlayers_multisrc_to_dst(), DT_LAYERS_ACTIVE_DST, DT_LAYERS_ACTIVE_SRC, DT_LAYERS_ALL_SRC, DT_LAYERS_INDEX_DST, DT_LAYERS_NAME_DST, interp(), MEM_freeN, MEM_mallocN, NULL, and ret.
Referenced by data_transfer_layersmapping_generate().
|
static |
Definition at line 520 of file data_transfer.c.
References CD_CALLOC, CustomData_add_layer(), CustomData_add_layer_named(), CustomData_duplicate_referenced_layer_n(), CustomData_free_layer(), CustomData_get_layer_n(), CustomData_get_layer_name(), CustomData_get_named_layer(), CustomData_number_of_layers(), data_transfer_layersmapping_add_item_cd(), DT_LAYERS_INDEX_DST, DT_LAYERS_NAME_DST, interp(), MEM_freeN, MEM_mallocN, and NULL.
Referenced by data_transfer_layersmapping_cdlayers().
|
static |
Definition at line 885 of file data_transfer.c.
References CD_FAKE, CD_FAKE_BWEIGHT, CD_FAKE_CREASE, CD_FAKE_LNOR, CD_FAKE_MDEFORMVERT, CD_FAKE_SEAM, CD_FAKE_SHAPEKEY, CD_FAKE_SHARP, CD_FAKE_UV, Mesh::cd_flag, CD_MDEFORMVERT, CD_MLOOPUV, CD_NORMAL, customdata_data_transfer_interp_normal_normals(), CustomData_get_layer(), Object::data, data_transfer_interp_char(), data_transfer_layersmapping_add_item(), data_transfer_layersmapping_cdlayers(), data_transfer_layersmapping_vgroups(), Mesh::dvert, Mesh::edata, ELEM, interp(), Mesh::ldata, ME_CDFLAG_EDGE_BWEIGHT, ME_CDFLAG_EDGE_CREASE, ME_CDFLAG_VERT_BWEIGHT, ME_EDGE, ME_LOOP, ME_POLY, ME_SEAM, ME_SHARP, ME_SMOOTH, ME_VERT, Mesh::medge, Mesh::mpoly, Mesh::mvert, NULL, Mesh::pdata, ret, Mesh::totedge, Mesh::totpoly, Mesh::totvert, and Mesh::vdata.
Referenced by BKE_object_data_transfer_ex(), and BKE_object_data_transfer_layout().
|
static |
Definition at line 38 of file data_transfer.c.
Referenced by BKE_object_data_transfer_ex().