Mesh: Remove face map list, convert to integer attribute #108025
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
* \{ */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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) {
|
||||
|
|
|
@ -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. */
|
||||
}
|
||||
|
|
|
@ -62,7 +62,6 @@ enum {
|
|||
SIMFACE_NORMAL,
|
||||
SIMFACE_COPLANAR,
|
||||
SIMFACE_SMOOTH,
|
||||
SIMFACE_FACEMAP,
|
||||
SIMFACE_FREESTYLE,
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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];
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue