parent
6dc7cefb78
commit
fd51d5d412
Notes:
blender-bot
2023-02-14 10:37:49 +01:00
Referenced by issue #64320, Joining objects with facemaps
|
@ -40,6 +40,11 @@ void BKE_object_facemap_unique_name(struct Object *ob, struct bFaceMap *fmap);
|
|||
struct bFaceMap *BKE_object_facemap_find_name(struct Object *ob, const char *name);
|
||||
void BKE_object_facemap_copy_list(struct ListBase *outbase, const struct ListBase *inbase);
|
||||
|
||||
int *BKE_object_facemap_index_map_create(struct Object *ob_src,
|
||||
struct Object *ob_dst,
|
||||
int *r_map_len);
|
||||
void BKE_object_facemap_index_map_apply(int *fmap, int fmap_len, const int *map, int map_len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -261,3 +261,41 @@ bFaceMap *BKE_object_facemap_find_name(Object *ob, const char *name)
|
|||
{
|
||||
return BLI_findstring(&ob->fmaps, name, offsetof(bFaceMap, name));
|
||||
}
|
||||
|
||||
int *BKE_object_facemap_index_map_create(Object *ob_src, Object *ob_dst, int *r_map_len)
|
||||
{
|
||||
/* Build src to merged mapping of facemap indices. */
|
||||
if (BLI_listbase_is_empty(&ob_src->fmaps) || BLI_listbase_is_empty(&ob_dst->fmaps)) {
|
||||
*r_map_len = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*r_map_len = BLI_listbase_count(&ob_src->fmaps);
|
||||
int *fmap_index_map = MEM_malloc_arrayN(
|
||||
*r_map_len, sizeof(*fmap_index_map), "defgroup index map create");
|
||||
bool is_fmap_remap_needed = false;
|
||||
|
||||
int i = 0;
|
||||
for (bFaceMap *fmap_src = ob_src->fmaps.first; fmap_src; fmap_src = fmap_src->next, i++) {
|
||||
fmap_index_map[i] = BKE_object_facemap_name_index(ob_dst, fmap_src->name);
|
||||
is_fmap_remap_needed = is_fmap_remap_needed || (fmap_index_map[i] != i);
|
||||
}
|
||||
|
||||
if (!is_fmap_remap_needed) {
|
||||
MEM_freeN(fmap_index_map);
|
||||
fmap_index_map = NULL;
|
||||
*r_map_len = 0;
|
||||
}
|
||||
|
||||
return fmap_index_map;
|
||||
}
|
||||
|
||||
void BKE_object_facemap_index_map_apply(int *fmap, int fmap_len, const int *map, int map_len)
|
||||
{
|
||||
if (map == NULL || map_len == 0) {
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < fmap_len; i++, fmap++) {
|
||||
*fmap = (*fmap < map_len && *fmap != -1) ? map[*fmap] : -1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
#include "BKE_multires.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_object_deform.h"
|
||||
#include "BKE_object_facemap.h"
|
||||
#include "BKE_report.h"
|
||||
|
||||
#include "DEG_depsgraph.h"
|
||||
|
@ -267,6 +268,22 @@ static void join_mesh_single(Depsgraph *depsgraph,
|
|||
mpoly->loopstart += *loopofs;
|
||||
mpoly->mat_nr = matmap ? matmap[mpoly->mat_nr] : 0;
|
||||
}
|
||||
|
||||
/* Face maps. */
|
||||
int *fmap = CustomData_get(pdata, *polyofs, CD_FACEMAP);
|
||||
int *fmap_src = CustomData_get(&me->pdata, 0, CD_FACEMAP);
|
||||
|
||||
/* Remap to correct new face-map indices, if needed. */
|
||||
if (fmap_src) {
|
||||
BLI_assert(fmap != NULL);
|
||||
int *fmap_index_map;
|
||||
int fmap_index_map_len;
|
||||
fmap_index_map = BKE_object_facemap_index_map_create(ob_src, ob_dst, &fmap_index_map_len);
|
||||
BKE_object_facemap_index_map_apply(fmap, me->totpoly, fmap_index_map, fmap_index_map_len);
|
||||
if (fmap_index_map != NULL) {
|
||||
MEM_freeN(fmap_index_map);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* these are used for relinking (cannot be set earlier, or else reattaching goes wrong) */
|
||||
|
@ -403,7 +420,7 @@ int join_mesh_exec(bContext *C, wmOperator *op)
|
|||
key->type = KEY_RELATIVE;
|
||||
}
|
||||
|
||||
/* first pass over objects - copying materials and vertexgroups across */
|
||||
/* First pass over objects: Copying materials, vertex-groups & face-maps across. */
|
||||
CTX_DATA_BEGIN (C, Object *, ob_iter, selected_editable_objects) {
|
||||
/* only act if a mesh, and not the one we're joining to */
|
||||
if ((ob != ob_iter) && (ob_iter->type == OB_MESH)) {
|
||||
|
@ -422,6 +439,19 @@ int join_mesh_exec(bContext *C, wmOperator *op)
|
|||
ob->actdef = 1;
|
||||
}
|
||||
|
||||
/* Join this object's face maps to the base one's. */
|
||||
for (bFaceMap *fmap = ob_iter->fmaps.first; fmap; fmap = fmap->next) {
|
||||
/* See if this group exists in the object (if it doesn't, add it to the end) */
|
||||
if (BKE_object_facemap_find_name(ob, fmap->name) == NULL) {
|
||||
bFaceMap *fmap_new = MEM_callocN(sizeof(bFaceMap), "join faceMap");
|
||||
memcpy(fmap_new, fmap, sizeof(bFaceMap));
|
||||
BLI_addtail(&ob->fmaps, fmap_new);
|
||||
}
|
||||
}
|
||||
if (ob->fmaps.first && ob->actfmap == 0) {
|
||||
ob->actfmap = 1;
|
||||
}
|
||||
|
||||
if (me->totvert) {
|
||||
/* Add this object's materials to the base one's if they don't exist already
|
||||
* (but only if limits not exceeded yet) */
|
||||
|
|
Loading…
Reference in New Issue