Mesh: Remove face map list, convert to integer attribute

Face maps were added as a prototype of a new rigging solution during
2.8 development. Their storage is redundant with the newer generic
attribute system (specifically with integer face attributes), and
they were never used much. This commit removes the face map list
and converts the storage to an attribute with the name `face_maps`.
There is nowhere to store the face map names anymore, so those
are not kept.

It probably still makes sense to have a feature like mesh face gizmo
selection for rigging. But the design and implementation woulds likely
have to change significantly, including possibly changing the storage
type, and making use of the generic attribute system instead of a
special type.

See #105317 for more discussion.
This commit is contained in:
Hans Goudey 2023-06-09 13:54:52 +02:00 committed by Hans Goudey
parent 9f0efb6390
commit 46cf093270
34 changed files with 68 additions and 1739 deletions

View File

@ -109,15 +109,7 @@ class MESH_UL_vgroups(UIList):
layout.label(text="", icon_value=icon)
class MESH_UL_fmaps(UIList):
def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index):
# assert(isinstance(item, bpy.types.FaceMap))
fmap = item
if self.layout_type in {'DEFAULT', 'COMPACT'}:
layout.prop(fmap, "name", text="", emboss=False, icon='FACE_MAPS')
elif self.layout_type == 'GRID':
layout.alignment = 'CENTER'
layout.label(text="", icon_value=icon)
class MESH_UL_shape_keys(UIList):
@ -285,50 +277,6 @@ class DATA_PT_vertex_groups(MeshButtonsPanel, Panel):
layout.prop(context.tool_settings, "vertex_group_weight", text="Weight")
class DATA_PT_face_maps(MeshButtonsPanel, Panel):
bl_label = "Face Maps"
bl_options = {'DEFAULT_CLOSED'}
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'}
@classmethod
def poll(cls, context):
obj = context.object
return (obj and obj.type == 'MESH')
def draw(self, context):
layout = self.layout
ob = context.object
facemap = ob.face_maps.active
rows = 2
if facemap:
rows = 4
row = layout.row()
row.template_list("MESH_UL_fmaps", "", ob, "face_maps", ob.face_maps, "active_index", rows=rows)
col = row.column(align=True)
col.operator("object.face_map_add", icon='ADD', text="")
col.operator("object.face_map_remove", icon='REMOVE', text="")
if facemap:
col.separator()
col.operator("object.face_map_move", icon='TRIA_UP', text="").direction = 'UP'
col.operator("object.face_map_move", icon='TRIA_DOWN', text="").direction = 'DOWN'
if ob.face_maps and (ob.mode == 'EDIT' and ob.type == 'MESH'):
row = layout.row()
sub = row.row(align=True)
sub.operator("object.face_map_assign", text="Assign")
sub.operator("object.face_map_remove_from", text="Remove")
sub = row.row(align=True)
sub.operator("object.face_map_select", text="Select")
sub.operator("object.face_map_deselect", text="Deselect")
class DATA_PT_shape_keys(MeshButtonsPanel, Panel):
bl_label = "Shape Keys"
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH', 'BLENDER_WORKBENCH_NEXT'}
@ -717,7 +665,6 @@ classes = (
MESH_MT_color_attribute_context_menu,
MESH_MT_attribute_context_menu,
MESH_UL_vgroups,
MESH_UL_fmaps,
MESH_UL_shape_keys,
MESH_UL_uvmaps,
MESH_UL_attributes,
@ -726,7 +673,6 @@ classes = (
DATA_PT_shape_keys,
DATA_PT_uv_texture,
DATA_PT_vertex_colors,
DATA_PT_face_maps,
DATA_PT_mesh_attributes,
DATA_PT_normals,
DATA_PT_texture_space,

View File

@ -27,13 +27,13 @@ extern "C" {
/* Blender file format version. */
#define BLENDER_FILE_VERSION BLENDER_VERSION
#define BLENDER_FILE_SUBVERSION 5
#define BLENDER_FILE_SUBVERSION 6
/* Minimum Blender version that supports reading file written with the current
* version. Older Blender versions will test this and show a warning if the file
* was written with too new a version. */
#define BLENDER_FILE_MIN_VERSION 400
#define BLENDER_FILE_MIN_SUBVERSION 2
#define BLENDER_FILE_MIN_SUBVERSION 3
/** User readable version string. */
const char *BKE_blender_version_string(void);

View File

@ -180,8 +180,6 @@ struct Mesh *BKE_mesh_new_nomain_from_curve_displist(const struct Object *ob,
bool BKE_mesh_attribute_required(const char *name);
bool BKE_mesh_ensure_facemap_customdata(struct Mesh *me);
bool BKE_mesh_clear_facemap_customdata(struct Mesh *me);
float (*BKE_mesh_orco_verts_get(struct Object *ob))[3];
void BKE_mesh_orco_verts_transform(struct Mesh *me, float (*orco)[3], int totvert, int invert);

View File

@ -84,6 +84,8 @@ void BKE_mesh_legacy_convert_polys_to_offsets(Mesh *mesh);
void BKE_mesh_legacy_convert_loops_to_corners(struct Mesh *mesh);
void BKE_mesh_legacy_face_map_to_generic(struct Mesh *mesh);
#endif
#ifdef __cplusplus

View File

@ -1,37 +0,0 @@
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
/** \file
* \ingroup bke
* \brief Functions for dealing with object face-maps.
*/
#ifdef __cplusplus
extern "C" {
#endif
struct ListBase;
struct Object;
struct bFaceMap;
struct bFaceMap *BKE_object_facemap_add(struct Object *ob);
struct bFaceMap *BKE_object_facemap_add_name(struct Object *ob, const char *name);
void BKE_object_facemap_remove(struct Object *ob, struct bFaceMap *fmap);
void BKE_object_facemap_clear(struct Object *ob);
int BKE_object_facemap_name_index(struct Object *ob, const char *name);
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

View File

@ -241,7 +241,6 @@ set(SRC
intern/object.cc
intern/object_deform.c
intern/object_dupli.cc
intern/object_facemap.c
intern/object_update.cc
intern/ocean.c
intern/ocean_spectrum.c
@ -457,7 +456,6 @@ set(SRC
BKE_node_tree_zones.hh
BKE_object.h
BKE_object_deform.h
BKE_object_facemap.h
BKE_ocean.h
BKE_outliner_treehash.hh
BKE_packedFile.h

View File

@ -1257,20 +1257,6 @@ static void layerSwap_flnor(void *data, const int *corner_indices)
/** \} */
/* -------------------------------------------------------------------- */
/** \name Callbacks for (`int`, #CD_FACEMAP)
* \{ */
static void layerDefault_fmap(void *data, const int count)
{
int *fmap_num = (int *)data;
for (int i = 0; i < count; i++) {
fmap_num[i] = -1;
}
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Callbacks for (#MPropCol, #CD_PROP_COLOR)
* \{ */
@ -1628,8 +1614,8 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
nullptr,
nullptr,
layerCopyValue_normal},
/* 9: CD_FACEMAP */
{sizeof(int), "", 0, nullptr, nullptr, nullptr, nullptr, nullptr, layerDefault_fmap, nullptr},
/* 9: CD_FACEMAP */ /* DEPRECATED */
{sizeof(int), ""},
/* 10: CD_PROP_FLOAT */
{sizeof(MFloatProperty),
"MFloatProperty",
@ -1865,7 +1851,7 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
/* 41: CD_CUSTOMLOOPNORMAL */
{sizeof(short[2]), "vec2s", 1, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr},
/* 42: CD_SCULPT_FACE_SETS */ /* DEPRECATED */
{sizeof(int), "", 0, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr},
{sizeof(int), ""},
/* 43: CD_LOCATION */
{sizeof(float[3]), "vec3f", 1, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr},
/* 44: CD_RADIUS */
@ -2010,14 +1996,14 @@ const CustomData_MeshMasks CD_MASK_BAREMESH = {
/*vmask*/ CD_MASK_PROP_FLOAT3,
/*emask*/ CD_MASK_PROP_INT32_2D,
/*fmask*/ 0,
/*pmask*/ CD_MASK_FACEMAP,
/*pmask*/ 0,
/*lmask*/ CD_MASK_PROP_INT32,
};
const CustomData_MeshMasks CD_MASK_BAREMESH_ORIGINDEX = {
/*vmask*/ CD_MASK_PROP_FLOAT3 | CD_MASK_ORIGINDEX,
/*emask*/ CD_MASK_PROP_INT32_2D | CD_MASK_ORIGINDEX,
/*fmask*/ 0,
/*pmask*/ CD_MASK_FACEMAP | CD_MASK_ORIGINDEX,
/*pmask*/ CD_MASK_ORIGINDEX,
/*lmask*/ CD_MASK_PROP_INT32,
};
const CustomData_MeshMasks CD_MASK_MESH = {
@ -2027,7 +2013,7 @@ const CustomData_MeshMasks CD_MASK_MESH = {
(CD_MASK_FREESTYLE_EDGE | CD_MASK_PROP_ALL | CD_MASK_CREASE),
/*fmask*/ 0,
/*pmask*/
(CD_MASK_FACEMAP | CD_MASK_FREESTYLE_FACE | CD_MASK_PROP_ALL),
(CD_MASK_FREESTYLE_FACE | CD_MASK_PROP_ALL),
/*lmask*/
(CD_MASK_MDISPS | CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_GRID_PAINT_MASK | CD_MASK_PROP_ALL),
};
@ -2039,7 +2025,7 @@ const CustomData_MeshMasks CD_MASK_DERIVEDMESH = {
(CD_MASK_ORIGINDEX | CD_MASK_FREESTYLE_EDGE | CD_MASK_PROP_ALL | CD_MASK_CREASE),
/*fmask*/ (CD_MASK_ORIGINDEX | CD_MASK_ORIGSPACE | CD_MASK_PREVIEW_MCOL | CD_MASK_TANGENT),
/*pmask*/
(CD_MASK_ORIGINDEX | CD_MASK_FREESTYLE_FACE | CD_MASK_FACEMAP | CD_MASK_PROP_ALL),
(CD_MASK_ORIGINDEX | CD_MASK_FREESTYLE_FACE | CD_MASK_PROP_ALL),
/*lmask*/
(CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_PREVIEW_MLOOPCOL | CD_MASK_ORIGSPACE_MLOOP |
CD_MASK_PROP_ALL), /* XXX: MISSING #CD_MASK_MLOOPTANGENT ? */
@ -2050,7 +2036,7 @@ const CustomData_MeshMasks CD_MASK_BMESH = {
/*emask*/ (CD_MASK_CREASE | CD_MASK_FREESTYLE_EDGE | CD_MASK_PROP_ALL),
/*fmask*/ 0,
/*pmask*/
(CD_MASK_FREESTYLE_FACE | CD_MASK_FACEMAP | CD_MASK_PROP_ALL),
(CD_MASK_FREESTYLE_FACE | CD_MASK_PROP_ALL),
/*lmask*/
(CD_MASK_MDISPS | CD_MASK_CUSTOMLOOPNORMAL | CD_MASK_GRID_PAINT_MASK | CD_MASK_PROP_ALL),
};
@ -2066,8 +2052,7 @@ const CustomData_MeshMasks CD_MASK_EVERYTHING = {
CD_MASK_ORIGSPACE | CD_MASK_TANGENT | CD_MASK_TESSLOOPNORMAL | CD_MASK_PREVIEW_MCOL |
CD_MASK_PROP_ALL),
/*pmask*/
(CD_MASK_BM_ELEM_PYPTR | CD_MASK_ORIGINDEX | CD_MASK_FACEMAP | CD_MASK_FREESTYLE_FACE |
CD_MASK_PROP_ALL),
(CD_MASK_BM_ELEM_PYPTR | CD_MASK_ORIGINDEX | CD_MASK_FREESTYLE_FACE | CD_MASK_PROP_ALL),
/*lmask*/
(CD_MASK_BM_ELEM_PYPTR | CD_MASK_MDISPS | CD_MASK_NORMAL | CD_MASK_CUSTOMLOOPNORMAL |
CD_MASK_MLOOPTANGENT | CD_MASK_PREVIEW_MLOOPCOL | CD_MASK_ORIGSPACE_MLOOP |
@ -5169,9 +5154,6 @@ void CustomData_blend_write(BlendWriter *writer,
case CD_GRID_PAINT_MASK:
write_grid_paint_mask(writer, count, static_cast<const GridPaintMask *>(layer.data));
break;
case CD_FACEMAP:
BLO_write_raw(writer, sizeof(int) * count, static_cast<const int *>(layer.data));
break;
case CD_PROP_BOOL:
BLO_write_raw(writer, sizeof(bool) * count, static_cast<const bool *>(layer.data));
break;

View File

@ -808,44 +808,6 @@ void BKE_mesh_ensure_skin_customdata(Mesh *me)
}
}
bool BKE_mesh_ensure_facemap_customdata(Mesh *me)
{
BMesh *bm = me->edit_mesh ? me->edit_mesh->bm : nullptr;
bool changed = false;
if (bm) {
if (!CustomData_has_layer(&bm->pdata, CD_FACEMAP)) {
BM_data_layer_add(bm, &bm->pdata, CD_FACEMAP);
changed = true;
}
}
else {
if (!CustomData_has_layer(&me->pdata, CD_FACEMAP)) {
CustomData_add_layer(&me->pdata, CD_FACEMAP, CD_SET_DEFAULT, me->totpoly);
changed = true;
}
}
return changed;
}
bool BKE_mesh_clear_facemap_customdata(Mesh *me)
{
BMesh *bm = me->edit_mesh ? me->edit_mesh->bm : nullptr;
bool changed = false;
if (bm) {
if (CustomData_has_layer(&bm->pdata, CD_FACEMAP)) {
BM_data_layer_free(bm, &bm->pdata, CD_FACEMAP);
changed = true;
}
}
else {
if (CustomData_has_layer(&me->pdata, CD_FACEMAP)) {
CustomData_free_layers(&me->pdata, CD_FACEMAP, me->totpoly);
changed = true;
}
}
return changed;
}
bool BKE_mesh_has_custom_loop_normals(Mesh *me)
{
if (me->edit_mesh) {

View File

@ -1305,6 +1305,40 @@ void BKE_mesh_legacy_face_set_to_generic(Mesh *mesh)
/** \} */
/* -------------------------------------------------------------------- */
/** \name Face Map Conversion
* \{ */
void BKE_mesh_legacy_face_map_to_generic(Mesh *mesh)
{
using namespace blender;
if (mesh->attributes().contains("face_maps")) {
return;
}
void *data = nullptr;
const ImplicitSharingInfo *sharing_info = nullptr;
for (const int i : IndexRange(mesh->pdata.totlayer)) {
CustomDataLayer &layer = mesh->pdata.layers[i];
if (layer.type == CD_FACEMAP) {
data = layer.data;
sharing_info = layer.sharing_info;
layer.data = nullptr;
layer.sharing_info = nullptr;
CustomData_free_layer(&mesh->pdata, CD_FACEMAP, mesh->totpoly, i);
break;
}
}
if (data != nullptr) {
CustomData_add_layer_named_with_data(
&mesh->pdata, CD_PROP_INT32, data, mesh->totpoly, "face_maps", sharing_info);
}
if (sharing_info != nullptr) {
sharing_info->remove_user_and_delete_if_last();
}
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Bevel Weight Conversion
* \{ */

View File

@ -114,7 +114,6 @@
#include "BKE_multires.h"
#include "BKE_node.hh"
#include "BKE_object.h"
#include "BKE_object_facemap.h"
#include "BKE_paint.h"
#include "BKE_particle.h"
#include "BKE_pbvh.h"
@ -233,7 +232,6 @@ static void object_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const in
}
}
BKE_object_facemap_copy_list(&ob_dst->fmaps, &ob_src->fmaps);
BKE_constraints_copy_ex(&ob_dst->constraints, &ob_src->constraints, flag_subdata, true);
ob_dst->mode = ob_dst->type != OB_GPENCIL_LEGACY ? OB_MODE_OBJECT : ob_dst->mode;
@ -302,7 +300,6 @@ static void object_free_data(ID *id)
MEM_SAFE_FREE(ob->iuser);
MEM_SAFE_FREE(ob->runtime.bb);
BLI_freelistN(&ob->fmaps);
if (ob->pose) {
BKE_pose_free_ex(ob->pose, false);
ob->pose = nullptr;
@ -546,13 +543,6 @@ static void object_foreach_path(ID *id, BPathForeachPathData *bpath_data)
}
}
static void write_fmaps(BlendWriter *writer, ListBase *fbase)
{
LISTBASE_FOREACH (bFaceMap *, fmap, fbase) {
BLO_write_struct(writer, bFaceMap, fmap);
}
}
static void object_blend_write(BlendWriter *writer, ID *id, const void *id_address)
{
Object *ob = (Object *)id;
@ -586,7 +576,6 @@ static void object_blend_write(BlendWriter *writer, ID *id, const void *id_addre
}
BKE_pose_blend_write(writer, ob->pose, arm);
write_fmaps(writer, &ob->fmaps);
BKE_constraint_blend_write(writer, &ob->constraints);
animviz_motionpath_blend_write(writer, ob->mpath);
@ -682,7 +671,6 @@ static void object_blend_read_data(BlendDataReader *reader, ID *id)
/* Only for versioning, vertex group names are now stored on object data. */
BLO_read_list(reader, &ob->defbase);
BLO_read_list(reader, &ob->fmaps);
/* XXX deprecated - old animation system <<< */
direct_link_nlastrips(reader, &ob->nlastrips);
BLO_read_list(reader, &ob->constraintChannels);

View File

@ -1,286 +0,0 @@
/* SPDX-FileCopyrightText: 2008 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup bke
*/
#include <string.h>
#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
#include "BLI_listbase.h"
#include "BLI_string.h"
#include "BLI_string_utils.h"
#include "BLI_utildefines.h"
#include "BKE_customdata.h"
#include "BKE_editmesh.h"
#include "BKE_object.h"
#include "BKE_object_deform.h"
#include "BKE_object_facemap.h" /* own include */
#include "BLT_translation.h"
#include "MEM_guardedalloc.h"
#include "RNA_access.h"
#include "RNA_define.h"
static bool fmap_unique_check(void *arg, const char *name)
{
struct {
Object *ob;
void *fm;
} *data = arg;
bFaceMap *fmap;
for (fmap = data->ob->fmaps.first; fmap; fmap = fmap->next) {
if (data->fm != fmap) {
if (STREQ(fmap->name, name)) {
return true;
}
}
}
return false;
}
static bFaceMap *fmap_duplicate(bFaceMap *infmap)
{
bFaceMap *outfmap;
if (!infmap) {
return NULL;
}
outfmap = MEM_callocN(sizeof(bFaceMap), "copy facemap");
/* For now, just copy everything over. */
memcpy(outfmap, infmap, sizeof(bFaceMap));
outfmap->next = outfmap->prev = NULL;
return outfmap;
}
void BKE_object_facemap_copy_list(ListBase *outbase, const ListBase *inbase)
{
bFaceMap *fmap, *fmapn;
BLI_listbase_clear(outbase);
for (fmap = inbase->first; fmap; fmap = fmap->next) {
fmapn = fmap_duplicate(fmap);
BLI_addtail(outbase, fmapn);
}
}
void BKE_object_facemap_unique_name(Object *ob, bFaceMap *fmap)
{
struct {
Object *ob;
void *fmap;
} data;
data.ob = ob;
data.fmap = fmap;
BLI_uniquename_cb(fmap_unique_check, &data, DATA_("Group"), '.', fmap->name, sizeof(fmap->name));
}
bFaceMap *BKE_object_facemap_add_name(Object *ob, const char *name)
{
bFaceMap *fmap;
if (!ob || ob->type != OB_MESH) {
return NULL;
}
fmap = MEM_callocN(sizeof(bFaceMap), __func__);
STRNCPY(fmap->name, name);
BLI_addtail(&ob->fmaps, fmap);
ob->actfmap = BLI_listbase_count(&ob->fmaps);
BKE_object_facemap_unique_name(ob, fmap);
return fmap;
}
bFaceMap *BKE_object_facemap_add(Object *ob)
{
return BKE_object_facemap_add_name(ob, DATA_("FaceMap"));
}
static void object_fmap_remove_edit_mode(Object *ob, bFaceMap *fmap, bool do_selected, bool purge)
{
const int fmap_nr = BLI_findindex(&ob->fmaps, fmap);
if (ob->type == OB_MESH) {
Mesh *me = ob->data;
if (me->edit_mesh) {
BMEditMesh *em = me->edit_mesh;
const int cd_fmap_offset = CustomData_get_offset(&em->bm->pdata, CD_FACEMAP);
if (cd_fmap_offset != -1) {
BMFace *efa;
BMIter iter;
int *map;
if (purge) {
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
map = BM_ELEM_CD_GET_VOID_P(efa, cd_fmap_offset);
if (map) {
if (*map == fmap_nr) {
*map = -1;
}
else if (*map > fmap_nr) {
*map -= 1;
}
}
}
}
else {
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
map = BM_ELEM_CD_GET_VOID_P(efa, cd_fmap_offset);
if (map && *map == fmap_nr && (!do_selected || BM_elem_flag_test(efa, BM_ELEM_SELECT)))
{
*map = -1;
}
}
}
}
if (ob->actfmap == BLI_listbase_count(&ob->fmaps)) {
ob->actfmap--;
}
BLI_remlink(&ob->fmaps, fmap);
MEM_freeN(fmap);
}
}
}
static void object_fmap_remove_object_mode(Object *ob, bFaceMap *fmap, bool purge)
{
const int fmap_nr = BLI_findindex(&ob->fmaps, fmap);
if (ob->type == OB_MESH) {
Mesh *me = ob->data;
if (CustomData_has_layer(&me->pdata, CD_FACEMAP)) {
int *map = CustomData_get_layer_for_write(&me->pdata, CD_FACEMAP, me->totpoly);
int i;
if (map) {
for (i = 0; i < me->totpoly; i++) {
if (map[i] == fmap_nr) {
map[i] = -1;
}
else if (purge && map[i] > fmap_nr) {
map[i]--;
}
}
}
}
if (ob->actfmap == BLI_listbase_count(&ob->fmaps)) {
ob->actfmap--;
}
BLI_remlink(&ob->fmaps, fmap);
MEM_freeN(fmap);
}
}
static void fmap_remove_exec(Object *ob, bFaceMap *fmap, const bool is_edit_mode, const bool purge)
{
if (is_edit_mode) {
object_fmap_remove_edit_mode(ob, fmap, false, purge);
}
else {
object_fmap_remove_object_mode(ob, fmap, purge);
}
}
void BKE_object_facemap_remove(Object *ob, bFaceMap *fmap)
{
fmap_remove_exec(ob, fmap, BKE_object_is_in_editmode(ob), true);
}
void BKE_object_facemap_clear(Object *ob)
{
bFaceMap *fmap = (bFaceMap *)ob->fmaps.first;
if (fmap) {
const bool edit_mode = BKE_object_is_in_editmode_vgroup(ob);
while (fmap) {
bFaceMap *next_fmap = fmap->next;
fmap_remove_exec(ob, fmap, edit_mode, false);
fmap = next_fmap;
}
}
/* remove all face-maps */
if (ob->type == OB_MESH) {
Mesh *me = ob->data;
CustomData_free_layer(&me->pdata, CD_FACEMAP, me->totpoly, 0);
}
ob->actfmap = 0;
}
int BKE_object_facemap_name_index(Object *ob, const char *name)
{
return (name) ? BLI_findstringindex(&ob->fmaps, name, offsetof(bFaceMap, name)) : -1;
}
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;
}
}

View File

@ -1569,7 +1569,6 @@ static void set_ccgdm_all_geometry(CCGDerivedMesh *ccgdm,
loopindex2);
loopindex2++;
/* Copy over poly data, e.g. #CD_FACEMAP. */
CustomData_copy_data(&dm->polyData, &ccgdm->dm.polyData, origIndex, faceNum, 1);
if (polyOrigIndex) {

View File

@ -190,6 +190,17 @@ void blo_do_versions_400(FileData * /*fd*/, Library * /*lib*/, Main *bmain)
}
}
if (!MAIN_VERSION_ATLEAST(bmain, 400, 6)) {
LISTBASE_FOREACH (Mesh *, mesh, &bmain->meshes) {
BKE_mesh_legacy_face_map_to_generic(mesh);
FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
versioning_replace_legacy_glossy_node(ntree);
versioning_remove_microfacet_sharp_distribution(ntree);
}
FOREACH_NODETREE_END;
}
}
/**
* Versioning code until next subversion bump goes here.
*
@ -204,11 +215,6 @@ void blo_do_versions_400(FileData * /*fd*/, Library * /*lib*/, Main *bmain)
*/
{
/* Convert anisotropic BSDF node to glossy BSDF. */
FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
versioning_replace_legacy_glossy_node(ntree);
versioning_remove_microfacet_sharp_distribution(ntree);
}
FOREACH_NODETREE_END;
/* Keep this block, even when empty. */
}

View File

@ -62,7 +62,6 @@ enum {
SIMFACE_NORMAL,
SIMFACE_COPLANAR,
SIMFACE_SMOOTH,
SIMFACE_FACEMAP,
SIMFACE_FREESTYLE,
};

View File

@ -99,28 +99,3 @@ void ED_gizmo_draw_preset_circle(const struct wmGizmo *gz,
single_axis_convert(OB_POSZ, mat, axis, mat_rotate);
ed_gizmo_draw_preset_geometry(gz, mat_rotate, select_id, &wm_gizmo_geom_data_dial);
}
void ED_gizmo_draw_preset_facemap(
const bContext *C, const struct wmGizmo *gz, Object *ob, const int facemap, int select_id)
{
/* Dependency graph is supposed to be evaluated prior to draw. */
Depsgraph *depsgraph = CTX_data_expect_evaluated_depsgraph(C);
const bool is_select = (select_id != -1);
const bool is_highlight = is_select && (gz->state & WM_GIZMO_STATE_HIGHLIGHT) != 0;
float color[4];
gizmo_color_get(gz, is_highlight, color);
if (is_select) {
GPU_select_load_id(select_id);
}
GPU_matrix_push();
GPU_matrix_mul(ob->object_to_world);
ED_draw_object_facemap(depsgraph, ob, color, facemap);
GPU_matrix_pop();
if (is_select) {
GPU_select_load_id(-1);
}
}

View File

@ -52,11 +52,6 @@ void ED_gizmo_draw_preset_circle(const struct wmGizmo *gz,
float mat[4][4],
int axis,
int select_id);
void ED_gizmo_draw_preset_facemap(const struct bContext *C,
const struct wmGizmo *gz,
struct Object *ob,
int facemap,
int select_id);
/* -------------------------------------------------------------------- */
/* 3D Arrow Gizmo */

View File

@ -34,7 +34,6 @@ struct ViewLayer;
struct XFormObjectData;
struct bConstraint;
struct bContext;
struct bFaceMap;
struct bPoseChannel;
struct uiLayout;
struct wmKeyConfig;
@ -729,17 +728,6 @@ bool ED_object_jump_to_bone(struct bContext *C,
const char *bone_name,
bool reveal_hidden);
/* object_facemap_ops.c */
/**
* Called while not in edit-mode.
*/
void ED_object_facemap_face_add(struct Object *ob, struct bFaceMap *fmap, int facenum);
/**
* Called while not in edit-mode.
*/
void ED_object_facemap_face_remove(struct Object *ob, struct bFaceMap *fmap, int facenum);
/* object_data_transform.cc */
struct XFormObjectData *ED_object_data_xform_create_ex(struct ID *id, bool is_edit_mode);

View File

@ -1056,10 +1056,6 @@ void ED_view3d_check_mats_rv3d(struct RegionView3D *rv3d);
struct RV3DMatrixStore *ED_view3d_mats_rv3d_backup(struct RegionView3D *rv3d);
void ED_view3d_mats_rv3d_restore(struct RegionView3D *rv3d, struct RV3DMatrixStore *rv3dmat);
void ED_draw_object_facemap(struct Depsgraph *depsgraph,
struct Object *ob,
const float col[4],
int facemap);
struct RenderEngineType *ED_view3d_engine_type(const struct Scene *scene, int drawtype);

View File

@ -2221,23 +2221,6 @@ bool EDBM_select_pick(bContext *C, const int mval[2], const SelectPick_Params *p
vc.em->mat_nr = efa->mat_nr;
WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_LINKS, nullptr);
}
/* Change active face-map on object. */
if (!BLI_listbase_is_empty(&vc.obedit->fmaps)) {
const int cd_fmap_offset = CustomData_get_offset(&vc.em->bm->pdata, CD_FACEMAP);
if (cd_fmap_offset != -1) {
int map = *((int *)BM_ELEM_CD_GET_VOID_P(efa, cd_fmap_offset));
if ((map < -1) || (map > BLI_listbase_count_at_most(&vc.obedit->fmaps, map))) {
map = -1;
}
map += 1;
if (map != vc.obedit->actfmap) {
/* We may want to add notifiers later,
* currently select update handles redraw. */
vc.obedit->actfmap = map;
}
}
}
}
/* Changing active object is handy since it allows us to

View File

@ -76,7 +76,6 @@ static const EnumPropertyItem prop_similar_types[] = {
{SIMFACE_NORMAL, "NORMAL", 0, "Normal", ""},
{SIMFACE_COPLANAR, "COPLANAR", 0, "Coplanar", ""},
{SIMFACE_SMOOTH, "SMOOTH", 0, "Flat/Smooth", ""},
{SIMFACE_FACEMAP, "FACE_MAP", 0, "Face Map", ""},
#ifdef WITH_FREESTYLE
{SIMFACE_FREESTYLE, "FREESTYLE_FACE", 0, "Freestyle Face Marks", ""},
#endif
@ -177,7 +176,6 @@ static int similar_face_select_exec(bContext *C, wmOperator *op)
KDTree_3d *tree_3d = NULL;
KDTree_4d *tree_4d = NULL;
GSet *gset = NULL;
GSet **gset_array = NULL;
int face_data_value = SIMFACE_DATA_NONE;
switch (type) {
@ -195,10 +193,6 @@ static int similar_face_select_exec(bContext *C, wmOperator *op)
case SIMFACE_MATERIAL:
gset = BLI_gset_ptr_new("Select similar face");
break;
case SIMFACE_FACEMAP:
gset_array = MEM_callocN(sizeof(GSet *) * objects_len,
"Select similar face: facemap gset array");
break;
}
int tree_index = 0;
@ -232,13 +226,6 @@ static int similar_face_select_exec(bContext *C, wmOperator *op)
}
break;
}
case SIMFACE_FACEMAP: {
custom_data_offset = CustomData_get_offset(&bm->pdata, CD_FACEMAP);
if (custom_data_offset == -1) {
continue;
}
gset_array[ob_index] = BLI_gset_ptr_new("Select similar face: facemap gset");
}
}
BMFace *face; /* Mesh face. */
@ -301,12 +288,6 @@ static int similar_face_select_exec(bContext *C, wmOperator *op)
}
break;
}
case SIMFACE_FACEMAP: {
BLI_assert(custom_data_offset != -1);
int *face_map = BM_ELEM_CD_GET_VOID_P(face, custom_data_offset);
BLI_gset_add(gset_array[ob_index], face_map);
break;
}
}
}
}
@ -354,12 +335,6 @@ static int similar_face_select_exec(bContext *C, wmOperator *op)
}
break;
}
case SIMFACE_FACEMAP: {
custom_data_offset = CustomData_get_offset(&bm->pdata, CD_FACEMAP);
if (custom_data_offset == -1) {
continue;
}
}
}
BMFace *face; /* Mesh face. */
@ -467,18 +442,6 @@ static int similar_face_select_exec(bContext *C, wmOperator *op)
}
break;
}
case SIMFACE_FACEMAP: {
const int *face_map = BM_ELEM_CD_GET_VOID_P(face, custom_data_offset);
GSetIterator gs_iter;
GSET_ITER (gs_iter, gset_array[ob_index]) {
const int *face_map_iter = BLI_gsetIterator_getKey(&gs_iter);
if (*face_map == *face_map_iter) {
select = true;
break;
}
}
break;
}
}
if (select) {
@ -533,14 +496,6 @@ static int similar_face_select_exec(bContext *C, wmOperator *op)
if (gset != NULL) {
BLI_gset_free(gset, NULL);
}
if (gset_array != NULL) {
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
if (gset_array[ob_index] != NULL) {
BLI_gset_free(gset_array[ob_index], NULL);
}
}
MEM_freeN(gset_array);
}
return OPERATOR_FINISHED;
}
@ -1376,7 +1331,7 @@ static const EnumPropertyItem *select_similar_type_itemf(bContext *C,
#ifdef WITH_FREESTYLE
const int a_end = SIMFACE_FREESTYLE;
#else
const int a_end = SIMFACE_FACEMAP;
const int a_end = SIMFACE_MATERIAL;
#endif
for (a = SIMFACE_MATERIAL; a <= a_end; a++) {
RNA_enum_items_add_value(&item, &totitem, prop_similar_types, a);

View File

@ -40,7 +40,6 @@
#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"
@ -273,23 +272,6 @@ static void join_mesh_single(Depsgraph *depsgraph,
for (const int i : blender::IndexRange(me->totpoly)) {
poly_offsets[i] = src_poly_offsets[i] + *loopofs;
}
/* Face maps. */
int *fmap = (int *)CustomData_get_for_write(pdata, *polyofs, CD_FACEMAP, totpoly);
const int *fmap_src = (const int *)CustomData_get_for_write(
&me->pdata, 0, CD_FACEMAP, me->totpoly);
/* Remap to correct new face-map indices, if needed. */
if (fmap_src) {
BLI_assert(fmap != nullptr);
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 != nullptr) {
MEM_freeN(fmap_index_map);
}
}
}
/* these are used for relinking (cannot be set earlier, or else reattaching goes wrong) */
@ -483,19 +465,6 @@ int ED_mesh_join_objects_exec(bContext *C, wmOperator *op)
me->vertex_group_active_index = 1;
}
/* Join this object's face maps to the base one's. */
LISTBASE_FOREACH (bFaceMap *, fmap, &ob_iter->fmaps) {
/* 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) == nullptr) {
bFaceMap *fmap_new = static_cast<bFaceMap *>(MEM_mallocN(sizeof(bFaceMap), __func__));
memcpy(fmap_new, fmap, sizeof(bFaceMap));
BLI_addtail(&ob->fmaps, fmap_new);
}
}
if (ob->fmaps.first && ob->actfmap == 0) {
ob->actfmap = 1;
}
mesh_join_offset_face_sets_ID(me, &face_set_id_offset);
if (me->totvert) {

View File

@ -44,7 +44,6 @@ set(SRC
object_data_transfer.c
object_data_transform.cc
object_edit.cc
object_facemap_ops.c
object_gpencil_modifier.c
object_hook.c
object_light_linking_ops.cc

View File

@ -1,493 +0,0 @@
/* SPDX-FileCopyrightText: 2008 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup edobj
*/
#include <string.h>
#include "MEM_guardedalloc.h"
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
#include "DNA_workspace_types.h"
#include "BKE_context.h"
#include "BKE_customdata.h"
#include "BKE_editmesh.h"
#include "BKE_object.h"
#include "BKE_object_deform.h"
#include "BKE_object_facemap.h"
#include "DEG_depsgraph.h"
#include "RNA_access.h"
#include "RNA_define.h"
#include "WM_api.h"
#include "WM_types.h"
#include "ED_mesh.h"
#include "ED_object.h"
#include "object_intern.h"
void ED_object_facemap_face_add(Object *ob, bFaceMap *fmap, int facenum)
{
int fmap_nr;
if (GS(((ID *)ob->data)->name) != ID_ME) {
return;
}
/* get the face map number, exit if it can't be found */
fmap_nr = BLI_findindex(&ob->fmaps, fmap);
if (fmap_nr != -1) {
int *facemap;
Mesh *me = ob->data;
/* if there's is no facemap layer then create one */
if ((facemap = CustomData_get_layer_for_write(&me->pdata, CD_FACEMAP, me->totpoly)) == NULL) {
facemap = CustomData_add_layer(&me->pdata, CD_FACEMAP, CD_SET_DEFAULT, me->totpoly);
}
facemap[facenum] = fmap_nr;
}
}
void ED_object_facemap_face_remove(Object *ob, bFaceMap *fmap, int facenum)
{
int fmap_nr;
if (GS(((ID *)ob->data)->name) != ID_ME) {
return;
}
/* get the face map number, exit if it can't be found */
fmap_nr = BLI_findindex(&ob->fmaps, fmap);
if (fmap_nr != -1) {
int *facemap;
Mesh *me = ob->data;
if ((facemap = CustomData_get_layer_for_write(&me->pdata, CD_FACEMAP, me->totpoly)) == NULL) {
return;
}
facemap[facenum] = -1;
}
}
static void object_fmap_remap_edit_mode(Object *ob, const int *remap)
{
if (ob->type != OB_MESH) {
return;
}
Mesh *me = ob->data;
if (me->edit_mesh) {
BMEditMesh *em = me->edit_mesh;
const int cd_fmap_offset = CustomData_get_offset(&em->bm->pdata, CD_FACEMAP);
if (cd_fmap_offset != -1) {
BMFace *efa;
BMIter iter;
int *map;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
map = BM_ELEM_CD_GET_VOID_P(efa, cd_fmap_offset);
if (map && *map != -1) {
*map = remap[*map];
}
}
}
}
}
static void object_fmap_remap_object_mode(Object *ob, const int *remap)
{
if (ob->type != OB_MESH) {
return;
}
Mesh *me = ob->data;
if (CustomData_has_layer(&me->pdata, CD_FACEMAP)) {
int *map = CustomData_get_layer_for_write(&me->pdata, CD_FACEMAP, me->totpoly);
if (map) {
for (int i = 0; i < me->totpoly; i++) {
if (map[i] != -1) {
map[i] = remap[map[i]];
}
}
}
}
}
static void object_facemap_remap(Object *ob, const int *remap)
{
if (BKE_object_is_in_editmode(ob)) {
object_fmap_remap_edit_mode(ob, remap);
}
else {
object_fmap_remap_object_mode(ob, remap);
}
}
static bool face_map_supported_poll(bContext *C)
{
Object *ob = ED_object_context(C);
ID *data = (ob) ? ob->data : NULL;
return (ob && !ID_IS_LINKED(ob) && !ID_IS_OVERRIDE_LIBRARY(ob) && ob->type == OB_MESH && data &&
!ID_IS_LINKED(data) && !ID_IS_OVERRIDE_LIBRARY(data));
}
static bool face_map_supported_edit_mode_poll(bContext *C)
{
Object *ob = ED_object_context(C);
if (face_map_supported_poll(C)) {
if (ob->mode == OB_MODE_EDIT) {
return true;
}
}
return false;
}
static bool face_map_supported_remove_poll(bContext *C)
{
if (!face_map_supported_poll(C)) {
return false;
}
Object *ob = ED_object_context(C);
bFaceMap *fmap = BLI_findlink(&ob->fmaps, ob->actfmap - 1);
if (fmap) {
return true;
}
return false;
}
static int face_map_add_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *ob = ED_object_context(C);
BKE_object_facemap_add(ob);
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
return OPERATOR_FINISHED;
}
void OBJECT_OT_face_map_add(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Add Face Map";
ot->idname = "OBJECT_OT_face_map_add";
ot->description = "Add a new face map to the active object";
/* api callbacks */
ot->poll = face_map_supported_poll;
ot->exec = face_map_add_exec;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
static int face_map_remove_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *ob = ED_object_context(C);
bFaceMap *fmap = BLI_findlink(&ob->fmaps, ob->actfmap - 1);
if (fmap) {
BKE_object_facemap_remove(ob, fmap);
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
}
return OPERATOR_FINISHED;
}
void OBJECT_OT_face_map_remove(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Remove Face Map";
ot->idname = "OBJECT_OT_face_map_remove";
ot->description = "Remove a face map from the active object";
/* api callbacks */
ot->poll = face_map_supported_remove_poll;
ot->exec = face_map_remove_exec;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
static int face_map_assign_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *ob = ED_object_context(C);
bFaceMap *fmap = BLI_findlink(&ob->fmaps, ob->actfmap - 1);
if (fmap) {
Mesh *me = ob->data;
BMEditMesh *em = me->edit_mesh;
BMFace *efa;
BMIter iter;
int *map;
int cd_fmap_offset;
if (!CustomData_has_layer(&em->bm->pdata, CD_FACEMAP)) {
BM_data_layer_add(em->bm, &em->bm->pdata, CD_FACEMAP);
}
cd_fmap_offset = CustomData_get_offset(&em->bm->pdata, CD_FACEMAP);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
map = BM_ELEM_CD_GET_VOID_P(efa, cd_fmap_offset);
if (BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
*map = ob->actfmap - 1;
}
}
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
}
return OPERATOR_FINISHED;
}
void OBJECT_OT_face_map_assign(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Assign Face Map";
ot->idname = "OBJECT_OT_face_map_assign";
ot->description = "Assign faces to a face map";
/* api callbacks */
ot->poll = face_map_supported_edit_mode_poll;
ot->exec = face_map_assign_exec;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
static int face_map_remove_from_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *ob = ED_object_context(C);
bFaceMap *fmap = BLI_findlink(&ob->fmaps, ob->actfmap - 1);
if (fmap) {
Mesh *me = ob->data;
BMEditMesh *em = me->edit_mesh;
BMFace *efa;
BMIter iter;
int *map;
int cd_fmap_offset;
int mapindex = ob->actfmap - 1;
if (!CustomData_has_layer(&em->bm->pdata, CD_FACEMAP)) {
return OPERATOR_CANCELLED;
}
cd_fmap_offset = CustomData_get_offset(&em->bm->pdata, CD_FACEMAP);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
map = BM_ELEM_CD_GET_VOID_P(efa, cd_fmap_offset);
if (BM_elem_flag_test(efa, BM_ELEM_SELECT) && *map == mapindex) {
*map = -1;
}
}
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
}
return OPERATOR_FINISHED;
}
void OBJECT_OT_face_map_remove_from(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Remove from Face Map";
ot->idname = "OBJECT_OT_face_map_remove_from";
ot->description = "Remove faces from a face map";
/* api callbacks */
ot->poll = face_map_supported_edit_mode_poll;
ot->exec = face_map_remove_from_exec;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
static void fmap_select(Object *ob, bool select)
{
Mesh *me = ob->data;
BMEditMesh *em = me->edit_mesh;
BMFace *efa;
BMIter iter;
int *map;
int cd_fmap_offset;
int mapindex = ob->actfmap - 1;
if (!CustomData_has_layer(&em->bm->pdata, CD_FACEMAP)) {
BM_data_layer_add(em->bm, &em->bm->pdata, CD_FACEMAP);
}
cd_fmap_offset = CustomData_get_offset(&em->bm->pdata, CD_FACEMAP);
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
map = BM_ELEM_CD_GET_VOID_P(efa, cd_fmap_offset);
if (*map == mapindex) {
BM_face_select_set(em->bm, efa, select);
}
}
}
static int face_map_select_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *ob = ED_object_context(C);
bFaceMap *fmap = BLI_findlink(&ob->fmaps, ob->actfmap - 1);
if (fmap) {
fmap_select(ob, true);
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
}
return OPERATOR_FINISHED;
}
void OBJECT_OT_face_map_select(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Select Face Map Faces";
ot->idname = "OBJECT_OT_face_map_select";
ot->description = "Select faces belonging to a face map";
/* api callbacks */
ot->poll = face_map_supported_edit_mode_poll;
ot->exec = face_map_select_exec;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
static int face_map_deselect_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *ob = ED_object_context(C);
bFaceMap *fmap = BLI_findlink(&ob->fmaps, ob->actfmap - 1);
if (fmap) {
fmap_select(ob, false);
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
}
return OPERATOR_FINISHED;
}
void OBJECT_OT_face_map_deselect(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Deselect Face Map Faces";
ot->idname = "OBJECT_OT_face_map_deselect";
ot->description = "Deselect faces belonging to a face map";
/* api callbacks */
ot->poll = face_map_supported_edit_mode_poll;
ot->exec = face_map_deselect_exec;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
static int face_map_move_exec(bContext *C, wmOperator *op)
{
Object *ob = ED_object_context(C);
bFaceMap *fmap;
int dir = RNA_enum_get(op->ptr, "direction");
fmap = BLI_findlink(&ob->fmaps, ob->actfmap - 1);
if (!fmap) {
return OPERATOR_CANCELLED;
}
if (!fmap->prev && !fmap->next) {
return OPERATOR_CANCELLED;
}
int pos1 = BLI_findindex(&ob->fmaps, fmap);
int pos2 = pos1 - dir;
int len = BLI_listbase_count(&ob->fmaps);
int *map = MEM_mallocN(len * sizeof(*map), __func__);
if (!IN_RANGE(pos2, -1, len)) {
const int offset = len - dir;
for (int i = 0; i < len; i++) {
map[i] = (i + offset) % len;
}
pos2 = map[pos1];
}
else {
range_vn_i(map, len, 0);
SWAP(int, map[pos1], map[pos2]);
}
void *prev = fmap->prev;
void *next = fmap->next;
BLI_remlink(&ob->fmaps, fmap);
if (dir == 1) { /*up*/
BLI_insertlinkbefore(&ob->fmaps, prev, fmap);
}
else { /*down*/
BLI_insertlinkafter(&ob->fmaps, next, fmap);
}
/* Iterate through mesh and substitute the indices as necessary. */
object_facemap_remap(ob, map);
MEM_freeN(map);
ob->actfmap = pos2 + 1;
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GEOM | ND_VERTEX_GROUP, ob);
return OPERATOR_FINISHED;
}
void OBJECT_OT_face_map_move(wmOperatorType *ot)
{
static EnumPropertyItem fmap_slot_move[] = {
{1, "UP", 0, "Up", ""},
{-1, "DOWN", 0, "Down", ""},
{0, NULL, 0, NULL, NULL},
};
/* identifiers */
ot->name = "Move Face Map";
ot->idname = "OBJECT_OT_face_map_move";
ot->description = "Move the active face map up/down in the list";
/* api callbacks */
ot->poll = face_map_supported_poll;
ot->exec = face_map_move_exec;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
RNA_def_enum(
ot->srna, "direction", fmap_slot_move, 0, "Direction", "Direction to move, up or down");
}

View File

@ -316,16 +316,6 @@ void OBJECT_OT_vertex_weight_set_active(struct wmOperatorType *ot);
void OBJECT_OT_vertex_weight_normalize_active_vertex(struct wmOperatorType *ot);
void OBJECT_OT_vertex_weight_copy(struct wmOperatorType *ot);
/* object_facemap_ops.c */
void OBJECT_OT_face_map_add(struct wmOperatorType *ot);
void OBJECT_OT_face_map_remove(struct wmOperatorType *ot);
void OBJECT_OT_face_map_assign(struct wmOperatorType *ot);
void OBJECT_OT_face_map_remove_from(struct wmOperatorType *ot);
void OBJECT_OT_face_map_select(struct wmOperatorType *ot);
void OBJECT_OT_face_map_deselect(struct wmOperatorType *ot);
void OBJECT_OT_face_map_move(struct wmOperatorType *ot);
/* object_warp.c */
void TRANSFORM_OT_vertex_warp(struct wmOperatorType *ot);

View File

@ -226,13 +226,7 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_vertex_weight_normalize_active_vertex);
WM_operatortype_append(OBJECT_OT_vertex_weight_copy);
WM_operatortype_append(OBJECT_OT_face_map_add);
WM_operatortype_append(OBJECT_OT_face_map_remove);
WM_operatortype_append(OBJECT_OT_face_map_assign);
WM_operatortype_append(OBJECT_OT_face_map_remove_from);
WM_operatortype_append(OBJECT_OT_face_map_select);
WM_operatortype_append(OBJECT_OT_face_map_deselect);
WM_operatortype_append(OBJECT_OT_face_map_move);
WM_operatortype_append(TRANSFORM_OT_vertex_warp);

View File

@ -464,7 +464,6 @@ enum eSculptFaceSetsInitMode {
SCULPT_FACE_SETS_FROM_CREASES = 4,
SCULPT_FACE_SETS_FROM_SHARP_EDGES = 5,
SCULPT_FACE_SETS_FROM_BEVEL_WEIGHT = 6,
SCULPT_FACE_SETS_FROM_FACE_MAPS = 7,
SCULPT_FACE_SETS_FROM_FACE_SET_BOUNDARIES = 8,
};
@ -518,13 +517,7 @@ static EnumPropertyItem prop_sculpt_face_sets_init_types[] = {
"Face Sets from Sharp Edges",
"Create Face Sets using Sharp Edges as boundaries",
},
{
SCULPT_FACE_SETS_FROM_FACE_MAPS,
"FACE_MAPS",
0,
"Face Sets from Face Maps",
"Create a Face Set per Face Map",
},
{
SCULPT_FACE_SETS_FROM_FACE_SET_BOUNDARIES,
"FACE_SET_BOUNDARIES",
@ -610,13 +603,6 @@ static void sculpt_face_sets_init_loop(Object *ob, const int mode)
ss->face_sets[i] = material_indices[i] + 1;
}
}
else if (mode == SCULPT_FACE_SETS_FROM_FACE_MAPS) {
const int *face_maps = static_cast<const int *>(
CustomData_get_layer(&mesh->pdata, CD_FACEMAP));
for (const int i : IndexRange(mesh->totpoly)) {
ss->face_sets[i] = face_maps ? face_maps[i] : 1;
}
}
}
static int sculpt_face_set_init_exec(bContext *C, wmOperator *op)
@ -719,10 +705,6 @@ static int sculpt_face_set_init_exec(bContext *C, wmOperator *op)
});
break;
}
case SCULPT_FACE_SETS_FROM_FACE_MAPS: {
sculpt_face_sets_init_loop(ob, SCULPT_FACE_SETS_FROM_FACE_MAPS);
break;
}
}
SCULPT_undo_push_end(ob);

View File

@ -41,87 +41,3 @@
uchar view3d_camera_border_hack_col[3];
bool view3d_camera_border_hack_test = false;
#endif
/* ***************** BACKBUF SEL (BBS) ********* */
void ED_draw_object_facemap(Depsgraph *depsgraph,
Object *ob,
const float col[4],
const int facemap)
{
/* happens on undo */
if (ob->type != OB_MESH || !ob->data) {
return;
}
const Mesh *me = static_cast<const Mesh *>(ob->data);
{
Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
const Mesh *me_eval = BKE_object_get_evaluated_mesh(ob_eval);
if (me_eval != nullptr) {
me = me_eval;
}
}
GPU_front_facing(ob->transflag & OB_NEG_SCALE);
/* Just to create the data to pass to immediate mode! (sigh) */
const int *facemap_data = static_cast<const int *>(CustomData_get_layer(&me->pdata, CD_FACEMAP));
if (facemap_data) {
GPU_blend(GPU_BLEND_ALPHA);
const float(*positions)[3] = BKE_mesh_vert_positions(me);
const blender::OffsetIndices polys = me->polys();
const blender::Span<int> corner_verts = me->corner_verts();
const blender::Span<MLoopTri> looptris = me->looptris();
facemap_data = static_cast<const int *>(CustomData_get_layer(&me->pdata, CD_FACEMAP));
/* Make a batch and free it each time for now. */
const int looptris_len = poly_to_tri_count(polys.size(), corner_verts.size());
const int vbo_len_capacity = looptris_len * 3;
int vbo_len_used = 0;
GPUVertFormat format_pos = {0};
const uint pos_id = GPU_vertformat_attr_add(
&format_pos, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT);
GPUVertBuf *vbo_pos = GPU_vertbuf_create_with_format(&format_pos);
GPU_vertbuf_data_alloc(vbo_pos, vbo_len_capacity);
GPUVertBufRaw pos_step;
GPU_vertbuf_attr_get_raw_data(vbo_pos, pos_id, &pos_step);
int tri_index = 0;
for (const int i : polys.index_range()) {
if (facemap_data[i] == facemap) {
for (int j = 2; j < polys[i].size(); j++) {
copy_v3_v3(static_cast<float *>(GPU_vertbuf_raw_step(&pos_step)),
positions[corner_verts[looptris[tri_index].tri[0]]]);
copy_v3_v3(static_cast<float *>(GPU_vertbuf_raw_step(&pos_step)),
positions[corner_verts[looptris[tri_index].tri[1]]]);
copy_v3_v3(static_cast<float *>(GPU_vertbuf_raw_step(&pos_step)),
positions[corner_verts[looptris[tri_index].tri[2]]]);
vbo_len_used += 3;
tri_index++;
}
}
else {
tri_index += polys[i].size() - 2;
}
}
if (vbo_len_capacity != vbo_len_used) {
GPU_vertbuf_data_resize(vbo_pos, vbo_len_used);
}
GPUBatch *draw_batch = GPU_batch_create(GPU_PRIM_TRIS, vbo_pos, nullptr);
GPU_batch_program_set_builtin(draw_batch, GPU_SHADER_3D_UNIFORM_COLOR);
GPU_batch_uniform_4fv(draw_batch, "color", col);
GPU_batch_draw(draw_batch);
GPU_batch_discard(draw_batch);
GPU_vertbuf_discard(vbo_pos);
GPU_blend(GPU_BLEND_NONE);
}
}

View File

@ -121,7 +121,9 @@ typedef enum eCustomDataType {
* lazily. Derived vertex and polygon normals are stored in #Mesh_Runtime.
*/
CD_NORMAL = 8,
CD_FACEMAP = 9, /* exclusive face group, each face can only be part of one */
#ifdef DNA_DEPRECATED_ALLOW
CD_FACEMAP = 9,
#endif
CD_PROP_FLOAT = 10,
CD_PROP_INT32 = 11,
CD_PROP_STRING = 12,
@ -190,7 +192,6 @@ typedef enum eCustomDataType {
#define CD_MASK_MCOL (1 << CD_MCOL)
#define CD_MASK_ORIGINDEX (1 << CD_ORIGINDEX)
#define CD_MASK_NORMAL (1 << CD_NORMAL)
#define CD_MASK_FACEMAP (1 << CD_FACEMAP)
#define CD_MASK_PROP_FLOAT (1 << CD_PROP_FLOAT)
#define CD_MASK_PROP_INT32 (1 << CD_PROP_INT32)
#define CD_MASK_PROP_STRING (1 << CD_PROP_STRING)

View File

@ -56,15 +56,6 @@ typedef struct bDeformGroup {
char flag, _pad0[7];
} bDeformGroup;
/** Face Maps. */
typedef struct bFaceMap {
struct bFaceMap *next, *prev;
/** MAX_VGROUP_NAME. */
char name[64];
char flag;
char _pad0[7];
} bFaceMap;
#define MAX_VGROUP_NAME 64
/* bDeformGroup->flag */
@ -353,8 +344,6 @@ typedef struct Object {
ListBase modifiers;
/** List of GpencilModifierData structures. */
ListBase greasepencil_modifiers;
/** List of facemaps. */
ListBase fmaps;
/** List of viewport effects. Actually only used by grease pencil. */
ListBase shader_fx;
@ -445,8 +434,7 @@ typedef struct Object {
/** Current deformation group, NOTE: index starts at 1. */
unsigned short actdef DNA_DEPRECATED;
/** Current face map, NOTE: index starts at 1. */
unsigned short actfmap;
char _pad2[2];
char _pad2[4];
/** Object color (in most cases the material color is used for drawing). */
float color[4];

View File

@ -154,17 +154,6 @@ static void rna_MeshEdgeLayer_name_set(PointerRNA *ptr, const char *value)
}
}
# endif
static void rna_MeshPolyLayer_name_set(PointerRNA *ptr, const char *value)
{
CustomDataLayer *layer = (CustomDataLayer *)ptr->data;
if (CD_TYPE_AS_MASK(layer->type) & CD_MASK_PROP_ALL) {
BKE_id_attribute_rename(ptr->owner_id, layer->name, value, NULL);
}
else {
rna_cd_layer_name_set(rna_mesh_pdata(ptr), layer, value);
}
}
static void rna_MeshLoopLayer_name_set(PointerRNA *ptr, const char *value)
{
CustomDataLayer *layer = (CustomDataLayer *)ptr->data;
@ -1356,78 +1345,6 @@ static int rna_MeshPaintMaskLayer_data_length(PointerRNA *ptr)
/* End paint mask */
/* Face maps */
DEFINE_CUSTOMDATA_LAYER_COLLECTION(face_map, pdata, CD_FACEMAP)
DEFINE_CUSTOMDATA_LAYER_COLLECTION_ACTIVEITEM(
face_map, pdata, CD_FACEMAP, active, MeshFaceMapLayer)
static char *rna_MeshFaceMapLayer_path(const PointerRNA *ptr)
{
const CustomDataLayer *cdl = ptr->data;
char name_esc[sizeof(cdl->name) * 2];
BLI_str_escape(name_esc, cdl->name, sizeof(name_esc));
return BLI_sprintfN("face_maps[\"%s\"]", name_esc);
}
static void rna_MeshFaceMapLayer_data_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
{
Mesh *me = rna_mesh(ptr);
CustomDataLayer *layer = (CustomDataLayer *)ptr->data;
rna_iterator_array_begin(
iter, layer->data, sizeof(int), (me->edit_mesh) ? 0 : me->totpoly, 0, NULL);
}
static int rna_MeshFaceMapLayer_data_length(PointerRNA *ptr)
{
Mesh *me = rna_mesh(ptr);
return (me->edit_mesh) ? 0 : me->totpoly;
}
static PointerRNA rna_Mesh_face_map_new(struct Mesh *me, ReportList *reports, const char *name)
{
if (BKE_mesh_ensure_facemap_customdata(me) == false) {
BKE_report(reports, RPT_ERROR, "Currently only single face map layers are supported");
return PointerRNA_NULL;
}
CustomData *pdata = rna_mesh_pdata_helper(me);
int index = CustomData_get_layer_index(pdata, CD_FACEMAP);
BLI_assert(index != -1);
CustomDataLayer *cdl = &pdata->layers[index];
rna_cd_layer_name_set(pdata, cdl, name);
PointerRNA ptr;
RNA_pointer_create(&me->id, &RNA_MeshFaceMapLayer, cdl, &ptr);
return ptr;
}
static void rna_Mesh_face_map_remove(struct Mesh *me,
ReportList *reports,
struct CustomDataLayer *layer)
{
/* just for sanity check */
{
CustomData *pdata = rna_mesh_pdata_helper(me);
int index = CustomData_get_layer_index(pdata, CD_FACEMAP);
if (index != -1) {
CustomDataLayer *layer_test = &pdata->layers[index];
if (layer != layer_test) {
/* don't show name, its likely freed memory */
BKE_report(reports, RPT_ERROR, "Face map not in mesh");
return;
}
}
}
if (BKE_mesh_clear_facemap_customdata(me) == false) {
BKE_report(reports, RPT_ERROR, "Error removing face map");
}
}
/* End face maps */
/* poly.vertices - this is faked loop access for convenience */
static int rna_MeshPoly_vertices_get_length(const PointerRNA *ptr,
int length[RNA_MAX_ARRAY_DIMENSION])
@ -1702,27 +1619,6 @@ static char *rna_EdgeCustomData_data_path(const PointerRNA *ptr, const char *col
return NULL;
}
static char *rna_PolyCustomData_data_path(const PointerRNA *ptr, const char *collection, int type)
{
const CustomDataLayer *cdl;
const Mesh *me = rna_mesh(ptr);
const CustomData *pdata = rna_mesh_pdata(ptr);
int a, b, totpoly = (me->edit_mesh) ? 0 : me->totpoly;
for (cdl = pdata->layers, a = 0; a < pdata->totlayer; cdl++, a++) {
if (cdl->type == type) {
b = ((char *)ptr->data - ((char *)cdl->data)) / CustomData_sizeof(type);
if (b >= 0 && b < totpoly) {
char name_esc[sizeof(cdl->name) * 2];
BLI_str_escape(name_esc, cdl->name, sizeof(name_esc));
return BLI_sprintfN("%s[\"%s\"].data[%d]", collection, name_esc, b);
}
}
}
return NULL;
}
static char *rna_LoopCustomData_data_path(const PointerRNA *ptr, const char *collection, int type)
{
const CustomDataLayer *cdl;
@ -2053,11 +1949,6 @@ static char *rna_MeshColor_path(const PointerRNA *ptr)
return rna_LoopCustomData_data_path(ptr, "vertex_colors", CD_PROP_BYTE_COLOR);
}
static char *rna_MeshFaceMap_path(const PointerRNA *ptr)
{
return rna_PolyCustomData_data_path(ptr, "face_maps", CD_FACEMAP);
}
/***************************************/
static int rna_Mesh_tot_vert_get(PointerRNA *ptr)
@ -2153,10 +2044,6 @@ static void UNUSED_FUNCTION(rna_mesh_unused)(void)
(void)rna_Mesh_uv_layer_render_index_get;
(void)rna_Mesh_uv_layer_render_index_set;
(void)rna_Mesh_uv_layer_render_set;
(void)rna_Mesh_face_map_index_range;
(void)rna_Mesh_face_map_active_index_set;
(void)rna_Mesh_face_map_active_index_get;
(void)rna_Mesh_face_map_active_set;
(void)rna_Mesh_vertex_crease_index_range;
(void)rna_Mesh_edge_crease_index_range;
/* end unused function block */
@ -3227,85 +3114,6 @@ static void rna_def_paint_mask(BlenderRNA *brna, PropertyRNA *UNUSED(cprop))
RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all");
}
static void rna_def_face_map(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
srna = RNA_def_struct(brna, "MeshFaceMapLayer", NULL);
RNA_def_struct_ui_text(srna, "Mesh Face Map Layer", "Per-face map index");
RNA_def_struct_sdna(srna, "CustomDataLayer");
RNA_def_struct_path_func(srna, "rna_MeshFaceMapLayer_path");
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_struct_name_property(srna, prop);
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MeshPolyLayer_name_set");
RNA_def_property_string_maxlength(prop, MAX_CUSTOMDATA_LAYER_NAME_NO_PREFIX);
RNA_def_property_ui_text(prop, "Name", "Name of face map layer");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all");
prop = RNA_def_property(srna, "data", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_type(prop, "MeshFaceMap");
RNA_def_property_ui_text(prop, "Data", "");
RNA_def_property_collection_funcs(prop,
"rna_MeshFaceMapLayer_data_begin",
"rna_iterator_array_next",
"rna_iterator_array_end",
"rna_iterator_array_get",
"rna_MeshFaceMapLayer_data_length",
NULL,
NULL,
NULL);
/* FaceMap struct */
srna = RNA_def_struct(brna, "MeshFaceMap", NULL);
RNA_def_struct_sdna(srna, "MIntProperty");
RNA_def_struct_ui_text(srna, "Int Property", "");
RNA_def_struct_path_func(srna, "rna_MeshFaceMap_path");
prop = RNA_def_property(srna, "value", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "i");
RNA_def_property_ui_text(prop, "Value", "");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all");
}
static void rna_def_face_maps(BlenderRNA *brna, PropertyRNA *cprop)
{
StructRNA *srna;
PropertyRNA *prop;
RNA_def_property_srna(cprop, "MeshFaceMapLayers");
srna = RNA_def_struct(brna, "MeshFaceMapLayers", NULL);
RNA_def_struct_ui_text(srna, "Mesh Face Map Layer", "Per-face map index");
RNA_def_struct_sdna(srna, "Mesh");
RNA_def_struct_ui_text(srna, "Mesh Face Maps", "Collection of mesh face maps");
/* add this since we only ever have one layer anyway, don't bother with active_index */
prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "MeshFaceMapLayer");
RNA_def_property_pointer_funcs(prop, "rna_Mesh_face_map_active_get", NULL, NULL, NULL);
RNA_def_property_ui_text(prop, "Active Face Map Layer", "");
RNA_def_property_update(prop, 0, "rna_Mesh_update_data_legacy_deg_tag_all");
FunctionRNA *func;
PropertyRNA *parm;
func = RNA_def_function(srna, "new", "rna_Mesh_face_map_new");
RNA_def_function_flag(func, FUNC_USE_REPORTS);
RNA_def_function_ui_description(func, "Add a float property layer to Mesh");
RNA_def_string(func, "name", "Face Map", 0, "", "Face map name");
parm = RNA_def_pointer(func, "layer", "MeshFaceMapLayer", "", "The newly created layer");
RNA_def_parameter_flags(parm, 0, PARM_RNAPTR);
RNA_def_function_return(func, parm);
func = RNA_def_function(srna, "remove", "rna_Mesh_face_map_remove");
RNA_def_function_ui_description(func, "Remove a face map layer");
RNA_def_function_flag(func, FUNC_USE_REPORTS);
parm = RNA_def_pointer(func, "layer", "MeshFaceMapLayer", "", "The layer to remove");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
}
static void rna_def_looptri_poly_value(BlenderRNA *brna)
{
StructRNA *srna = RNA_def_struct(brna, "ReadOnlyInteger", NULL);
@ -3552,23 +3360,6 @@ static void rna_def_mesh(BlenderRNA *brna)
"Legacy vertex color layers. Deprecated, use color attributes instead");
rna_def_loop_colors(brna, prop);
/* face-maps */
prop = RNA_def_property(srna, "face_maps", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "pdata.layers", "pdata.totlayer");
RNA_def_property_collection_funcs(prop,
"rna_Mesh_face_maps_begin",
NULL,
NULL,
NULL,
"rna_Mesh_face_maps_length",
NULL,
NULL,
NULL);
RNA_def_property_struct_type(prop, "MeshFaceMapLayer");
RNA_def_property_override_flag(prop, PROPOVERRIDE_IGNORE);
RNA_def_property_ui_text(prop, "Face Map", "");
rna_def_face_maps(brna, prop);
/* Skin vertices */
prop = RNA_def_property(srna, "skin_vertices", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "vdata.layers", "vdata.totlayer");
@ -3866,7 +3657,6 @@ void RNA_def_mesh(BlenderRNA *brna)
rna_def_mpolygon(brna);
rna_def_mloopuv(brna);
rna_def_mloopcol(brna);
rna_def_face_map(brna);
}
#endif

View File

@ -35,7 +35,6 @@
#include "BKE_editmesh.h"
#include "BKE_layer.h"
#include "BKE_object_deform.h"
#include "BKE_object_facemap.h"
#include "BKE_paint.h"
#include "RNA_access.h"
@ -966,91 +965,6 @@ void rna_object_vgroup_name_set(PointerRNA *ptr,
result[0] = '\0';
}
static void rna_FaceMap_name_set(PointerRNA *ptr, const char *value)
{
Object *ob = (Object *)ptr->owner_id;
bFaceMap *fmap = (bFaceMap *)ptr->data;
STRNCPY_UTF8(fmap->name, value);
BKE_object_facemap_unique_name(ob, fmap);
}
static int rna_FaceMap_index_get(PointerRNA *ptr)
{
Object *ob = (Object *)ptr->owner_id;
return BLI_findindex(&ob->fmaps, ptr->data);
}
static PointerRNA rna_Object_active_face_map_get(PointerRNA *ptr)
{
Object *ob = (Object *)ptr->owner_id;
return rna_pointer_inherit_refine(ptr, &RNA_FaceMap, BLI_findlink(&ob->fmaps, ob->actfmap - 1));
}
static int rna_Object_active_face_map_index_get(PointerRNA *ptr)
{
Object *ob = (Object *)ptr->owner_id;
return ob->actfmap - 1;
}
static void rna_Object_active_face_map_index_set(PointerRNA *ptr, int value)
{
Object *ob = (Object *)ptr->owner_id;
ob->actfmap = value + 1;
}
static void rna_Object_active_face_map_index_range(
PointerRNA *ptr, int *min, int *max, int *UNUSED(softmin), int *UNUSED(softmax))
{
Object *ob = (Object *)ptr->owner_id;
*min = 0;
*max = max_ii(0, BLI_listbase_count(&ob->fmaps) - 1);
}
void rna_object_BKE_object_facemap_name_index_get(PointerRNA *ptr, char *value, int index)
{
Object *ob = (Object *)ptr->owner_id;
bFaceMap *fmap;
fmap = BLI_findlink(&ob->fmaps, index - 1);
if (fmap) {
strcpy(value, fmap->name);
}
else {
value[0] = '\0';
}
}
int rna_object_BKE_object_facemap_name_index_length(PointerRNA *ptr, int index)
{
Object *ob = (Object *)ptr->owner_id;
bFaceMap *fmap;
fmap = BLI_findlink(&ob->fmaps, index - 1);
return (fmap) ? strlen(fmap->name) : 0;
}
void rna_object_BKE_object_facemap_name_index_set(PointerRNA *ptr, const char *value, short *index)
{
Object *ob = (Object *)ptr->owner_id;
*index = BKE_object_facemap_name_index(ob, value) + 1;
}
void rna_object_fmap_name_set(PointerRNA *ptr, const char *value, char *result, int result_maxncpy)
{
Object *ob = (Object *)ptr->owner_id;
bFaceMap *fmap = BKE_object_facemap_find_name(ob, value);
if (fmap) {
/* No need for BLI_strncpy_utf8, since this matches an existing group. */
BLI_strncpy(result, value, result_maxncpy);
return;
}
result[0] = '\0';
}
void rna_object_uvlayer_name_set(PointerRNA *ptr,
const char *value,
char *result,
@ -2151,71 +2065,6 @@ static float rna_VertexGroup_weight(ID *id, bDeformGroup *dg, ReportList *report
return weight;
}
static bFaceMap *rna_Object_fmap_new(Object *ob, const char *name)
{
bFaceMap *fmap = BKE_object_facemap_add_name(ob, name);
WM_main_add_notifier(NC_OBJECT | ND_DRAW, ob);
return fmap;
}
static void rna_Object_fmap_remove(Object *ob, ReportList *reports, PointerRNA *fmap_ptr)
{
bFaceMap *fmap = fmap_ptr->data;
if (BLI_findindex(&ob->fmaps, fmap) == -1) {
BKE_reportf(
reports, RPT_ERROR, "Face map '%s' not in object '%s'", fmap->name, ob->id.name + 2);
return;
}
BKE_object_facemap_remove(ob, fmap);
RNA_POINTER_INVALIDATE(fmap_ptr);
WM_main_add_notifier(NC_OBJECT | ND_DRAW, ob);
}
static void rna_Object_fmap_clear(Object *ob)
{
BKE_object_facemap_clear(ob);
WM_main_add_notifier(NC_OBJECT | ND_DRAW, ob);
}
static void rna_FaceMap_face_add(
ID *id, bFaceMap *fmap, ReportList *reports, int index_len, int *index)
{
Object *ob = (Object *)id;
if (BKE_object_is_in_editmode(ob)) {
BKE_report(reports, RPT_ERROR, "FaceMap.add(): cannot be called while object is in edit mode");
return;
}
while (index_len--) {
ED_object_facemap_face_add(ob, fmap, *index++);
}
WM_main_add_notifier(NC_GEOM | ND_DATA, (ID *)ob->data);
}
static void rna_FaceMap_face_remove(
ID *id, bFaceMap *fmap, ReportList *reports, int index_len, int *index)
{
Object *ob = (Object *)id;
if (BKE_object_is_in_editmode(ob)) {
BKE_report(reports, RPT_ERROR, "FaceMap.add(): cannot be called while object is in edit mode");
return;
}
while (index_len--) {
ED_object_facemap_face_remove(ob, fmap, *index++);
}
WM_main_add_notifier(NC_GEOM | ND_DATA, (ID *)ob->data);
}
/* generic poll functions */
bool rna_Lattice_object_poll(PointerRNA *UNUSED(ptr), PointerRNA value)
{
@ -2486,52 +2335,6 @@ static void rna_def_vertex_group(BlenderRNA *brna)
RNA_def_function_return(func, parm);
}
static void rna_def_face_map(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
FunctionRNA *func;
PropertyRNA *parm;
srna = RNA_def_struct(brna, "FaceMap", NULL);
RNA_def_struct_sdna(srna, "bFaceMap");
RNA_def_struct_ui_text(
srna, "Face Map", "Group of faces, each face can only be part of one map");
RNA_def_struct_ui_icon(srna, ICON_MOD_TRIANGULATE);
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_property_ui_text(prop, "Name", "Face map name");
RNA_def_struct_name_property(srna, prop);
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_FaceMap_name_set");
/* update data because modifiers may use #24761. */
RNA_def_property_update(prop, NC_GEOM | ND_DATA | NA_RENAME, "rna_Object_internal_update_data");
prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SELECT);
RNA_def_property_ui_text(prop, "Select", "Face map selection state (for tools to use)");
/* important not to use a notifier here, creates a feedback loop! */
prop = RNA_def_property(srna, "index", PROP_INT, PROP_UNSIGNED);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_int_funcs(prop, "rna_FaceMap_index_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Index", "Index number of the face map");
func = RNA_def_function(srna, "add", "rna_FaceMap_face_add");
RNA_def_function_ui_description(func, "Add faces to the face-map");
RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_SELF_ID);
/* TODO: see how array size of 0 works, this shouldn't be used. */
parm = RNA_def_int_array(func, "index", 1, NULL, 0, 0, "", "List of indices", 0, 0);
RNA_def_parameter_flags(parm, PROP_DYNAMIC, PARM_REQUIRED);
func = RNA_def_function(srna, "remove", "rna_FaceMap_face_remove");
RNA_def_function_ui_description(func, "Remove faces from the face-map");
RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_SELF_ID);
/* TODO: see how array size of 0 works, this shouldn't be used. */
parm = RNA_def_int_array(func, "index", 1, NULL, 0, 0, "", "List of indices", 0, 0);
RNA_def_parameter_flags(parm, PROP_DYNAMIC, PARM_REQUIRED);
}
static void rna_def_material_slot(BlenderRNA *brna)
{
StructRNA *srna;
@ -2921,56 +2724,6 @@ static void rna_def_object_vertex_groups(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_function_ui_description(func, "Delete all vertex groups from object");
}
/* object.face_maps */
static void rna_def_object_face_maps(BlenderRNA *brna, PropertyRNA *cprop)
{
StructRNA *srna;
PropertyRNA *prop;
FunctionRNA *func;
PropertyRNA *parm;
RNA_def_property_srna(cprop, "FaceMaps");
srna = RNA_def_struct(brna, "FaceMaps", NULL);
RNA_def_struct_sdna(srna, "Object");
RNA_def_struct_ui_text(srna, "Face Maps", "Collection of face maps");
prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "FaceMap");
RNA_def_property_pointer_funcs(
prop, "rna_Object_active_face_map_get", "rna_Object_active_face_map_set", NULL, NULL);
RNA_def_property_ui_text(prop, "Active Face Map", "Face maps of the object");
RNA_def_property_update(prop, NC_GEOM | ND_DATA, "rna_Object_internal_update_data");
prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_int_sdna(prop, NULL, "actfmap");
RNA_def_property_int_funcs(prop,
"rna_Object_active_face_map_index_get",
"rna_Object_active_face_map_index_set",
"rna_Object_active_face_map_index_range");
RNA_def_property_ui_text(prop, "Active Face Map Index", "Active index in face map array");
RNA_def_property_update(prop, NC_GEOM | ND_DATA, "rna_Object_internal_update_data");
/* face maps */ /* add_face_map */
func = RNA_def_function(srna, "new", "rna_Object_fmap_new");
RNA_def_function_ui_description(func, "Add face map to object");
RNA_def_string(func, "name", "Map", 0, "", "face map name"); /* optional */
parm = RNA_def_pointer(func, "fmap", "FaceMap", "", "New face map");
RNA_def_function_return(func, parm);
func = RNA_def_function(srna, "remove", "rna_Object_fmap_remove");
RNA_def_function_flag(func, FUNC_USE_REPORTS);
RNA_def_function_ui_description(func, "Delete vertex group from object");
parm = RNA_def_pointer(func, "group", "FaceMap", "", "Face map to remove");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
RNA_def_property_clear_flag(parm, PROP_THICK_WRAP);
func = RNA_def_function(srna, "clear", "rna_Object_fmap_clear");
RNA_def_function_ui_description(func, "Delete all vertex groups from object");
}
static void rna_def_object_display(BlenderRNA *brna)
{
StructRNA *srna;
@ -3599,14 +3352,6 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Vertex Groups", "Vertex groups of the object");
rna_def_object_vertex_groups(brna, prop);
/* face maps */
prop = RNA_def_property(srna, "face_maps", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "fmaps", NULL);
RNA_def_property_struct_type(prop, "FaceMap");
RNA_def_property_override_clear_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
RNA_def_property_ui_text(prop, "Face Maps", "Maps of faces of the object");
rna_def_object_face_maps(brna, prop);
/* empty */
prop = RNA_def_property(srna, "empty_display_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "empty_drawtype");
@ -4017,7 +3762,6 @@ void RNA_def_object(BlenderRNA *brna)
RNA_define_animate_sdna(false);
rna_def_vertex_group(brna);
rna_def_face_map(brna);
rna_def_material_slot(brna);
rna_def_object_display(brna);
rna_def_object_lineart(brna);

View File

@ -44,12 +44,6 @@ static void rna_gizmo_draw_preset_circle(wmGizmo *gz, float matrix[16], int axis
ED_gizmo_draw_preset_circle(gz, (float(*)[4])matrix, axis, select_id);
}
static void rna_gizmo_draw_preset_facemap(
wmGizmo *gz, struct bContext *C, struct Object *ob, int facemap, int select_id)
{
ED_gizmo_draw_preset_facemap(C, gz, ob, facemap, select_id);
}
/* -------------------------------------------------------------------- */
/** \name Gizmo Property Define
* \{ */
@ -261,24 +255,6 @@ void RNA_api_gizmo(StructRNA *srna)
/* -------------------------------------------------------------------- */
/* Other Shapes */
/* draw_preset_facemap */
func = RNA_def_function(srna, "draw_preset_facemap", "rna_gizmo_draw_preset_facemap");
RNA_def_function_ui_description(func, "Draw the face-map of a mesh object");
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
parm = RNA_def_pointer(func, "object", "Object", "", "Object");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
parm = RNA_def_int(func, "face_map", 0, 0, INT_MAX, "Face map index", "", 0, INT_MAX);
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
RNA_def_int(func,
"select_id",
-1,
-1,
INT_MAX,
"ID to use when gizmo is selectable. Use -1 when not selecting",
"",
-1,
INT_MAX);
/* -------------------------------------------------------------------- */
/* Property API */

View File

@ -127,7 +127,6 @@ static void expand_mesh(Mesh &mesh,
CustomData_realloc(&mesh.edata, old_edges_num, mesh.totedge);
}
if (poly_expand != 0) {
CustomData_free_layers(&mesh.pdata, CD_FACEMAP, mesh.totpoly);
CustomData_free_layers(&mesh.pdata, CD_FREESTYLE_FACE, mesh.totpoly);
const int old_polys_num = mesh.totpoly;
mesh.totpoly += poly_expand;

View File

@ -98,8 +98,6 @@ PyDoc_STRVAR(bpy_bmlayeraccess_collection__skin_doc,
"Accessor for skin layer.\n\ntype: :class:`BMLayerCollection`");
PyDoc_STRVAR(bpy_bmlayeraccess_collection__paint_mask_doc,
"Accessor for paint mask layer.\n\ntype: :class:`BMLayerCollection`");
PyDoc_STRVAR(bpy_bmlayeraccess_collection__face_map_doc,
"FaceMap custom-data layer.\n\ntype: :class:`BMLayerCollection`");
#ifdef WITH_FREESTYLE
PyDoc_STRVAR(bpy_bmlayeraccess_collection__freestyle_edge_doc,
"Accessor for Freestyle edge layer.\n\ntype: :class:`BMLayerCollection`");
@ -302,11 +300,6 @@ static PyGetSetDef bpy_bmlayeraccess_face_getseters[] = {
(setter)NULL,
bpy_bmlayeraccess_collection__string_doc,
(void *)CD_PROP_STRING},
{"face_map",
(getter)bpy_bmlayeraccess_collection_get,
(setter)NULL,
bpy_bmlayeraccess_collection__face_map_doc,
(void *)CD_FACEMAP},
#ifdef WITH_FREESTYLE
{"freestyle",
@ -1115,8 +1108,7 @@ PyObject *BPy_BMLayerItem_GetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer)
ret = PyFloat_FromDouble(*(float *)value);
break;
}
case CD_PROP_INT32:
case CD_FACEMAP: {
case CD_PROP_INT32: {
ret = PyLong_FromLong(*(int *)value);
break;
}
@ -1194,8 +1186,7 @@ int BPy_BMLayerItem_SetItem(BPy_BMElem *py_ele, BPy_BMLayerItem *py_layer, PyObj
}
break;
}
case CD_PROP_INT32:
case CD_FACEMAP: {
case CD_PROP_INT32: {
const int tmp_val = PyC_Long_AsI32(py_value);
if (UNLIKELY(tmp_val == -1 && PyErr_Occurred())) {
/* error is set */