Refactor: Move vertex group names to object data

This commit moves the storage of `bDeformGroup` and the active index
to `Mesh`, `Lattice`, and `bGPdata` instead of `Object`. Utility
functions are added to allow easy access to the vertex groups given
an object or an ID.

As explained in T88951, the list of vertex group names is currently
stored separately per object, even though vertex group data is stored
on the geometry. This tends to complicate code and cause bugs,
especially as geometry is created procedurally and tied less closely
to an object.

The "Copy Vertex Groups to Linked" operator is removed, since they
are stored on the geometry anyway.

This patch leaves the object-level python API for vertex groups in
place. Creating a geometry-level RNA API can be a separate step;
the changes in this commit are invasive enough as it is.

Note that opening a file saved in 3.0 in an earlier version means
the vertex groups will not be available.

Differential Revision: https://developer.blender.org/D11689
This commit is contained in:
Hans Goudey 2021-07-13 12:10:34 -04:00
parent 52b94049f2
commit 3b6ee8cee7
Notes: blender-bot 2023-02-14 18:28:10 +01:00
Referenced by commit fc14d02bc5, Fix T93892: Changing bone name leaves non-functional vertex group
Referenced by commit 72b39d3f92, Fix T93728: Greasepencil separate will loose all vertex groups
Referenced by commit 0e52af097f, Fix T93611: Curve modifier crash in editmode in certain situations
Referenced by commit 7bf9c70b14, Fix T92083: Crash renaming bone used in Armature modifier on curve
Referenced by commit 263fa406cd, Fix T90087: Assigning object data doesn't copy vertex groups
Referenced by commit fc32567cda, Versioning: fix vertex group name loss in linked duplicates.
Referenced by commit de913516dd, Fix: missing null check
Referenced by issue #99857, Rebuilding subdivisions with multiresolution deletes vertex groups
Referenced by issue #97208, Copy object from 3.1 to any lower version delete "all vertex groups"
Referenced by issue #96550, Project opened on windows looses vertex groups on Linux.
Referenced by issue #96494, Crash when a curve object got an array modifier with a mesh object containing a vertex group set as cap
Referenced by issue #94634, regression, instanced object can't have different vertex group names (preventing instances to be rigged to other bones)
Referenced by issue #94128, Vertex groups of fake user mesh data go missing when loading old files in 3.0
Referenced by issue #93892, Change bone name cause vertex group not working until select another vertex group
Referenced by issue #93728, When seperating a grease pencil stroke to its own object it will lose all vertex groups
Referenced by issue #93704, gltf2 not exporting animations in 3.0
Referenced by issue #93611, Crash on edit mesh with a curve modifier with both a vertex group assigned and the edit mode display option enabled
Referenced by issue #92912, vertex groups get lost when opening a 3.0 file in Blender 2.93
Referenced by issue #92083, Crash when renaming bone if parented to curve
Referenced by issue #90746, Vertex Group Missing When opening blend file saved in 3.0, on a lower blender version
Referenced by issue #90441, File that was saved in 3.0 and after opened in 2.93.X will lose his vertex group data
Referenced by issue #90087, data copy is ommitting vgroups
Referenced by issue #90039, Pinning data (mesh, curve, grease pencil, lattice, particle system) makes certain tabs/options disappear (vertex groups, shapekeys facemaps)
Referenced by issue #89899, BLI_assert failed: BKE_id_defgroup_list_get()
Referenced by issue #89870, Vertex groups are lost if I save a file in 3.0 and open in 2.92 without warnings
Referenced by issue #89316, Geometry Nodes: An existing Vertex Group (VG) can't be altered after a Boolean Node.
Referenced by issue #88951, Move vertex group names from object to geometry
Referenced by issue #88376, Vertex groups in copy linked object with wrong namming in field of modifier (Bevel)
Referenced by issue #88334, Failure to preserve vertex groups through Geometry Nodes, new to 2.93
Referenced by issue blender/blender-addons#93803, vertex group Names gone when opening file back in older blender version
79 changed files with 731 additions and 496 deletions

View File

@ -41,7 +41,6 @@ class MESH_MT_vertex_group_context_menu(Menu):
).sort_type = 'BONE_HIERARCHY'
layout.separator()
layout.operator("object.vertex_group_copy", icon='DUPLICATE')
layout.operator("object.vertex_group_copy_to_linked")
layout.operator("object.vertex_group_copy_to_selected")
layout.separator()
layout.operator("object.vertex_group_mirror", icon='ARROW_LEFTRIGHT').use_topology = False

View File

@ -39,7 +39,7 @@ extern "C" {
/* Blender file format version. */
#define BLENDER_FILE_VERSION BLENDER_VERSION
#define BLENDER_FILE_SUBVERSION 10
#define BLENDER_FILE_SUBVERSION 11
/* 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

View File

@ -37,6 +37,19 @@ struct MLoop;
struct MPoly;
struct Object;
struct bDeformGroup;
struct ID;
bool BKE_object_supports_vertex_groups(const struct Object *ob);
const struct ListBase *BKE_object_defgroup_list(const struct Object *ob);
struct ListBase *BKE_object_defgroup_list_mutable(struct Object *ob);
int BKE_object_defgroup_count(const struct Object *ob);
int BKE_object_defgroup_active_index_get(const struct Object *ob);
void BKE_object_defgroup_active_index_set(struct Object *ob, const int new_index);
const struct ListBase *BKE_id_defgroup_list_get(const struct ID *id);
struct ListBase *BKE_id_defgroup_list_get_mutable(struct ID *id);
int BKE_id_defgroup_name_index(const struct ID *id, const char *name);
struct bDeformGroup *BKE_object_defgroup_new(struct Object *ob, const char *name);
void BKE_defgroup_copy_list(struct ListBase *outbase, const struct ListBase *inbase);
@ -171,6 +184,7 @@ void BKE_defvert_blend_write(struct BlendWriter *writer, int count, struct MDefo
void BKE_defvert_blend_read(struct BlendDataReader *reader,
int count,
struct MDeformVert *mdverts);
void BKE_defbase_blend_write(struct BlendWriter *writer, const ListBase *defbase);
#ifdef __cplusplus
}

View File

@ -325,10 +325,6 @@ class MeshComponent : public GeometryComponent {
private:
Mesh *mesh_ = nullptr;
GeometryOwnershipType ownership_ = GeometryOwnershipType::Owned;
/* Due to historical design choices, vertex group data is stored in the mesh, but the vertex
* group names are stored on an object. Since we don't have an object here, we copy over the
* names into this map. */
blender::Map<std::string, int> vertex_group_names_;
public:
MeshComponent();
@ -338,14 +334,8 @@ class MeshComponent : public GeometryComponent {
void clear();
bool has_mesh() const;
void replace(Mesh *mesh, GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
void replace_mesh_but_keep_vertex_group_names(
Mesh *mesh, GeometryOwnershipType ownership = GeometryOwnershipType::Owned);
Mesh *release();
void copy_vertex_group_names_from_object(const struct Object &object);
const blender::Map<std::string, int> &vertex_group_names() const;
blender::Map<std::string, int> &vertex_group_names();
const Mesh *get_for_read() const;
Mesh *get_for_write();

View File

@ -900,7 +900,7 @@ static Mesh *prepare_geometry_set_for_mesh_modifier(Mesh *mesh, GeometrySet &r_g
{
/* Add the mesh to the geometry set. */
MeshComponent &mesh_component = r_geometry_set.get_component_for_write<MeshComponent>();
mesh_component.replace_mesh_but_keep_vertex_group_names(mesh, GeometryOwnershipType::Editable);
mesh_component.replace(mesh, GeometryOwnershipType::Editable);
}
{
/* Combine mesh and all instances into a single mesh that can be passed to the modifier. */
@ -948,8 +948,7 @@ static Mesh *modifier_modify_mesh_and_geometry_set(ModifierData *md,
/* Replace only the mesh rather than the whole component, because the entire #MeshComponent
* might have been replaced by data from a different object in the node tree, which means the
* component contains vertex group name data for that object that should not be removed. */
mesh_component.replace_mesh_but_keep_vertex_group_names(input_mesh,
GeometryOwnershipType::Editable);
mesh_component.replace(input_mesh, GeometryOwnershipType::Editable);
/* Let the modifier change the geometry set. */
mti->modifyGeometrySet(md, &mectx, &geometry_set);
@ -993,12 +992,6 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
/* This geometry set contains the non-mesh data that might be generated by modifiers. */
GeometrySet geometry_set_final;
/* Add the initial mesh component, with a copy of the vertex group names from the object,
* since they need to be stored in the geometry set for evaluation. */
MeshComponent &initial_mesh_component =
geometry_set_final.get_component_for_write<MeshComponent>();
initial_mesh_component.copy_vertex_group_names_from_object(*ob);
BLI_assert((mesh_input->id.tag & LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT) == 0);
/* Deformed vertex locations array. Deform only modifier need this type of
@ -1602,12 +1595,6 @@ static void editbmesh_calc_modifiers(struct Depsgraph *depsgraph,
/* This geometry set contains the non-mesh data that might be generated by modifiers. */
GeometrySet geometry_set_final;
/* Add the initial mesh component, with a copy of the vertex group names from the object,
* since they need to be stored in the geometry set for evaluation. */
MeshComponent &initial_mesh_component =
geometry_set_final.get_component_for_write<MeshComponent>();
initial_mesh_component.copy_vertex_group_names_from_object(*ob);
/* Deformed vertex locations array. Deform only modifier need this type of
* float array rather than MVert*. Tracked along with mesh_final as an
* optimization to avoid copying coordinates back and forth if there are
@ -1951,8 +1938,7 @@ static void mesh_build_data(struct Depsgraph *depsgraph,
/* Add the final mesh as read-only non-owning component to the geometry set. */
MeshComponent &mesh_component = geometry_set_eval->get_component_for_write<MeshComponent>();
mesh_component.replace_mesh_but_keep_vertex_group_names(mesh_eval,
GeometryOwnershipType::ReadOnly);
mesh_component.replace(mesh_eval, GeometryOwnershipType::ReadOnly);
ob->runtime.geometry_set_eval = geometry_set_eval;
ob->runtime.mesh_deform_eval = mesh_deform_eval;

View File

@ -486,7 +486,7 @@ static void armature_deform_coords_impl(const Object *ob_arm,
int defbase_len = 0; /* safety for vertexgroup index overflow */
int i, dverts_len = 0; /* safety for vertexgroup overflow */
bool use_dverts = false;
int armature_def_nr;
int armature_def_nr = -1;
int cd_dvert_offset = -1;
/* in editmode, or not an armature */
@ -501,11 +501,11 @@ static void armature_deform_coords_impl(const Object *ob_arm,
BLI_assert(0);
}
/* get the def_nr for the overall armature vertex group if present */
armature_def_nr = BKE_object_defgroup_name_index(ob_target, defgrp_name);
if (ELEM(ob_target->type, OB_MESH, OB_LATTICE, OB_GPENCIL)) {
defbase_len = BLI_listbase_count(&ob_target->defbase);
/* get the def_nr for the overall armature vertex group if present */
armature_def_nr = BKE_object_defgroup_name_index(ob_target, defgrp_name);
defbase_len = BKE_object_defgroup_count(ob_target);
if (ob_target->type == OB_MESH) {
if (em_target == NULL) {
@ -552,7 +552,8 @@ static void armature_deform_coords_impl(const Object *ob_arm,
*
* - Check whether keeping this consistent across frames gives speedup.
*/
for (i = 0, dg = ob_target->defbase.first; dg; i++, dg = dg->next) {
const ListBase *defbase = BKE_object_defgroup_list(ob_target);
for (i = 0, dg = defbase->first; dg; i++, dg = dg->next) {
pchan_from_defbase[i] = BKE_pose_channel_find_name(ob_arm->pose, dg->name);
/* exclude non-deforming bones */
if (pchan_from_defbase[i]) {

View File

@ -1437,7 +1437,7 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph,
if (vgroup_name) {
mdef = CustomData_get_layer(&me_dst->vdata, CD_MDEFORMVERT);
if (mdef) {
vg_idx = BKE_object_defgroup_name_index(ob_dst, vgroup_name);
vg_idx = BKE_id_defgroup_name_index(&me_dst->id, vgroup_name);
}
}

View File

@ -29,6 +29,8 @@
#include "MEM_guardedalloc.h"
#include "DNA_gpencil_types.h"
#include "DNA_lattice_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
@ -64,7 +66,9 @@ bDeformGroup *BKE_object_defgroup_new(Object *ob, const char *name)
BLI_strncpy(defgroup->name, name, sizeof(defgroup->name));
BLI_addtail(&ob->defbase, defgroup);
ListBase *defbase = BKE_object_defgroup_list_mutable(ob);
BLI_addtail(defbase, defgroup);
BKE_object_defgroup_unique_name(defgroup, ob);
BKE_object_batch_cache_dirty_tag(ob);
@ -484,18 +488,120 @@ void BKE_defvert_flip_merged(MDeformVert *dvert, const int *flip_map, const int
}
}
bool BKE_object_supports_vertex_groups(const Object *ob)
{
const ID *id = (const ID *)ob->data;
if (id == NULL) {
return false;
}
return ELEM(GS(id->name), ID_ME, ID_LT, ID_GD);
}
const ListBase *BKE_id_defgroup_list_get(const ID *id)
{
switch (GS(id->name)) {
case ID_ME: {
const Mesh *me = (const Mesh *)id;
return &me->vertex_group_names;
}
case ID_LT: {
const Lattice *lt = (const Lattice *)id;
return &lt->vertex_group_names;
}
case ID_GD: {
const bGPdata *gpd = (const bGPdata *)id;
return &gpd->vertex_group_names;
}
default: {
BLI_assert_unreachable();
}
}
return NULL;
}
static const int *object_defgroup_active_index_get_p(const Object *ob)
{
BLI_assert(BKE_object_supports_vertex_groups(ob));
switch (ob->type) {
case OB_MESH: {
const Mesh *mesh = (const Mesh *)ob->data;
return &mesh->vertex_group_active_index;
}
case OB_LATTICE: {
const Lattice *lattice = (const Lattice *)ob->data;
return &lattice->vertex_group_active_index;
}
case OB_GPENCIL: {
const bGPdata *gpd = (const bGPdata *)ob->data;
return &gpd->vertex_group_active_index;
}
}
return NULL;
}
ListBase *BKE_id_defgroup_list_get_mutable(ID *id)
{
/* Cast away const just for the accessor. */
return (ListBase *)BKE_id_defgroup_list_get(id);
}
bDeformGroup *BKE_object_defgroup_find_name(const Object *ob, const char *name)
{
return (name && name[0] != '\0') ?
BLI_findstring(&ob->defbase, name, offsetof(bDeformGroup, name)) :
NULL;
if (name == NULL || name[0] == '\0') {
return NULL;
}
const ListBase *defbase = BKE_object_defgroup_list(ob);
return BLI_findstring(defbase, name, offsetof(bDeformGroup, name));
}
int BKE_id_defgroup_name_index(const ID *id, const char *name)
{
if (name == NULL || name[0] == '\0') {
return -1;
}
const ListBase *defbase = BKE_id_defgroup_list_get(id);
return BLI_findstringindex(defbase, name, offsetof(bDeformGroup, name));
}
const ListBase *BKE_object_defgroup_list(const Object *ob)
{
BLI_assert(BKE_object_supports_vertex_groups(ob));
return BKE_id_defgroup_list_get((const ID *)ob->data);
}
int BKE_object_defgroup_name_index(const Object *ob, const char *name)
{
return (name && name[0] != '\0') ?
BLI_findstringindex(&ob->defbase, name, offsetof(bDeformGroup, name)) :
-1;
return BKE_id_defgroup_name_index((ID *)ob->data, name);
}
ListBase *BKE_object_defgroup_list_mutable(Object *ob)
{
BLI_assert(BKE_object_supports_vertex_groups(ob));
return BKE_id_defgroup_list_get_mutable((ID *)ob->data);
}
int BKE_object_defgroup_count(const Object *ob)
{
return BLI_listbase_count(BKE_object_defgroup_list(ob));
}
/**
* \note For historical reasons, the index starts at 1 rather than 0.
*/
int BKE_object_defgroup_active_index_get(const Object *ob)
{
return *object_defgroup_active_index_get_p(ob);
}
/**
* \note For historical reasons, the index starts at 1 rather than 0.
*/
void BKE_object_defgroup_active_index_set(Object *ob, const int new_index)
{
/* Cast away const just for the accessor. */
int *index = (int *)object_defgroup_active_index_get_p(ob);
*index = new_index;
}
/**
@ -503,7 +609,8 @@ int BKE_object_defgroup_name_index(const Object *ob, const char *name)
*/
int *BKE_object_defgroup_flip_map(const Object *ob, int *flip_map_len, const bool use_default)
{
int defbase_tot = *flip_map_len = BLI_listbase_count(&ob->defbase);
const ListBase *defbase = BKE_object_defgroup_list(ob);
int defbase_tot = *flip_map_len = BLI_listbase_count(defbase);
if (defbase_tot == 0) {
return NULL;
@ -517,7 +624,7 @@ int *BKE_object_defgroup_flip_map(const Object *ob, int *flip_map_len, const boo
map[i] = -1;
}
for (dg = ob->defbase.first, i = 0; dg; dg = dg->next, i++) {
for (dg = defbase->first, i = 0; dg; dg = dg->next, i++) {
if (map[i] == -1) { /* may be calculated previously */
/* in case no valid value is found, use this */
@ -547,7 +654,8 @@ int *BKE_object_defgroup_flip_map_single(const Object *ob,
const bool use_default,
int defgroup)
{
int defbase_tot = *flip_map_len = BLI_listbase_count(&ob->defbase);
const ListBase *defbase = BKE_object_defgroup_list(ob);
int defbase_tot = *flip_map_len = BLI_listbase_count(defbase);
if (defbase_tot == 0) {
return NULL;
@ -561,7 +669,7 @@ int *BKE_object_defgroup_flip_map_single(const Object *ob,
map[i] = use_default ? i : -1;
}
dg = BLI_findlink(&ob->defbase, defgroup);
dg = BLI_findlink(defbase, defgroup);
BLI_string_flip_side_name(name_flip, dg->name, false, sizeof(name_flip));
if (!STREQ(name_flip, dg->name)) {
@ -578,7 +686,8 @@ int *BKE_object_defgroup_flip_map_single(const Object *ob,
int BKE_object_defgroup_flip_index(const Object *ob, int index, const bool use_default)
{
bDeformGroup *dg = BLI_findlink(&ob->defbase, index);
const ListBase *defbase = BKE_object_defgroup_list(ob);
bDeformGroup *dg = BLI_findlink(defbase, index);
int flip_index = -1;
if (dg) {
@ -595,9 +704,10 @@ int BKE_object_defgroup_flip_index(const Object *ob, int index, const bool use_d
static bool defgroup_find_name_dupe(const char *name, bDeformGroup *dg, Object *ob)
{
const ListBase *defbase = BKE_object_defgroup_list(ob);
bDeformGroup *curdef;
for (curdef = ob->defbase.first; curdef; curdef = curdef->next) {
for (curdef = defbase->first; curdef; curdef = curdef->next) {
if (dg != curdef) {
if (STREQ(curdef->name, name)) {
return true;
@ -1189,7 +1299,10 @@ static bool data_transfer_layersmapping_vgroups_multisrc_to_dst(ListBase *r_map,
{
int idx_src;
int idx_dst;
int tot_dst = BLI_listbase_count(&ob_dst->defbase);
const ListBase *src_list = BKE_object_defgroup_list(ob_src);
ListBase *dst_defbase = BKE_object_defgroup_list_mutable(ob_dst);
int tot_dst = BLI_listbase_count(dst_defbase);
const size_t elem_size = sizeof(*((MDeformVert *)NULL));
@ -1218,7 +1331,7 @@ static bool data_transfer_layersmapping_vgroups_multisrc_to_dst(ListBase *r_map,
}
else if (use_delete && idx_dst > idx_src) {
while (idx_dst-- > idx_src) {
BKE_object_defgroup_remove(ob_dst, ob_dst->defbase.last);
BKE_object_defgroup_remove(ob_dst, dst_defbase->last);
}
}
if (r_map) {
@ -1255,7 +1368,7 @@ static bool data_transfer_layersmapping_vgroups_multisrc_to_dst(ListBase *r_map,
if (use_delete) {
/* Remove all unused dst vgroups first, simpler in this case. */
for (dg_dst = ob_dst->defbase.first; dg_dst;) {
for (dg_dst = dst_defbase->first; dg_dst;) {
bDeformGroup *dg_dst_next = dg_dst->next;
if (BKE_object_defgroup_name_index(ob_src, dg_dst->name) == -1) {
@ -1265,7 +1378,7 @@ static bool data_transfer_layersmapping_vgroups_multisrc_to_dst(ListBase *r_map,
}
}
for (idx_src = 0, dg_src = ob_src->defbase.first; idx_src < num_layers_src;
for (idx_src = 0, dg_src = src_list->first; idx_src < num_layers_src;
idx_src++, dg_src = dg_src->next) {
if (!use_layers_src[idx_src]) {
continue;
@ -1274,7 +1387,7 @@ static bool data_transfer_layersmapping_vgroups_multisrc_to_dst(ListBase *r_map,
if ((idx_dst = BKE_object_defgroup_name_index(ob_dst, dg_src->name)) == -1) {
if (use_create) {
BKE_object_defgroup_add_name(ob_dst, dg_src->name);
idx_dst = ob_dst->actdef - 1;
idx_dst = BKE_object_defgroup_active_index_get(ob_dst) - 1;
}
else {
/* If we are not allowed to create missing dst vgroups, just skip matching src one. */
@ -1340,8 +1453,12 @@ bool data_transfer_layersmapping_vgroups(ListBase *r_map,
* This implies we may have to handle data layout itself while having NULL data itself,
* and even have to support NULL data_src in transfer data code
* (we always create a data_dst, though).
*
* Note: Above comment is outdated, but this function was written when that was true.
*/
if (BLI_listbase_is_empty(&ob_src->defbase)) {
const ListBase *src_defbase = BKE_object_defgroup_list(ob_src);
if (BLI_listbase_is_empty(src_defbase)) {
if (use_delete) {
BKE_object_defgroup_remove_all(ob_dst);
}
@ -1361,35 +1478,37 @@ bool data_transfer_layersmapping_vgroups(ListBase *r_map,
if (fromlayers >= 0) {
idx_src = fromlayers;
if (idx_src >= BLI_listbase_count(&ob_src->defbase)) {
if (idx_src >= BLI_listbase_count(src_defbase)) {
/* This can happen when vgroups are removed from source object...
* Remapping would be really tricky here, we'd need to go over all objects in
* Main every time we delete a vgroup... for now, simpler and safer to abort. */
return false;
}
}
else if ((idx_src = ob_src->actdef - 1) == -1) {
else if ((idx_src = BKE_object_defgroup_active_index_get(ob_src) - 1) == -1) {
return false;
}
if (tolayers >= 0) {
/* NOTE: in this case we assume layer exists! */
idx_dst = tolayers;
BLI_assert(idx_dst < BLI_listbase_count(&ob_dst->defbase));
const ListBase *dst_defbase = BKE_object_defgroup_list(ob_dst);
BLI_assert(idx_dst < BLI_listbase_count(dst_defbase));
UNUSED_VARS_NDEBUG(dst_defbase);
}
else if (tolayers == DT_LAYERS_ACTIVE_DST) {
if ((idx_dst = ob_dst->actdef - 1) == -1) {
if ((idx_dst = BKE_object_defgroup_active_index_get(ob_dst) - 1) == -1) {
bDeformGroup *dg_src;
if (!use_create) {
return true;
}
dg_src = BLI_findlink(&ob_src->defbase, idx_src);
dg_src = BLI_findlink(src_defbase, idx_src);
BKE_object_defgroup_add_name(ob_dst, dg_src->name);
idx_dst = ob_dst->actdef - 1;
idx_dst = BKE_object_defgroup_active_index_get(ob_dst) - 1;
}
}
else if (tolayers == DT_LAYERS_INDEX_DST) {
int num = BLI_listbase_count(&ob_src->defbase);
int num = BLI_listbase_count(src_defbase);
idx_dst = idx_src;
if (num <= idx_dst) {
if (!use_create) {
@ -1402,13 +1521,13 @@ bool data_transfer_layersmapping_vgroups(ListBase *r_map,
}
}
else if (tolayers == DT_LAYERS_NAME_DST) {
bDeformGroup *dg_src = BLI_findlink(&ob_src->defbase, idx_src);
bDeformGroup *dg_src = BLI_findlink(src_defbase, idx_src);
if ((idx_dst = BKE_object_defgroup_name_index(ob_dst, dg_src->name)) == -1) {
if (!use_create) {
return true;
}
BKE_object_defgroup_add_name(ob_dst, dg_src->name);
idx_dst = ob_dst->actdef - 1;
idx_dst = BKE_object_defgroup_active_index_get(ob_dst) - 1;
}
}
else {
@ -1531,6 +1650,13 @@ void BKE_defvert_weight_to_rgb(float r_rgb[3], const float weight)
/** \name .blend file I/O
* \{ */
void BKE_defbase_blend_write(BlendWriter *writer, const ListBase *defbase)
{
LISTBASE_FOREACH (bDeformGroup *, defgroup, defbase) {
BLO_write_struct(writer, bDeformGroup, defgroup);
}
}
void BKE_defvert_blend_write(BlendWriter *writer, int count, MDeformVert *dvlist)
{
if (dvlist == NULL) {

View File

@ -53,7 +53,6 @@ GeometryComponent *MeshComponent::copy() const
if (mesh_ != nullptr) {
new_component->mesh_ = BKE_mesh_copy_for_eval(mesh_, false);
new_component->ownership_ = GeometryOwnershipType::Owned;
new_component->vertex_group_names_ = blender::Map(vertex_group_names_);
}
return new_component;
}
@ -67,7 +66,6 @@ void MeshComponent::clear()
}
mesh_ = nullptr;
}
vertex_group_names_.clear();
}
bool MeshComponent::has_mesh() const
@ -84,23 +82,6 @@ void MeshComponent::replace(Mesh *mesh, GeometryOwnershipType ownership)
ownership_ = ownership;
}
/* This function exists for the same reason as #vertex_group_names_. Non-nodes modifiers need to
* be able to replace the mesh data without losing the vertex group names, which may have come
* from another object. */
void MeshComponent::replace_mesh_but_keep_vertex_group_names(Mesh *mesh,
GeometryOwnershipType ownership)
{
BLI_assert(this->is_mutable());
if (mesh_ != nullptr) {
if (ownership_ == GeometryOwnershipType::Owned) {
BKE_id_free(nullptr, mesh_);
}
mesh_ = nullptr;
}
mesh_ = mesh;
ownership_ = ownership;
}
/* Return the mesh and clear the component. The caller takes over responsibility for freeing the
* mesh (if the component was responsible before). */
Mesh *MeshComponent::release()
@ -111,28 +92,6 @@ Mesh *MeshComponent::release()
return mesh;
}
void MeshComponent::copy_vertex_group_names_from_object(const Object &object)
{
BLI_assert(this->is_mutable());
vertex_group_names_.clear();
int index = 0;
LISTBASE_FOREACH (const bDeformGroup *, group, &object.defbase) {
vertex_group_names_.add(group->name, index);
index++;
}
}
const blender::Map<std::string, int> &MeshComponent::vertex_group_names() const
{
return vertex_group_names_;
}
/* This is only exposed for the internal attribute API. */
blender::Map<std::string, int> &MeshComponent::vertex_group_names()
{
return vertex_group_names_;
}
/* Get the mesh from this component. This method can be used by multiple threads at the same
* time. Therefore, the returned mesh should not be modified. No ownership is transferred. */
const Mesh *MeshComponent::get_for_read() const
@ -864,8 +823,8 @@ class VertexGroupsAttributeProvider final : public DynamicAttributesProvider {
BLI_assert(component.type() == GEO_COMPONENT_TYPE_MESH);
const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
const Mesh *mesh = mesh_component.get_for_read();
const int vertex_group_index = mesh_component.vertex_group_names().lookup_default_as(
attribute_name, -1);
const int vertex_group_index = BLI_findstringindex(
&mesh->vertex_group_names, attribute_name.data(), offsetof(bDeformGroup, name));
if (vertex_group_index < 0) {
return {};
}
@ -889,8 +848,9 @@ class VertexGroupsAttributeProvider final : public DynamicAttributesProvider {
if (mesh == nullptr) {
return {};
}
const int vertex_group_index = mesh_component.vertex_group_names().lookup_default_as(
attribute_name, -1);
const int vertex_group_index = BLI_findstringindex(
&mesh->vertex_group_names, attribute_name.data(), offsetof(bDeformGroup, name));
if (vertex_group_index < 0) {
return {};
}
@ -913,13 +873,13 @@ class VertexGroupsAttributeProvider final : public DynamicAttributesProvider {
{
BLI_assert(component.type() == GEO_COMPONENT_TYPE_MESH);
MeshComponent &mesh_component = static_cast<MeshComponent &>(component);
Mesh *mesh = mesh_component.get_for_write();
const int vertex_group_index = mesh_component.vertex_group_names().pop_default_as(
attribute_name, -1);
const int vertex_group_index = BLI_findstringindex(
&mesh->vertex_group_names, attribute_name.data(), offsetof(bDeformGroup, name));
if (vertex_group_index < 0) {
return false;
}
Mesh *mesh = mesh_component.get_for_write();
if (mesh == nullptr) {
return true;
}
@ -938,14 +898,14 @@ class VertexGroupsAttributeProvider final : public DynamicAttributesProvider {
{
BLI_assert(component.type() == GEO_COMPONENT_TYPE_MESH);
const MeshComponent &mesh_component = static_cast<const MeshComponent &>(component);
for (const auto item : mesh_component.vertex_group_names().items()) {
const StringRefNull name = item.key;
const int vertex_group_index = item.value;
if (vertex_group_index >= 0) {
AttributeMetaData meta_data{ATTR_DOMAIN_POINT, CD_PROP_FLOAT};
if (!callback(name, meta_data)) {
return false;
}
const Mesh *mesh = mesh_component.get_for_read();
if (mesh == nullptr) {
return true;
}
LISTBASE_FOREACH (const bDeformGroup *, group, &mesh->vertex_group_names) {
if (!callback(group->name, {ATTR_DOMAIN_POINT, CD_PROP_FLOAT})) {
return false;
}
}
return true;

View File

@ -48,7 +48,6 @@ static void add_final_mesh_as_geometry_component(const Object &object, GeometryS
MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>();
mesh_component.replace(mesh, GeometryOwnershipType::ReadOnly);
mesh_component.copy_vertex_group_names_from_object(object);
}
}

View File

@ -87,6 +87,8 @@ static void greasepencil_copy_data(Main *UNUSED(bmain),
gpd_dst->mat = MEM_dupallocN(gpd_src->mat);
}
BKE_defgroup_copy_list(&gpd_dst->vertex_group_names, &gpd_src->vertex_group_names);
/* copy layers */
BLI_listbase_clear(&gpd_dst->layers);
LISTBASE_FOREACH (bGPDlayer *, gpl_src, &gpd_src->layers) {
@ -165,6 +167,8 @@ static void greasepencil_blend_write(BlendWriter *writer, ID *id, const void *id
BKE_animdata_blend_write(writer, gpd->adt);
}
BKE_defbase_blend_write(writer, &gpd->vertex_group_names);
BLO_write_pointer_array(writer, gpd->totcol, gpd->mat);
/* write grease-pencil layers to file */
@ -227,6 +231,8 @@ void BKE_gpencil_blend_read_data(BlendDataReader *reader, bGPdata *gpd)
}
}
BLO_read_list(reader, &gpd->vertex_group_names);
/* Materials. */
BLO_read_pointer_array(reader, (void **)&gpd->mat);
@ -498,6 +504,8 @@ void BKE_gpencil_free(bGPdata *gpd, bool free_all)
/* materials */
MEM_SAFE_FREE(gpd->mat);
BLI_freelistN(&gpd->vertex_group_names);
/* free all data */
if (free_all) {
/* clear cache */
@ -2087,8 +2095,9 @@ void BKE_gpencil_vgroup_remove(Object *ob, bDeformGroup *defgroup)
{
bGPdata *gpd = ob->data;
MDeformVert *dvert = NULL;
const int def_nr = BLI_findindex(&ob->defbase, defgroup);
const int totgrp = BLI_listbase_count(&ob->defbase);
const int def_nr = BLI_findindex(&gpd->vertex_group_names, defgroup);
const int totgrp = BLI_listbase_count(&gpd->vertex_group_names);
/* Remove points data */
if (gpd) {
@ -2117,7 +2126,7 @@ void BKE_gpencil_vgroup_remove(Object *ob, bDeformGroup *defgroup)
}
/* Remove the group */
BLI_freelinkN(&ob->defbase, defgroup);
BLI_freelinkN(&gpd->vertex_group_names, defgroup);
DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
}

View File

@ -1317,7 +1317,7 @@ static float *get_weights_array(Object *ob, char *vgroup, WeightsArrayCache *cac
if (cache) {
if (cache->defgroup_weights == NULL) {
int num_defgroup = BLI_listbase_count(&ob->defbase);
int num_defgroup = BKE_object_defgroup_count(ob);
cache->defgroup_weights = MEM_callocN(sizeof(*cache->defgroup_weights) * num_defgroup,
"cached defgroup weights");
cache->num_defgroup_weights = num_defgroup;

View File

@ -87,6 +87,8 @@ static void lattice_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const i
lattice_dst->key->from = &lattice_dst->id;
}
BKE_defgroup_copy_list(&lattice_dst->vertex_group_names, &lattice_src->vertex_group_names);
if (lattice_src->dvert) {
int tot = lattice_src->pntsu * lattice_src->pntsv * lattice_src->pntsw;
lattice_dst->dvert = MEM_mallocN(sizeof(MDeformVert) * tot, "Lattice MDeformVert");
@ -103,6 +105,8 @@ static void lattice_free_data(ID *id)
BKE_lattice_batch_cache_free(lattice);
BLI_freelistN(&lattice->vertex_group_names);
MEM_SAFE_FREE(lattice->def);
if (lattice->dvert) {
BKE_defvert_array_free(lattice->dvert, lattice->pntsu * lattice->pntsv * lattice->pntsw);
@ -150,6 +154,7 @@ static void lattice_blend_write(BlendWriter *writer, ID *id, const void *id_addr
/* direct data */
BLO_write_struct_array(writer, BPoint, lt->pntsu * lt->pntsv * lt->pntsw, lt->def);
BKE_defbase_blend_write(writer, &lt->vertex_group_names);
BKE_defvert_blend_write(writer, lt->pntsu * lt->pntsv * lt->pntsw, lt->dvert);
}
}
@ -161,6 +166,7 @@ static void lattice_blend_read_data(BlendDataReader *reader, ID *id)
BLO_read_data_address(reader, &lt->dvert);
BKE_defvert_blend_read(reader, lt->pntsu * lt->pntsv * lt->pntsw, lt->dvert);
BLO_read_list(reader, &lt->vertex_group_names);
lt->editlatt = NULL;
lt->batch_cache = NULL;

View File

@ -112,7 +112,7 @@ LatticeDeformData *BKE_lattice_deform_data_create(const Object *oblatt, const Ob
int defgrp_index = -1;
const MDeformVert *dvert = BKE_lattice_deform_verts_get(oblatt);
if (lt->vgroup[0] && dvert) {
defgrp_index = BKE_object_defgroup_name_index(oblatt, lt->vgroup);
defgrp_index = BKE_id_defgroup_name_index(&lt->id, lt->vgroup);
if (defgrp_index != -1) {
lattice_weights = MEM_malloc_arrayN(sizeof(float), num_points, "lattice_weights");
@ -364,7 +364,7 @@ static void lattice_deform_coords_impl(const Object *ob_lattice,
* We want either a Mesh/Lattice with no derived data, or derived data with deformverts.
*/
if (defgrp_name && defgrp_name[0] && ob_target && ELEM(ob_target->type, OB_MESH, OB_LATTICE)) {
defgrp_index = BKE_object_defgroup_name_index(ob_target, defgrp_name);
defgrp_index = BKE_id_defgroup_name_index((ID *)ob_target->data, defgrp_name);
if (defgrp_index != -1) {
/* if there's derived data without deformverts, don't use vgroups */

View File

@ -39,6 +39,7 @@
#include "BLI_ghash.h"
#include "BLI_hash.h"
#include "BLI_linklist.h"
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_memarena.h"
#include "BLI_string.h"
@ -125,6 +126,8 @@ static void mesh_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int
mesh_dst->mat = MEM_dupallocN(mesh_src->mat);
BKE_defgroup_copy_list(&mesh_dst->vertex_group_names, &mesh_src->vertex_group_names);
const eCDAllocType alloc_type = (flag & LIB_ID_COPY_CD_REFERENCE) ? CD_REFERENCE : CD_DUPLICATE;
CustomData_copy(&mesh_src->vdata, &mesh_dst->vdata, mask.vmask, alloc_type, mesh_dst->totvert);
CustomData_copy(&mesh_src->edata, &mesh_dst->edata, mask.emask, alloc_type, mesh_dst->totedge);
@ -155,6 +158,8 @@ static void mesh_free_data(ID *id)
{
Mesh *mesh = (Mesh *)id;
BLI_freelistN(&mesh->vertex_group_names);
BKE_mesh_runtime_clear_cache(mesh);
mesh_clear_geometry(mesh);
MEM_SAFE_FREE(mesh->mat);
@ -229,6 +234,8 @@ static void mesh_blend_write(BlendWriter *writer, ID *id, const void *id_address
BKE_animdata_blend_write(writer, mesh->adt);
}
BKE_defbase_blend_write(writer, &mesh->vertex_group_names);
BLO_write_pointer_array(writer, mesh->totcol, mesh->mat);
BLO_write_raw(writer, sizeof(MSelect) * mesh->totselect, mesh->mselect);
@ -288,6 +295,7 @@ static void mesh_blend_read_data(BlendDataReader *reader, ID *id)
/* Normally BKE_defvert_blend_read should be called in CustomData_blend_read,
* but for backwards compatibility in do_versions to work we do it here. */
BKE_defvert_blend_read(reader, mesh->totvert, mesh->dvert);
BLO_read_list(reader, &mesh->vertex_group_names);
CustomData_blend_read(reader, &mesh->vdata, mesh->totvert);
CustomData_blend_read(reader, &mesh->edata, mesh->totedge);
@ -923,6 +931,12 @@ void BKE_mesh_copy_parameters(Mesh *me_dst, const Mesh *me_src)
me_dst->texflag = me_src->texflag;
copy_v3_v3(me_dst->loc, me_src->loc);
copy_v3_v3(me_dst->size, me_src->size);
/* Some callers call this on existing meshes, so free the existing vertex groups first. */
BLI_freelistN(&me_dst->vertex_group_names);
BKE_defgroup_copy_list(&me_dst->vertex_group_names, &me_src->vertex_group_names);
me_dst->vertex_group_active_index = me_src->vertex_group_active_index;
}
/**

View File

@ -234,7 +234,7 @@ static void object_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const in
BKE_pose_rebuild(bmain, ob_dst, ob_dst->data, do_pose_id_user);
}
}
BKE_defgroup_copy_list(&ob_dst->defbase, &ob_src->defbase);
BKE_object_facemap_copy_list(&ob_dst->fmaps, &ob_src->fmaps);
BKE_constraints_copy_ex(&ob_dst->constraints, &ob_src->constraints, flag_subdata, true);
@ -285,7 +285,6 @@ static void object_free_data(ID *id)
MEM_SAFE_FREE(ob->iuser);
MEM_SAFE_FREE(ob->runtime.bb);
BLI_freelistN(&ob->defbase);
BLI_freelistN(&ob->fmaps);
if (ob->pose) {
BKE_pose_free_ex(ob->pose, false);
@ -510,13 +509,6 @@ static void object_foreach_id(ID *id, LibraryForeachIDData *data)
}
}
static void write_defgroups(BlendWriter *writer, ListBase *defbase)
{
LISTBASE_FOREACH (bDeformGroup *, defgroup, defbase) {
BLO_write_struct(writer, bDeformGroup, defgroup);
}
}
static void write_fmaps(BlendWriter *writer, ListBase *fbase)
{
LISTBASE_FOREACH (bFaceMap *, fmap, fbase) {
@ -561,7 +553,6 @@ static void object_blend_write(BlendWriter *writer, ID *id, const void *id_addre
}
BKE_pose_blend_write(writer, ob->pose, arm);
write_defgroups(writer, &ob->defbase);
write_fmaps(writer, &ob->fmaps);
BKE_constraint_blend_write(writer, &ob->constraints);
animviz_motionpath_blend_write(writer, ob->mpath);
@ -644,7 +635,9 @@ static void object_blend_read_data(BlendDataReader *reader, ID *id)
animviz_motionpath_blend_read_data(reader, ob->mpath);
}
/* 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);
@ -2901,9 +2894,6 @@ void BKE_object_make_proxy(Main *bmain, Object *ob, Object *target, Object *cob)
ob->data = target->data;
id_us_plus((ID *)ob->data); /* ensures lib data becomes LIB_TAG_EXTERN */
/* copy vertex groups */
BKE_defgroup_copy_list(&ob->defbase, &target->defbase);
/* copy material and index information */
ob->actcol = ob->totcol = 0;
if (ob->mat) {

View File

@ -33,6 +33,7 @@
#include "DNA_armature_types.h"
#include "DNA_cloth_types.h"
#include "DNA_curve_types.h"
#include "DNA_gpencil_types.h"
#include "DNA_lattice_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
@ -123,8 +124,7 @@ bDeformGroup *BKE_object_defgroup_add_name(Object *ob, const char *name)
}
defgroup = BKE_object_defgroup_new(ob, name);
ob->actdef = BLI_listbase_count(&ob->defbase);
BKE_object_defgroup_active_index_set(ob, BKE_object_defgroup_count(ob));
return defgroup;
}
@ -171,7 +171,8 @@ MDeformVert *BKE_object_defgroup_data_create(ID *id)
bool BKE_object_defgroup_clear(Object *ob, bDeformGroup *dg, const bool use_selection)
{
MDeformVert *dv;
const int def_nr = BLI_findindex(&ob->defbase, dg);
const ListBase *defbase = BKE_object_defgroup_list(ob);
const int def_nr = BLI_findindex(defbase, dg);
bool changed = false;
if (ob->type == OB_MESH) {
@ -249,7 +250,9 @@ bool BKE_object_defgroup_clear_all(Object *ob, const bool use_selection)
bDeformGroup *dg;
bool changed = false;
for (dg = ob->defbase.first; dg; dg = dg->next) {
const ListBase *defbase = BKE_object_defgroup_list(ob);
for (dg = defbase->first; dg; dg = dg->next) {
if (BKE_object_defgroup_clear(ob, dg, use_selection)) {
changed = true;
}
@ -265,7 +268,7 @@ bool BKE_object_defgroup_clear_all(Object *ob, const bool use_selection)
static void object_defgroup_remove_update_users(Object *ob, const int idx)
{
int i, defbase_tot = BLI_listbase_count(&ob->defbase) + 1;
int i, defbase_tot = BKE_object_defgroup_count(ob) + 1;
int *map = MEM_mallocN(sizeof(int) * defbase_tot, "vgroup del");
map[idx] = map[0] = 0;
@ -285,15 +288,18 @@ static void object_defgroup_remove_common(Object *ob, bDeformGroup *dg, const in
object_defgroup_remove_update_users(ob, def_nr + 1);
/* Remove the group */
BLI_freelinkN(&ob->defbase, dg);
ListBase *defbase = BKE_object_defgroup_list_mutable(ob);
BLI_freelinkN(defbase, dg);
/* Update the active deform index if necessary */
if (ob->actdef > def_nr) {
ob->actdef--;
const int active_index = BKE_object_defgroup_active_index_get(ob);
if (active_index > def_nr) {
BKE_object_defgroup_active_index_set(ob, active_index - 1);
}
/* remove all dverts */
if (BLI_listbase_is_empty(&ob->defbase)) {
if (BLI_listbase_is_empty(defbase)) {
if (ob->type == OB_MESH) {
Mesh *me = ob->data;
CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert);
@ -307,8 +313,9 @@ static void object_defgroup_remove_common(Object *ob, bDeformGroup *dg, const in
}
}
}
else if (ob->actdef < 1) { /* Keep a valid active index if we still have some vgroups. */
ob->actdef = 1;
else if (BKE_object_defgroup_active_index_get(ob) < 1) {
/* Keep a valid active index if we still have some vgroups. */
BKE_object_defgroup_active_index_set(ob, 1);
}
}
@ -316,7 +323,9 @@ static void object_defgroup_remove_object_mode(Object *ob, bDeformGroup *dg)
{
MDeformVert *dvert_array = NULL;
int dvert_tot = 0;
const int def_nr = BLI_findindex(&ob->defbase, dg);
const ListBase *defbase = BKE_object_defgroup_list(ob);
const int def_nr = BLI_findindex(defbase, dg);
BLI_assert(def_nr != -1);
@ -347,7 +356,8 @@ static void object_defgroup_remove_object_mode(Object *ob, bDeformGroup *dg)
static void object_defgroup_remove_edit_mode(Object *ob, bDeformGroup *dg)
{
int i;
const int def_nr = BLI_findindex(&ob->defbase, dg);
const ListBase *defbase = BKE_object_defgroup_list(ob);
const int def_nr = BLI_findindex(defbase, dg);
BLI_assert(def_nr != -1);
@ -425,7 +435,9 @@ void BKE_object_defgroup_remove(Object *ob, bDeformGroup *defgroup)
*/
void BKE_object_defgroup_remove_all_ex(struct Object *ob, bool only_unlocked)
{
bDeformGroup *dg = (bDeformGroup *)ob->defbase.first;
ListBase *defbase = BKE_object_defgroup_list_mutable(ob);
bDeformGroup *dg = (bDeformGroup *)defbase->first;
const bool edit_mode = BKE_object_is_in_editmode_vgroup(ob);
if (dg) {
@ -444,7 +456,7 @@ void BKE_object_defgroup_remove_all_ex(struct Object *ob, bool only_unlocked)
dg = next_dg;
}
}
else { /* ob->defbase is empty... */
else { /* defbase is empty... */
/* remove all dverts */
if (ob->type == OB_MESH) {
Mesh *me = ob->data;
@ -459,7 +471,7 @@ void BKE_object_defgroup_remove_all_ex(struct Object *ob, bool only_unlocked)
}
}
/* Fix counters/indices */
ob->actdef = 0;
BKE_object_defgroup_active_index_set(ob, 0);
}
}
@ -478,20 +490,23 @@ void BKE_object_defgroup_remove_all(struct Object *ob)
*/
int *BKE_object_defgroup_index_map_create(Object *ob_src, Object *ob_dst, int *r_map_len)
{
const ListBase *src_defbase = BKE_object_defgroup_list(ob_src);
const ListBase *dst_defbase = BKE_object_defgroup_list(ob_dst);
/* Build src to merged mapping of vgroup indices. */
if (BLI_listbase_is_empty(&ob_src->defbase) || BLI_listbase_is_empty(&ob_dst->defbase)) {
if (BLI_listbase_is_empty(src_defbase) || BLI_listbase_is_empty(dst_defbase)) {
*r_map_len = 0;
return NULL;
}
bDeformGroup *dg_src;
*r_map_len = BLI_listbase_count(&ob_src->defbase);
*r_map_len = BLI_listbase_count(src_defbase);
int *vgroup_index_map = MEM_malloc_arrayN(
*r_map_len, sizeof(*vgroup_index_map), "defgroup index map create");
bool is_vgroup_remap_needed = false;
int i;
for (dg_src = ob_src->defbase.first, i = 0; dg_src; dg_src = dg_src->next, i++) {
for (dg_src = src_defbase->first, i = 0; dg_src; dg_src = dg_src->next, i++) {
vgroup_index_map[i] = BKE_object_defgroup_name_index(ob_dst, dg_src->name);
is_vgroup_remap_needed = is_vgroup_remap_needed || (vgroup_index_map[i] != i);
}
@ -576,17 +591,17 @@ bool BKE_object_defgroup_array_get(ID *id, MDeformVert **dvert_arr, int *dvert_t
/**
* gets the status of "flag" for each bDeformGroup
* in ob->defbase and returns an array containing them
* in the object data's vertex group list and returns an array containing them
*/
bool *BKE_object_defgroup_lock_flags_get(Object *ob, const int defbase_tot)
{
bool is_locked = false;
int i;
// int defbase_tot = BLI_listbase_count(&ob->defbase);
ListBase *defbase = BKE_object_defgroup_list_mutable(ob);
bool *lock_flags = MEM_mallocN(defbase_tot * sizeof(bool), "defflags");
bDeformGroup *defgroup;
for (i = 0, defgroup = ob->defbase.first; i < defbase_tot && defgroup;
for (i = 0, defgroup = defbase->first; i < defbase_tot && defgroup;
defgroup = defgroup->next, i++) {
lock_flags[i] = ((defgroup->flag & DG_LOCK_WEIGHT) != 0);
is_locked |= lock_flags[i];
@ -606,17 +621,17 @@ bool *BKE_object_defgroup_validmap_get(Object *ob, const int defbase_tot)
bool *defgroup_validmap;
GHash *gh;
int i, step1 = 1;
// int defbase_tot = BLI_listbase_count(&ob->defbase);
const ListBase *defbase = BKE_object_defgroup_list(ob);
VirtualModifierData virtualModifierData;
if (BLI_listbase_is_empty(&ob->defbase)) {
if (BLI_listbase_is_empty(defbase)) {
return NULL;
}
gh = BLI_ghash_str_new_ex(__func__, defbase_tot);
/* add all names to a hash table */
for (dg = ob->defbase.first; dg; dg = dg->next) {
for (dg = defbase->first; dg; dg = dg->next) {
BLI_ghash_insert(gh, dg->name, NULL);
}
@ -655,7 +670,7 @@ bool *BKE_object_defgroup_validmap_get(Object *ob, const int defbase_tot)
defgroup_validmap = MEM_mallocN(sizeof(*defgroup_validmap) * defbase_tot, "wpaint valid map");
/* add all names to a hash table */
for (dg = ob->defbase.first, i = 0; dg; dg = dg->next, i++) {
for (dg = defbase->first, i = 0; dg; dg = dg->next, i++) {
defgroup_validmap[i] = (BLI_ghash_lookup(gh, dg->name) != NULL);
}
@ -676,9 +691,11 @@ bool *BKE_object_defgroup_selected_get(Object *ob, int defbase_tot, int *r_dg_fl
Object *armob = BKE_object_pose_armature_get(ob);
(*r_dg_flags_sel_tot) = 0;
const ListBase *defbase = BKE_object_defgroup_list(ob);
if (armob) {
bPose *pose = armob->pose;
for (i = 0, defgroup = ob->defbase.first; i < defbase_tot && defgroup;
for (i = 0, defgroup = defbase->first; i < defbase_tot && defgroup;
defgroup = defgroup->next, i++) {
bPoseChannel *pchan = BKE_pose_channel_find_name(pose, defgroup->name);
if (pchan && (pchan->bone->flag & BONE_SELECTED)) {
@ -774,11 +791,13 @@ void BKE_object_defgroup_mirror_selection(struct Object *ob,
bool *dg_flags_sel,
int *r_dg_flags_sel_tot)
{
const ListBase *defbase = BKE_object_defgroup_list(ob);
bDeformGroup *defgroup;
unsigned int i;
int i_mirr;
for (i = 0, defgroup = ob->defbase.first; i < defbase_tot && defgroup;
for (i = 0, defgroup = defbase->first; i < defbase_tot && defgroup;
defgroup = defgroup->next, i++) {
if (dg_selection[i]) {
char name_flip[MAXBONENAME];
@ -804,11 +823,12 @@ bool *BKE_object_defgroup_subset_from_select_type(Object *ob,
int *r_subset_count)
{
bool *defgroup_validmap = NULL;
*r_defgroup_tot = BLI_listbase_count(&ob->defbase);
*r_defgroup_tot = BKE_object_defgroup_count(ob);
switch (subset_type) {
case WT_VGROUP_ACTIVE: {
const int def_nr_active = ob->actdef - 1;
const int def_nr_active = BKE_object_defgroup_active_index_get(ob) - 1;
defgroup_validmap = MEM_mallocN(*r_defgroup_tot * sizeof(*defgroup_validmap), __func__);
memset(defgroup_validmap, false, *r_defgroup_tot * sizeof(*defgroup_validmap));
if ((def_nr_active >= 0) && (def_nr_active < *r_defgroup_tot)) {

View File

@ -2704,8 +2704,8 @@ static void mesh_to_softbody(Object *ob)
bp = sb->bpoint;
defgroup_index = me->dvert ? (sb->vertgroup - 1) : -1;
defgroup_index_mass = me->dvert ? BKE_object_defgroup_name_index(ob, sb->namedVG_Mass) : -1;
defgroup_index_spring = me->dvert ? BKE_object_defgroup_name_index(ob, sb->namedVG_Spring_K) :
defgroup_index_mass = me->dvert ? BKE_id_defgroup_name_index(&me->id, sb->namedVG_Mass) : -1;
defgroup_index_spring = me->dvert ? BKE_id_defgroup_name_index(&me->id, sb->namedVG_Spring_K) :
-1;
for (a = 0; a < me->totvert; a++, bp++) {
@ -2934,8 +2934,8 @@ static void lattice_to_softbody(Object *ob)
bp = sb->bpoint;
defgroup_index = lt->dvert ? (sb->vertgroup - 1) : -1;
defgroup_index_mass = lt->dvert ? BKE_object_defgroup_name_index(ob, sb->namedVG_Mass) : -1;
defgroup_index_spring = lt->dvert ? BKE_object_defgroup_name_index(ob, sb->namedVG_Spring_K) :
defgroup_index_mass = lt->dvert ? BKE_id_defgroup_name_index(&lt->id, sb->namedVG_Mass) : -1;
defgroup_index_spring = lt->dvert ? BKE_id_defgroup_name_index(&lt->id, sb->namedVG_Spring_K) :
-1;
/* same code used as for mesh vertices */

View File

@ -37,6 +37,7 @@
#include "BKE_action.h"
#include "BKE_animsys.h"
#include "BKE_collection.h"
#include "BKE_deform.h"
#include "BKE_fcurve_driver.h"
#include "BKE_lib_id.h"
#include "BKE_main.h"
@ -90,6 +91,19 @@ static void assert_sorted_ids(Main *bmain)
#endif
}
static void move_vertex_group_names_to_object_data(Main *bmain)
{
LISTBASE_FOREACH (Object *, object, &bmain->objects) {
if (ELEM(object->type, OB_MESH, OB_LATTICE, OB_GPENCIL)) {
ListBase *new_defbase = BKE_object_defgroup_list_mutable(object);
/* Clear the list in case the it was already assigned from another object. */
BLI_freelistN(new_defbase);
*new_defbase = object->defbase;
}
}
}
void do_versions_after_linking_300(Main *bmain, ReportList *UNUSED(reports))
{
if (MAIN_VERSION_ATLEAST(bmain, 300, 0) && !MAIN_VERSION_ATLEAST(bmain, 300, 1)) {
@ -134,6 +148,10 @@ void do_versions_after_linking_300(Main *bmain, ReportList *UNUSED(reports))
assert_sorted_ids(bmain);
}
if (!MAIN_VERSION_ATLEAST(bmain, 300, 11)) {
move_vertex_group_names_to_object_data(bmain);
}
/**
* Versioning code until next subversion bump goes here.
*

View File

@ -37,6 +37,7 @@
#include "BKE_action.h"
#include "BKE_armature.h"
#include "BKE_deform.h"
#include "BKE_modifier.h"
#include "DEG_depsgraph_query.h"
@ -1293,10 +1294,9 @@ static void draw_axes(ArmatureDrawContext *ctx,
const bArmature *arm)
{
float final_col[4];
const float *col = (ctx->const_color) ?
ctx->const_color :
(BONE_FLAG(eBone, pchan) & BONE_SELECTED) ? G_draw.block.colorTextHi :
G_draw.block.colorText;
const float *col = (ctx->const_color) ? ctx->const_color :
(BONE_FLAG(eBone, pchan) & BONE_SELECTED) ? G_draw.block.colorTextHi :
G_draw.block.colorText;
copy_v4_v4(final_col, col);
/* Mix with axes color. */
final_col[3] = (ctx->const_color) ? 1.0 : (BONE_FLAG(eBone, pchan) & BONE_SELECTED) ? 0.1 : 0.65;
@ -2040,7 +2040,8 @@ static void draw_armature_pose(ArmatureDrawContext *ctx)
const Object *obact_orig = DEG_get_original_object(draw_ctx->obact);
LISTBASE_FOREACH (bDeformGroup *, dg, &obact_orig->defbase) {
const ListBase *defbase = BKE_object_defgroup_list(obact_orig);
LISTBASE_FOREACH (const bDeformGroup *, dg, defbase) {
if (dg->flag & DG_LOCK_WEIGHT) {
pchan = BKE_pose_channel_find_name(ob->pose, dg->name);

View File

@ -3274,8 +3274,8 @@ GPUBatch *DRW_cache_lattice_wire_get(Object *ob, bool use_weight)
Lattice *lt = ob->data;
int actdef = -1;
if (use_weight && ob->defbase.first && lt->editlatt->latt->dvert) {
actdef = ob->actdef - 1;
if (use_weight && !BLI_listbase_is_empty(&lt->vertex_group_names) && lt->editlatt->latt->dvert) {
actdef = lt->vertex_group_active_index - 1;
}
return DRW_lattice_batch_cache_get_all_edges(lt, use_weight, actdef);

View File

@ -844,8 +844,8 @@ static void gpencil_edit_batches_ensure(Object *ob, GpencilBatchCache *cache, in
int vert_len = GPU_vertbuf_get_vertex_len(cache->vbo);
gpEditIterData iter;
iter.vgindex = ob->actdef - 1;
if (!BLI_findlink(&ob->defbase, iter.vgindex)) {
iter.vgindex = gpd->vertex_group_active_index - 1;
if (!BLI_findlink(&gpd->vertex_group_names, iter.vgindex)) {
iter.vgindex = -1;
}

View File

@ -544,8 +544,8 @@ static void drw_mesh_weight_state_extract(Object *ob,
/* Extract complete vertex weight group selection state and mode flags. */
memset(wstate, 0, sizeof(*wstate));
wstate->defgroup_active = ob->actdef - 1;
wstate->defgroup_len = BLI_listbase_count(&ob->defbase);
wstate->defgroup_active = me->vertex_group_active_index - 1;
wstate->defgroup_len = BLI_listbase_count(&me->vertex_group_names);
wstate->alert_mode = ts->weightuser;

View File

@ -478,7 +478,7 @@ void ED_object_vgroup_calc_from_armature(ReportList *reports,
bArmature *arm = par->data;
if (mode == ARM_GROUPS_NAME) {
const int defbase_tot = BLI_listbase_count(&ob->defbase);
const int defbase_tot = BKE_object_defgroup_count(ob);
int defbase_add;
/* Traverse the bone list, trying to create empty vertex
* groups corresponding to the bone.

View File

@ -384,7 +384,7 @@ static void gpencil_add_verts_to_dgroups(
/* loop groups and assign weight */
for (j = 0; j < numbones; j++) {
int def_nr = BLI_findindex(&ob->defbase, dgrouplist[j]);
int def_nr = BLI_findindex(&gpd->vertex_group_names, dgrouplist[j]);
if (def_nr < 0) {
continue;
}
@ -454,7 +454,7 @@ static void gpencil_object_vgroup_calc_from_armature(const bContext *C,
bArmature *arm = ob_arm->data;
/* always create groups */
const int defbase_tot = BLI_listbase_count(&ob->defbase);
const int defbase_tot = BKE_object_defgroup_count(ob);
int defbase_add;
/* Traverse the bone list, trying to create empty vertex
* groups corresponding to the bone.

View File

@ -2165,7 +2165,9 @@ static bool gpencil_vertex_group_poll(bContext *C)
Object *ob = CTX_data_active_object(C);
if ((ob) && (ob->type == OB_GPENCIL)) {
if (!ID_IS_LINKED(ob) && !ID_IS_LINKED(ob->data) && ob->defbase.first) {
const bGPdata *gpd = (const bGPdata *)ob->data;
if (!ID_IS_LINKED(ob) && !ID_IS_LINKED(ob->data) &&
!BLI_listbase_is_empty(&gpd->vertex_group_names)) {
if (ELEM(ob->mode, OB_MODE_EDIT_GPENCIL, OB_MODE_SCULPT_GPENCIL)) {
return true;
}
@ -2180,7 +2182,9 @@ static bool gpencil_vertex_group_weight_poll(bContext *C)
Object *ob = CTX_data_active_object(C);
if ((ob) && (ob->type == OB_GPENCIL)) {
if (!ID_IS_LINKED(ob) && !ID_IS_LINKED(ob->data) && ob->defbase.first) {
const bGPdata *gpd = (const bGPdata *)ob->data;
if (!ID_IS_LINKED(ob) && !ID_IS_LINKED(ob->data) &&
!BLI_listbase_is_empty(&gpd->vertex_group_names)) {
if (ob->mode == OB_MODE_WEIGHT_GPENCIL) {
return true;
}
@ -2333,6 +2337,7 @@ static int gpencil_vertex_group_invert_exec(bContext *C, wmOperator *op)
{
ToolSettings *ts = CTX_data_tool_settings(C);
Object *ob = CTX_data_active_object(C);
bGPdata *gpd = ob->data;
/* sanity checks */
if (ELEM(NULL, ts, ob, ob->data)) {
@ -2340,8 +2345,9 @@ static int gpencil_vertex_group_invert_exec(bContext *C, wmOperator *op)
}
MDeformVert *dvert;
const int def_nr = ob->actdef - 1;
bDeformGroup *defgroup = BLI_findlink(&ob->defbase, def_nr);
const int def_nr = gpd->vertex_group_active_index - 1;
bDeformGroup *defgroup = BLI_findlink(&gpd->vertex_group_names, def_nr);
if (defgroup == NULL) {
return OPERATOR_CANCELLED;
}
@ -2373,7 +2379,6 @@ static int gpencil_vertex_group_invert_exec(bContext *C, wmOperator *op)
CTX_DATA_END;
/* notifiers */
bGPdata *gpd = ob->data;
DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED | ND_SPACE_PROPERTIES, NULL);
@ -2403,14 +2408,15 @@ static int gpencil_vertex_group_smooth_exec(bContext *C, wmOperator *op)
ToolSettings *ts = CTX_data_tool_settings(C);
Object *ob = CTX_data_active_object(C);
bGPdata *gpd = ob->data;
/* sanity checks */
if (ELEM(NULL, ts, ob, ob->data)) {
return OPERATOR_CANCELLED;
}
const int def_nr = ob->actdef - 1;
bDeformGroup *defgroup = BLI_findlink(&ob->defbase, def_nr);
const int def_nr = gpd->vertex_group_active_index - 1;
bDeformGroup *defgroup = BLI_findlink(&gpd->vertex_group_names, def_nr);
if (defgroup == NULL) {
return OPERATOR_CANCELLED;
}
@ -2470,7 +2476,6 @@ static int gpencil_vertex_group_smooth_exec(bContext *C, wmOperator *op)
CTX_DATA_END;
/* notifiers */
bGPdata *gpd = ob->data;
DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED | ND_SPACE_PROPERTIES, NULL);
@ -2500,6 +2505,7 @@ static int gpencil_vertex_group_normalize_exec(bContext *C, wmOperator *op)
{
ToolSettings *ts = CTX_data_tool_settings(C);
Object *ob = CTX_data_active_object(C);
bGPdata *gpd = ob->data;
/* sanity checks */
if (ELEM(NULL, ts, ob, ob->data)) {
@ -2508,8 +2514,8 @@ static int gpencil_vertex_group_normalize_exec(bContext *C, wmOperator *op)
MDeformVert *dvert = NULL;
MDeformWeight *dw = NULL;
const int def_nr = ob->actdef - 1;
bDeformGroup *defgroup = BLI_findlink(&ob->defbase, def_nr);
const int def_nr = gpd->vertex_group_active_index - 1;
bDeformGroup *defgroup = BLI_findlink(&gpd->vertex_group_names, def_nr);
if (defgroup == NULL) {
return OPERATOR_CANCELLED;
}
@ -2548,7 +2554,6 @@ static int gpencil_vertex_group_normalize_exec(bContext *C, wmOperator *op)
CTX_DATA_END;
/* notifiers */
bGPdata *gpd = ob->data;
DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED | ND_SPACE_PROPERTIES, NULL);
@ -2576,6 +2581,7 @@ static int gpencil_vertex_group_normalize_all_exec(bContext *C, wmOperator *op)
ToolSettings *ts = CTX_data_tool_settings(C);
Object *ob = CTX_data_active_object(C);
bool lock_active = RNA_boolean_get(op->ptr, "lock_active");
bGPdata *gpd = ob->data;
/* sanity checks */
if (ELEM(NULL, ts, ob, ob->data)) {
@ -2585,8 +2591,8 @@ static int gpencil_vertex_group_normalize_all_exec(bContext *C, wmOperator *op)
bDeformGroup *defgroup = NULL;
MDeformVert *dvert = NULL;
MDeformWeight *dw = NULL;
const int def_nr = ob->actdef - 1;
const int defbase_tot = BLI_listbase_count(&ob->defbase);
const int def_nr = gpd->vertex_group_active_index - 1;
const int defbase_tot = BLI_listbase_count(&gpd->vertex_group_names);
if (defbase_tot == 0) {
return OPERATOR_CANCELLED;
}
@ -2603,7 +2609,7 @@ static int gpencil_vertex_group_normalize_all_exec(bContext *C, wmOperator *op)
for (int i = 0; i < gps->totpoints; i++) {
dvert = &gps->dvert[i];
for (int v = 0; v < defbase_tot; v++) {
defgroup = BLI_findlink(&ob->defbase, v);
defgroup = BLI_findlink(&gpd->vertex_group_names, v);
/* skip NULL or locked groups */
if ((defgroup == NULL) || (defgroup->flag & DG_LOCK_WEIGHT)) {
continue;
@ -2629,7 +2635,7 @@ static int gpencil_vertex_group_normalize_all_exec(bContext *C, wmOperator *op)
dvert = &gps->dvert[i];
for (int v = 0; v < defbase_tot; v++) {
defgroup = BLI_findlink(&ob->defbase, v);
defgroup = BLI_findlink(&gpd->vertex_group_names, v);
/* skip NULL or locked groups */
if ((defgroup == NULL) || (defgroup->flag & DG_LOCK_WEIGHT)) {
continue;
@ -2653,7 +2659,6 @@ static int gpencil_vertex_group_normalize_all_exec(bContext *C, wmOperator *op)
CTX_DATA_END;
/* notifiers */
bGPdata *gpd = ob->data;
DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED | ND_SPACE_PROPERTIES, NULL);
@ -2769,7 +2774,6 @@ int ED_gpencil_join_objects_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
Object *ob_active = CTX_data_active_object(C);
bGPdata *gpd_dst = NULL;
bool ok = false;
/* Ensure we're in right mode and that the active object is correct */
@ -2807,7 +2811,7 @@ int ED_gpencil_join_objects_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
gpd_dst = ob_active->data;
bGPdata *gpd_dst = ob_active->data;
Object *ob_dst = ob_active;
/* loop and join all data */
@ -2828,11 +2832,11 @@ int ED_gpencil_join_objects_exec(bContext *C, wmOperator *op)
/* copy vertex groups to the base one's */
int old_idx = 0;
LISTBASE_FOREACH (bDeformGroup *, dg, &ob_iter->defbase) {
LISTBASE_FOREACH (bDeformGroup *, dg, &gpd_src->vertex_group_names) {
bDeformGroup *vgroup = MEM_dupallocN(dg);
int idx = BLI_listbase_count(&ob_active->defbase);
int idx = BLI_listbase_count(&gpd_dst->vertex_group_names);
BKE_object_defgroup_unique_name(vgroup, ob_active);
BLI_addtail(&ob_active->defbase, vgroup);
BLI_addtail(&gpd_dst->vertex_group_names, vgroup);
/* update vertex groups in strokes in original data */
LISTBASE_FOREACH (bGPDlayer *, gpl_src, &gpd->layers) {
LISTBASE_FOREACH (bGPDframe *, gpf, &gpl_src->frames) {
@ -2852,8 +2856,9 @@ int ED_gpencil_join_objects_exec(bContext *C, wmOperator *op)
}
old_idx++;
}
if (ob_active->defbase.first && ob_active->actdef == 0) {
ob_active->actdef = 1;
if (!BLI_listbase_is_empty(&gpd_dst->vertex_group_names) &&
gpd_dst->vertex_group_active_index == 0) {
gpd_dst->vertex_group_active_index = 1;
}
/* add missing materials reading source materials and checking in destination object */

View File

@ -1522,8 +1522,8 @@ static void gpencil_stroke_from_buffer(tGPDfill *tgpf)
pt = gps->points;
point2D = (tGPspoint *)tgpf->sbuffer;
const int def_nr = tgpf->ob->actdef - 1;
const bool have_weight = (bool)BLI_findlink(&tgpf->ob->defbase, def_nr);
const int def_nr = tgpf->gpd->vertex_group_active_index - 1;
const bool have_weight = (bool)BLI_findlink(&tgpf->gpd->vertex_group_names, def_nr);
if ((ts->gpencil_flags & GP_TOOL_FLAG_CREATE_WEIGHTS) && (have_weight)) {
BKE_gpencil_dvert_ensure(gps);

View File

@ -938,8 +938,8 @@ static void gpencil_stroke_newfrombuffer(tGPsdata *p)
Depsgraph *depsgraph = p->depsgraph;
Object *obact = (Object *)p->ownerPtr.data;
RegionView3D *rv3d = p->region->regiondata;
const int def_nr = obact->actdef - 1;
const bool have_weight = (bool)BLI_findlink(&obact->defbase, def_nr);
const int def_nr = gpd->vertex_group_active_index - 1;
const bool have_weight = (bool)BLI_findlink(&gpd->vertex_group_names, def_nr);
const char align_flag = ts->gpencil_v3d_align;
const bool is_depth = (bool)(align_flag & (GP_PROJECT_DEPTH_VIEW | GP_PROJECT_DEPTH_STROKE));
const bool is_lock_axis_view = (bool)(ts->gp_sculpt.lock_axis == 0);

View File

@ -1315,8 +1315,9 @@ static void gpencil_primitive_interaction_end(bContext *C,
Brush *brush = tgpi->brush;
BrushGpencilSettings *brush_settings = brush->gpencil_settings;
const int def_nr = tgpi->ob->actdef - 1;
const bool have_weight = (bool)BLI_findlink(&tgpi->ob->defbase, def_nr);
const int def_nr = tgpi->gpd->vertex_group_active_index - 1;
const ListBase *defbase = BKE_object_defgroup_list(tgpi->ob);
const bool have_weight = (bool)BLI_findlink(defbase, def_nr);
/* return to normal cursor and header status */
ED_workspace_status_text(C, NULL);

View File

@ -1177,8 +1177,8 @@ static bool gpencil_sculpt_brush_init(bContext *C, wmOperator *op)
gso->object = ob;
if (ob) {
invert_m4_m4(gso->inv_mat, ob->obmat);
gso->vrgroup = ob->actdef - 1;
if (!BLI_findlink(&ob->defbase, gso->vrgroup)) {
gso->vrgroup = gso->gpd->vertex_group_active_index - 1;
if (!BLI_findlink(&gso->gpd->vertex_group_names, gso->vrgroup)) {
gso->vrgroup = -1;
}
/* Check if some modifier can transform the stroke. */

View File

@ -1600,8 +1600,8 @@ void ED_gpencil_vgroup_assign(bContext *C, Object *ob, float weight)
{
bGPdata *gpd = (bGPdata *)ob->data;
const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
const int def_nr = ob->actdef - 1;
if (!BLI_findlink(&ob->defbase, def_nr)) {
const int def_nr = gpd->vertex_group_active_index - 1;
if (!BLI_findlink(&gpd->vertex_group_names, def_nr)) {
return;
}
@ -1654,8 +1654,8 @@ void ED_gpencil_vgroup_remove(bContext *C, Object *ob)
{
bGPdata *gpd = (bGPdata *)ob->data;
const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
const int def_nr = ob->actdef - 1;
if (!BLI_findlink(&ob->defbase, def_nr)) {
const int def_nr = gpd->vertex_group_active_index - 1;
if (!BLI_findlink(&gpd->vertex_group_names, def_nr)) {
return;
}
@ -1707,8 +1707,8 @@ void ED_gpencil_vgroup_select(bContext *C, Object *ob)
{
bGPdata *gpd = (bGPdata *)ob->data;
const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
const int def_nr = ob->actdef - 1;
if (!BLI_findlink(&ob->defbase, def_nr)) {
const int def_nr = gpd->vertex_group_active_index - 1;
if (!BLI_findlink(&gpd->vertex_group_names, def_nr)) {
return;
}
@ -1762,8 +1762,8 @@ void ED_gpencil_vgroup_deselect(bContext *C, Object *ob)
{
bGPdata *gpd = (bGPdata *)ob->data;
const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
const int def_nr = ob->actdef - 1;
if (!BLI_findlink(&ob->defbase, def_nr)) {
const int def_nr = gpd->vertex_group_active_index - 1;
if (!BLI_findlink(&gpd->vertex_group_names, def_nr)) {
return;
}

View File

@ -252,7 +252,7 @@ static bool brush_draw_apply(tGP_BrushWeightpaintData *gso,
}
}
else {
bDeformGroup *defgroup = BLI_findlink(&gso->object->defbase, gso->vrgroup);
bDeformGroup *defgroup = BLI_findlink(&gso->gpd->vertex_group_names, gso->vrgroup);
if (defgroup->flag & DG_LOCK_WEIGHT) {
return false;
}
@ -308,8 +308,8 @@ static bool gpencil_weightpaint_brush_init(bContext *C, wmOperator *op)
gso->scene = scene;
gso->object = ob;
if (ob) {
gso->vrgroup = ob->actdef - 1;
if (!BLI_findlink(&ob->defbase, gso->vrgroup)) {
gso->vrgroup = gso->gpd->vertex_group_active_index - 1;
if (!BLI_findlink(&gso->gpd->vertex_group_names, gso->vrgroup)) {
gso->vrgroup = -1;
}
}

View File

@ -514,7 +514,7 @@ static int lattice_select_ungrouped_exec(bContext *C, wmOperator *op)
BPoint *bp;
int a, tot;
if (BLI_listbase_is_empty(&obedit->defbase) || lt->dvert == NULL) {
if (BLI_listbase_is_empty(&lt->vertex_group_names) || lt->dvert == NULL) {
continue;
}

View File

@ -36,6 +36,7 @@
#include "BKE_context.h"
#include "BKE_customdata.h"
#include "BKE_deform.h"
#include "BKE_editmesh.h"
#include "BKE_layer.h"
#include "BKE_report.h"
@ -4740,10 +4741,11 @@ static bool edbm_select_ungrouped_poll(bContext *C)
BMEditMesh *em = BKE_editmesh_from_object(obedit);
const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT);
const ListBase *defbase = BKE_object_defgroup_list(obedit);
if ((em->selectmode & SCE_SELECT_VERTEX) == 0) {
CTX_wm_operator_poll_msg_set(C, "Must be in vertex selection mode");
}
else if (BLI_listbase_is_empty(&obedit->defbase) || cd_dvert_offset == -1) {
else if (BLI_listbase_is_empty(defbase) || cd_dvert_offset == -1) {
CTX_wm_operator_poll_msg_set(C, "No weights/vertex groups on object");
}
else {

View File

@ -30,6 +30,7 @@
#include "BKE_context.h"
#include "BKE_customdata.h"
#include "BKE_deform.h"
#include "BKE_editmesh.h"
#include "BKE_layer.h"
#include "BKE_material.h"
@ -1042,7 +1043,7 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
if (cd_dvert_offset == -1) {
continue;
}
defbase_len = BLI_listbase_count(&ob->defbase);
defbase_len = BKE_object_defgroup_count(ob);
if (defbase_len == 0) {
continue;
}
@ -1091,8 +1092,10 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
/* We store the names of the vertex groups, so we can select
* vertex groups with the same name in different objects. */
const ListBase *defbase = BKE_object_defgroup_list(ob);
int i = 0;
LISTBASE_FOREACH (bDeformGroup *, dg, &ob->defbase) {
LISTBASE_FOREACH (bDeformGroup *, dg, defbase) {
if (BLI_BITMAP_TEST(defbase_selected, i)) {
BLI_gset_add(gset, dg->name);
}
@ -1129,7 +1132,8 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
if (cd_dvert_offset == -1) {
continue;
}
defbase_len = BLI_listbase_count(&ob->defbase);
const ListBase *defbase = BKE_object_defgroup_list(ob);
defbase_len = BLI_listbase_count(defbase);
if (defbase_len == 0) {
continue;
}
@ -1142,7 +1146,7 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op)
GSetIterator gs_iter;
GSET_ITER (gs_iter, gset) {
const char *name = BLI_gsetIterator_getKey(&gs_iter);
int vgroup_id = BLI_findstringindex(&ob->defbase, name, offsetof(bDeformGroup, name));
int vgroup_id = BLI_findstringindex(defbase, name, offsetof(bDeformGroup, name));
if (vgroup_id != -1) {
BLI_BITMAP_ENABLE(defbase_selected, vgroup_id);
found_any = true;

View File

@ -5740,7 +5740,7 @@ static int edbm_decimate_exec(bContext *C, wmOperator *op)
float *vweights = MEM_mallocN(sizeof(*vweights) * bm->totvert, __func__);
{
const int cd_dvert_offset = CustomData_get_offset(&bm->vdata, CD_MDEFORMVERT);
const int defbase_act = obedit->actdef - 1;
const int defbase_act = BKE_object_defgroup_active_index_get(obedit) - 1;
if (use_vertex_group && (cd_dvert_offset == -1)) {
BKE_report(op->reports, RPT_WARNING, "No active vertex group");

View File

@ -475,16 +475,17 @@ int ED_mesh_join_objects_exec(bContext *C, wmOperator *op)
me = ob_iter->data;
/* Join this object's vertex groups to the base one's */
for (dg = ob_iter->defbase.first; dg; dg = dg->next) {
for (dg = me->vertex_group_names.first; dg; dg = dg->next) {
/* See if this group exists in the object (if it doesn't, add it to the end) */
if (!BKE_object_defgroup_find_name(ob, dg->name)) {
odg = MEM_mallocN(sizeof(bDeformGroup), "join deformGroup");
memcpy(odg, dg, sizeof(bDeformGroup));
BLI_addtail(&ob->defbase, odg);
BLI_addtail(&mesh_active->vertex_group_names, odg);
}
}
if (ob->defbase.first && ob->actdef == 0) {
ob->actdef = 1;
if (!BLI_listbase_is_empty(&mesh_active->vertex_group_names) &&
me->vertex_group_active_index == 0) {
me->vertex_group_active_index = 1;
}
/* Join this object's face maps to the base one's. */
@ -1473,19 +1474,21 @@ bool ED_mesh_pick_vert(
MDeformVert *ED_mesh_active_dvert_get_em(Object *ob, BMVert **r_eve)
{
if (ob->mode & OB_MODE_EDIT && ob->type == OB_MESH && ob->defbase.first) {
if (ob->mode & OB_MODE_EDIT && ob->type == OB_MESH) {
Mesh *me = ob->data;
BMesh *bm = me->edit_mesh->bm;
const int cd_dvert_offset = CustomData_get_offset(&bm->vdata, CD_MDEFORMVERT);
if (!BLI_listbase_is_empty(&me->vertex_group_names)) {
BMesh *bm = me->edit_mesh->bm;
const int cd_dvert_offset = CustomData_get_offset(&bm->vdata, CD_MDEFORMVERT);
if (cd_dvert_offset != -1) {
BMVert *eve = BM_mesh_active_vert_get(bm);
if (cd_dvert_offset != -1) {
BMVert *eve = BM_mesh_active_vert_get(bm);
if (eve) {
if (r_eve) {
*r_eve = eve;
if (eve) {
if (r_eve) {
*r_eve = eve;
}
return BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset);
}
return BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset);
}
}
}

View File

@ -33,6 +33,7 @@
#include "BKE_context.h"
#include "BKE_data_transfer.h"
#include "BKE_deform.h"
#include "BKE_mesh_mapping.h"
#include "BKE_mesh_remap.h"
#include "BKE_mesh_runtime.h"
@ -133,12 +134,13 @@ static const EnumPropertyItem *dt_layers_select_src_itemf(bContext *C,
}
if (ob_src) {
bDeformGroup *dg;
const bDeformGroup *dg;
int i;
RNA_enum_item_add_separator(&item, &totitem);
for (i = 0, dg = ob_src->defbase.first; dg; i++, dg = dg->next) {
const ListBase *defbase = BKE_object_defgroup_list(ob_src);
for (i = 0, dg = defbase->first; dg; i++, dg = dg->next) {
tmp_item.value = i;
tmp_item.identifier = tmp_item.name = dg->name;
RNA_enum_item_add(&item, &totitem, &tmp_item);

View File

@ -105,14 +105,13 @@ static int return_editmesh_indexar(BMEditMesh *em, int *r_tot, int **r_indexar,
static bool return_editmesh_vgroup(Object *obedit, BMEditMesh *em, char *r_name, float r_cent[3])
{
const int cd_dvert_offset = obedit->actdef ?
const int active_index = BKE_object_defgroup_active_index_get(obedit);
const int cd_dvert_offset = active_index ?
CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT) :
-1;
zero_v3(r_cent);
if (cd_dvert_offset != -1) {
const int defgrp_index = obedit->actdef - 1;
const int defgrp_index = active_index - 1;
int totvert = 0;
MDeformVert *dvert;
@ -129,7 +128,8 @@ static bool return_editmesh_vgroup(Object *obedit, BMEditMesh *em, char *r_name,
}
}
if (totvert) {
bDeformGroup *dg = BLI_findlink(&obedit->defbase, defgrp_index);
const ListBase *defbase = BKE_object_defgroup_list(obedit);
bDeformGroup *dg = BLI_findlink(defbase, defgrp_index);
BLI_strncpy(r_name, dg->name, sizeof(dg->name));
mul_v3_fl(r_cent, 1.0f / (float)totvert);
return true;

View File

@ -247,7 +247,6 @@ void OBJECT_OT_vertex_group_assign_new(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_remove_from(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_select(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_deselect(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_copy_to_linked(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_copy_to_selected(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_copy(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_normalize(struct wmOperatorType *ot);

View File

@ -201,7 +201,6 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_vertex_group_remove_from);
WM_operatortype_append(OBJECT_OT_vertex_group_select);
WM_operatortype_append(OBJECT_OT_vertex_group_deselect);
WM_operatortype_append(OBJECT_OT_vertex_group_copy_to_linked);
WM_operatortype_append(OBJECT_OT_vertex_group_copy_to_selected);
WM_operatortype_append(OBJECT_OT_vertex_group_copy);
WM_operatortype_append(OBJECT_OT_vertex_group_normalize);

View File

@ -130,7 +130,7 @@ bool ED_vgroup_sync_from_pose(Object *ob)
if (arm->act_bone) {
int def_num = BKE_object_defgroup_name_index(ob, arm->act_bone->name);
if (def_num != -1) {
ob->actdef = def_num + 1;
BKE_object_defgroup_active_index_set(ob, def_num + 1);
return true;
}
}
@ -389,11 +389,16 @@ bool ED_vgroup_array_copy(Object *ob, Object *ob_from)
int dvert_tot_from;
int dvert_tot;
int i;
int defbase_tot_from = BLI_listbase_count(&ob_from->defbase);
int defbase_tot = BLI_listbase_count(&ob->defbase);
ListBase *defbase_dst = BKE_object_defgroup_list_mutable(ob);
const ListBase *defbase_src = BKE_object_defgroup_list(ob_from);
int defbase_tot_from = BLI_listbase_count(defbase_src);
int defbase_tot = BLI_listbase_count(defbase_dst);
bool new_vgroup = false;
if (ob == ob_from) {
BLI_assert(ob != ob_from);
if (ob->data == ob_from->data) {
return true;
}
@ -429,9 +434,9 @@ bool ED_vgroup_array_copy(Object *ob, Object *ob_from)
}
/* do the copy */
BLI_freelistN(&ob->defbase);
BLI_duplicatelist(&ob->defbase, &ob_from->defbase);
ob->actdef = ob_from->actdef;
BLI_freelistN(defbase_dst);
BLI_duplicatelist(defbase_dst, defbase_src);
BKE_object_defgroup_active_index_set(ob, BKE_object_defgroup_active_index_get(ob_from));
if (defbase_tot_from < defbase_tot) {
/* correct vgroup indices because the number of vgroups is being reduced. */
@ -882,7 +887,8 @@ void ED_vgroup_vert_add(Object *ob, bDeformGroup *dg, int vertnum, float weight,
/* add the vert to the deform group with the
* specified assign mode
*/
const int def_nr = BLI_findindex(&ob->defbase, dg);
const ListBase *defbase = BKE_object_defgroup_list(ob);
const int def_nr = BLI_findindex(defbase, dg);
MDeformVert *dv = NULL;
int tot;
@ -913,7 +919,8 @@ void ED_vgroup_vert_remove(Object *ob, bDeformGroup *dg, int vertnum)
/* TODO(campbell): This is slow in a loop, better pass def_nr directly,
* but leave for later. */
const int def_nr = BLI_findindex(&ob->defbase, dg);
const ListBase *defbase = BKE_object_defgroup_list(ob);
const int def_nr = BLI_findindex(defbase, dg);
if (def_nr != -1) {
MDeformVert *dvert = NULL;
@ -989,7 +996,8 @@ static float get_vert_def_nr(Object *ob, const int def_nr, const int vertnum)
float ED_vgroup_vert_weight(Object *ob, bDeformGroup *dg, int vertnum)
{
const int def_nr = BLI_findindex(&ob->defbase, dg);
const ListBase *defbase = BKE_object_defgroup_list(ob);
const int def_nr = BLI_findindex(defbase, dg);
if (def_nr == -1) {
return -1;
@ -1000,9 +1008,9 @@ float ED_vgroup_vert_weight(Object *ob, bDeformGroup *dg, int vertnum)
void ED_vgroup_select_by_name(Object *ob, const char *name)
{
/* NOTE: ob->actdef==0 signals on painting to create a new one,
/* NOTE: actdef==0 signals on painting to create a new one,
* if a bone in posemode is selected */
ob->actdef = BKE_object_defgroup_name_index(ob, name) + 1;
BKE_object_defgroup_active_index_set(ob, BKE_object_defgroup_name_index(ob, name) + 1);
}
/** \} */
@ -1014,9 +1022,10 @@ void ED_vgroup_select_by_name(Object *ob, const char *name)
/* only in editmode */
static void vgroup_select_verts(Object *ob, int select)
{
const int def_nr = ob->actdef - 1;
const int def_nr = BKE_object_defgroup_active_index_get(ob) - 1;
if (!BLI_findlink(&ob->defbase, def_nr)) {
const ListBase *defbase = BKE_object_defgroup_list(ob);
if (!BLI_findlink(defbase, def_nr)) {
return;
}
@ -1111,7 +1120,9 @@ static void vgroup_duplicate(Object *ob)
MDeformVert **dvert_array = NULL;
int i, idg, icdg, dvert_tot = 0;
dg = BLI_findlink(&ob->defbase, (ob->actdef - 1));
ListBase *defbase = BKE_object_defgroup_list_mutable(ob);
dg = BLI_findlink(defbase, BKE_object_defgroup_active_index_get(ob) - 1);
if (!dg) {
return;
}
@ -1127,11 +1138,11 @@ static void vgroup_duplicate(Object *ob)
BLI_strncpy(cdg->name, name, sizeof(cdg->name));
BKE_object_defgroup_unique_name(cdg, ob);
BLI_addtail(&ob->defbase, cdg);
BLI_addtail(defbase, cdg);
idg = (ob->actdef - 1);
ob->actdef = BLI_listbase_count(&ob->defbase);
icdg = (ob->actdef - 1);
idg = BKE_object_defgroup_active_index_get(ob) - 1;
BKE_object_defgroup_active_index_set(ob, BLI_listbase_count(defbase));
icdg = BKE_object_defgroup_active_index_get(ob) - 1;
/* TODO(campbell): we might want to allow only copy selected verts here? */
ED_vgroup_parray_alloc(ob->data, &dvert_array, &dvert_tot, false);
@ -1157,11 +1168,12 @@ static bool vgroup_normalize(Object *ob)
MDeformWeight *dw;
MDeformVert *dv, **dvert_array = NULL;
int dvert_tot = 0;
const int def_nr = ob->actdef - 1;
const int def_nr = BKE_object_defgroup_active_index_get(ob) - 1;
const bool use_vert_sel = vertex_group_use_vert_sel(ob);
if (!BLI_findlink(&ob->defbase, def_nr)) {
const ListBase *defbase = BKE_object_defgroup_list(ob);
if (!BLI_findlink(defbase, def_nr)) {
return false;
}
@ -1639,7 +1651,7 @@ static bool vgroup_normalize_all(Object *ob,
{
MDeformVert *dv, **dvert_array = NULL;
int i, dvert_tot = 0;
const int def_nr = ob->actdef - 1;
const int def_nr = BKE_object_defgroup_active_index_get(ob) - 1;
const bool use_vert_sel = vertex_group_use_vert_sel(ob);
@ -1651,7 +1663,8 @@ static bool vgroup_normalize_all(Object *ob,
ED_vgroup_parray_alloc(ob->data, &dvert_array, &dvert_tot, use_vert_sel);
if (dvert_array) {
const int defbase_tot = BLI_listbase_count(&ob->defbase);
const ListBase *defbase = BKE_object_defgroup_list(ob);
const int defbase_tot = BLI_listbase_count(defbase);
bool *lock_flags = BKE_object_defgroup_lock_flags_get(ob, defbase_tot);
bool changed = false;
@ -1742,7 +1755,7 @@ static const EnumPropertyItem vgroup_lock_mask[] = {
static bool *vgroup_selected_get(Object *ob)
{
int sel_count = 0, defbase_tot = BLI_listbase_count(&ob->defbase);
int sel_count = 0, defbase_tot = BKE_object_defgroup_count(ob);
bool *mask;
if (ob->mode & OB_MODE_WEIGHT_PAINT) {
@ -1759,8 +1772,9 @@ static bool *vgroup_selected_get(Object *ob)
mask = MEM_callocN(defbase_tot * sizeof(bool), __func__);
}
if (sel_count == 0 && ob->actdef >= 1 && ob->actdef <= defbase_tot) {
mask[ob->actdef - 1] = true;
const int actdef = BKE_object_defgroup_active_index_get(ob);
if (sel_count == 0 && actdef >= 1 && actdef <= defbase_tot) {
mask[actdef - 1] = true;
}
return mask;
@ -1775,11 +1789,12 @@ static void vgroup_lock_all(Object *ob, int action, int mask)
if (mask != VGROUP_MASK_ALL) {
selected = vgroup_selected_get(ob);
}
const ListBase *defbase = BKE_object_defgroup_list(ob);
if (action == VGROUP_TOGGLE) {
action = VGROUP_LOCK;
for (dg = ob->defbase.first, i = 0; dg; dg = dg->next, i++) {
for (dg = defbase->first, i = 0; dg; dg = dg->next, i++) {
switch (mask) {
case VGROUP_MASK_INVERT_UNSELECTED:
case VGROUP_MASK_SELECTED:
@ -1802,7 +1817,7 @@ static void vgroup_lock_all(Object *ob, int action, int mask)
}
}
for (dg = ob->defbase.first, i = 0; dg; dg = dg->next, i++) {
for (dg = defbase->first, i = 0; dg; dg = dg->next, i++) {
switch (mask) {
case VGROUP_MASK_SELECTED:
if (!selected[i]) {
@ -2379,13 +2394,15 @@ void ED_vgroup_mirror(Object *ob,
MDeformVert *dvert, *dvert_mirr;
char sel, sel_mirr;
int *flip_map = NULL, flip_map_len;
const int def_nr = ob->actdef - 1;
const int def_nr = BKE_object_defgroup_active_index_get(ob) - 1;
int totmirr = 0, totfail = 0;
*r_totmirr = *r_totfail = 0;
const ListBase *defbase = BKE_object_defgroup_list(ob);
if ((mirror_weights == false && flip_vgroups == false) ||
(BLI_findlink(&ob->defbase, def_nr) == NULL)) {
(BLI_findlink(defbase, def_nr) == NULL)) {
return;
}
@ -2569,7 +2586,8 @@ cleanup:
static void vgroup_delete_active(Object *ob)
{
bDeformGroup *dg = BLI_findlink(&ob->defbase, ob->actdef - 1);
const ListBase *defbase = BKE_object_defgroup_list(ob);
bDeformGroup *dg = BLI_findlink(defbase, BKE_object_defgroup_active_index_get(ob) - 1);
if (!dg) {
return;
}
@ -2580,9 +2598,10 @@ static void vgroup_delete_active(Object *ob)
/* only in editmode */
static void vgroup_assign_verts(Object *ob, const float weight)
{
const int def_nr = ob->actdef - 1;
const int def_nr = BKE_object_defgroup_active_index_get(ob) - 1;
if (!BLI_findlink(&ob->defbase, def_nr)) {
const ListBase *defbase = BKE_object_defgroup_list(ob);
if (!BLI_findlink(defbase, def_nr)) {
return;
}
@ -2700,7 +2719,8 @@ static bool vertex_group_poll_ex(bContext *C, Object *ob)
return false;
}
if (BLI_listbase_is_empty(&ob->defbase)) {
const ListBase *defbase = BKE_object_defgroup_list(ob);
if (BLI_listbase_is_empty(defbase)) {
CTX_wm_operator_poll_msg_set(C, "Object has no vertex groups");
return false;
}
@ -2823,8 +2843,10 @@ static bool vertex_group_vert_select_unlocked_poll(bContext *C)
return false;
}
if (ob->actdef != 0) {
bDeformGroup *dg = BLI_findlink(&ob->defbase, ob->actdef - 1);
const int def_nr = BKE_object_defgroup_active_index_get(ob);
if (def_nr != 0) {
const ListBase *defbase = BKE_object_defgroup_list(ob);
const bDeformGroup *dg = BLI_findlink(defbase, def_nr - 1);
if (dg) {
return !(dg->flag & DG_LOCK_WEIGHT);
}
@ -3025,8 +3047,8 @@ static int vertex_group_remove_from_exec(bContext *C, wmOperator *op)
}
}
else {
bDeformGroup *dg = BLI_findlink(&ob->defbase, ob->actdef - 1);
const ListBase *defbase = BKE_object_defgroup_list(ob);
bDeformGroup *dg = BLI_findlink(defbase, BKE_object_defgroup_active_index_get(ob) - 1);
if ((dg == NULL) || (BKE_object_defgroup_clear(ob, dg, !use_all_verts) == false)) {
return OPERATOR_CANCELLED;
}
@ -3859,55 +3881,6 @@ void OBJECT_OT_vertex_group_mirror(wmOperatorType *ot)
/** \} */
/* -------------------------------------------------------------------- */
/** \name Vertex Group Copy to Linked Operator
* \{ */
static int vertex_group_copy_to_linked_exec(bContext *C, wmOperator *UNUSED(op))
{
Scene *scene = CTX_data_scene(C);
Object *ob_active = ED_object_context(C);
int retval = OPERATOR_CANCELLED;
FOREACH_SCENE_OBJECT_BEGIN (scene, ob_iter) {
if (ob_iter->type == ob_active->type) {
if (ob_iter != ob_active && ob_iter->data == ob_active->data) {
BLI_freelistN(&ob_iter->defbase);
BLI_duplicatelist(&ob_iter->defbase, &ob_active->defbase);
ob_iter->actdef = ob_active->actdef;
DEG_id_tag_update(&ob_iter->id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob_iter);
WM_event_add_notifier(C, NC_GEOM | ND_VERTEX_GROUP, ob_iter->data);
retval = OPERATOR_FINISHED;
}
}
}
FOREACH_SCENE_OBJECT_END;
return retval;
}
void OBJECT_OT_vertex_group_copy_to_linked(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Copy Vertex Groups to Linked";
ot->idname = "OBJECT_OT_vertex_group_copy_to_linked";
ot->description =
"Replace vertex groups of all users of the same geometry data by vertex groups of active "
"object";
/* api callbacks */
ot->poll = vertex_group_poll;
ot->exec = vertex_group_copy_to_linked_exec;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Vertex Group Copy to Selected Operator
* \{ */
@ -3972,7 +3945,7 @@ static int set_active_group_exec(bContext *C, wmOperator *op)
int nr = RNA_enum_get(op->ptr, "group");
BLI_assert(nr + 1 >= 0);
ob->actdef = nr + 1;
BKE_object_defgroup_active_index_set(ob, nr + 1);
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_GEOM | ND_VERTEX_GROUP, ob);
@ -3999,7 +3972,8 @@ static const EnumPropertyItem *vgroup_itemf(bContext *C,
return DummyRNA_NULL_items;
}
for (a = 0, def = ob->defbase.first; def; def = def->next, a++) {
const ListBase *defbase = BKE_object_defgroup_list(ob);
for (a = 0, def = defbase->first; def; def = def->next, a++) {
tmp.value = a;
tmp.icon = ICON_GROUP_VERTEX;
tmp.identifier = def->name;
@ -4048,13 +4022,13 @@ void OBJECT_OT_vertex_group_set_active(wmOperatorType *ot)
* with the order of vgroups then call vgroup_do_remap after */
static char *vgroup_init_remap(Object *ob)
{
bDeformGroup *def;
int defbase_tot = BLI_listbase_count(&ob->defbase);
const ListBase *defbase = BKE_object_defgroup_list(ob);
int defbase_tot = BLI_listbase_count(defbase);
char *name_array = MEM_mallocN(MAX_VGROUP_NAME * sizeof(char) * defbase_tot, "sort vgroups");
char *name;
name = name_array;
for (def = ob->defbase.first; def; def = def->next) {
for (const bDeformGroup *def = defbase->first; def; def = def->next) {
BLI_strncpy(name, def->name, MAX_VGROUP_NAME);
name += MAX_VGROUP_NAME;
}
@ -4065,8 +4039,9 @@ static char *vgroup_init_remap(Object *ob)
static int vgroup_do_remap(Object *ob, const char *name_array, wmOperator *op)
{
MDeformVert *dvert = NULL;
bDeformGroup *def;
int defbase_tot = BLI_listbase_count(&ob->defbase);
const bDeformGroup *def;
const ListBase *defbase = BKE_object_defgroup_list(ob);
int defbase_tot = BLI_listbase_count(defbase);
/* Needs a dummy index at the start. */
int *sort_map_update = MEM_mallocN(sizeof(int) * (defbase_tot + 1), "sort vgroups");
@ -4076,8 +4051,8 @@ static int vgroup_do_remap(Object *ob, const char *name_array, wmOperator *op)
int i;
name = name_array;
for (def = ob->defbase.first, i = 0; def; def = def->next, i++) {
sort_map[i] = BLI_findstringindex(&ob->defbase, name, offsetof(bDeformGroup, name));
for (def = defbase->first, i = 0; def; def = def->next, i++) {
sort_map[i] = BLI_findstringindex(defbase, name, offsetof(bDeformGroup, name));
name += MAX_VGROUP_NAME;
BLI_assert(sort_map[i] != -1);
@ -4130,8 +4105,9 @@ static int vgroup_do_remap(Object *ob, const char *name_array, wmOperator *op)
sort_map_update[0] = 0;
BKE_object_defgroup_remap_update_users(ob, sort_map_update);
BLI_assert(sort_map_update[ob->actdef] >= 0);
ob->actdef = sort_map_update[ob->actdef];
BLI_assert(sort_map_update[BKE_object_defgroup_active_index_get(ob)] >= 0);
BKE_object_defgroup_active_index_set(ob,
sort_map_update[BKE_object_defgroup_active_index_get(ob)]);
MEM_freeN(sort_map_update);
@ -4159,6 +4135,7 @@ static void vgroup_sort_bone_hierarchy(Object *ob, ListBase *bonebase)
bonebase = &armature->bonebase;
}
}
ListBase *defbase = BKE_object_defgroup_list_mutable(ob);
if (bonebase != NULL) {
Bone *bone;
@ -4167,8 +4144,8 @@ static void vgroup_sort_bone_hierarchy(Object *ob, ListBase *bonebase)
vgroup_sort_bone_hierarchy(ob, &bone->childbase);
if (dg != NULL) {
BLI_remlink(&ob->defbase, dg);
BLI_addhead(&ob->defbase, dg);
BLI_remlink(defbase, dg);
BLI_addhead(defbase, dg);
}
}
}
@ -4189,10 +4166,12 @@ static int vertex_group_sort_exec(bContext *C, wmOperator *op)
/* Init remapping. */
name_array = vgroup_init_remap(ob);
ListBase *defbase = BKE_object_defgroup_list_mutable(ob);
/* Sort vgroup names. */
switch (sort_type) {
case SORT_TYPE_NAME:
BLI_listbase_sort(&ob->defbase, vgroup_sort_name);
BLI_listbase_sort(defbase, vgroup_sort_name);
break;
case SORT_TYPE_BONEHIERARCHY:
vgroup_sort_bone_hierarchy(ob, NULL);
@ -4250,14 +4229,16 @@ static int vgroup_move_exec(bContext *C, wmOperator *op)
int dir = RNA_enum_get(op->ptr, "direction");
int ret = OPERATOR_FINISHED;
def = BLI_findlink(&ob->defbase, ob->actdef - 1);
ListBase *defbase = BKE_object_defgroup_list_mutable(ob);
def = BLI_findlink(defbase, BKE_object_defgroup_active_index_get(ob) - 1);
if (!def) {
return OPERATOR_CANCELLED;
}
name_array = vgroup_init_remap(ob);
if (BLI_listbase_link_move(&ob->defbase, def, dir)) {
if (BLI_listbase_link_move(defbase, def, dir)) {
ret = vgroup_do_remap(ob, name_array, op);
if (ret != OPERATOR_CANCELLED) {
@ -4376,7 +4357,8 @@ static void vgroup_copy_active_to_sel_single(Object *ob, const int def_nr)
static bool check_vertex_group_accessible(wmOperator *op, Object *ob, int def_nr)
{
bDeformGroup *dg = BLI_findlink(&ob->defbase, def_nr);
const ListBase *defbase = BKE_object_defgroup_list(ob);
bDeformGroup *dg = BLI_findlink(defbase, def_nr);
if (!dg) {
BKE_report(op->reports, RPT_ERROR, "Invalid vertex group index");
@ -4498,7 +4480,7 @@ static int vertex_weight_set_active_exec(bContext *C, wmOperator *op)
const int wg_index = RNA_int_get(op->ptr, "weight_group");
if (wg_index != -1) {
ob->actdef = wg_index + 1;
BKE_object_defgroup_active_index_set(ob, wg_index + 1);
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
}

View File

@ -752,7 +752,7 @@ static int vert_select_ungrouped_exec(bContext *C, wmOperator *op)
Object *ob = CTX_data_active_object(C);
Mesh *me = ob->data;
if (BLI_listbase_is_empty(&ob->defbase) || (me->dvert == NULL)) {
if (BLI_listbase_is_empty(&me->vertex_group_names) || (me->dvert == NULL)) {
BKE_report(op->reports, RPT_ERROR, "No weights/vertex groups on object");
return OPERATOR_CANCELLED;
}

View File

@ -1607,13 +1607,13 @@ static bool wpaint_stroke_test_start(bContext *C, wmOperator *op, const float mo
/* check if we are attempting to paint onto a locked vertex group,
* and other options disallow it from doing anything useful */
bDeformGroup *dg;
dg = BLI_findlink(&ob->defbase, vgroup_index.active);
dg = BLI_findlink(&me->vertex_group_names, vgroup_index.active);
if (dg->flag & DG_LOCK_WEIGHT) {
BKE_report(op->reports, RPT_WARNING, "Active group is locked, aborting");
return false;
}
if (vgroup_index.mirror != -1) {
dg = BLI_findlink(&ob->defbase, vgroup_index.mirror);
dg = BLI_findlink(&me->vertex_group_names, vgroup_index.mirror);
if (dg->flag & DG_LOCK_WEIGHT) {
BKE_report(op->reports, RPT_WARNING, "Mirror group is locked, aborting");
return false;
@ -1622,7 +1622,7 @@ static bool wpaint_stroke_test_start(bContext *C, wmOperator *op, const float mo
}
/* check that multipaint groups are unlocked */
defbase_tot = BLI_listbase_count(&ob->defbase);
defbase_tot = BLI_listbase_count(&me->vertex_group_names);
defbase_sel = BKE_object_defgroup_selected_get(ob, defbase_tot, &defbase_tot_sel);
if (ts->multipaint && defbase_tot_sel > 1) {
@ -1636,7 +1636,7 @@ static bool wpaint_stroke_test_start(bContext *C, wmOperator *op, const float mo
for (i = 0; i < defbase_tot; i++) {
if (defbase_sel[i]) {
dg = BLI_findlink(&ob->defbase, i);
dg = BLI_findlink(&me->vertex_group_names, i);
if (dg->flag & DG_LOCK_WEIGHT) {
BKE_report(op->reports, RPT_WARNING, "Multipaint group is locked, aborting");
MEM_freeN(defbase_sel);
@ -2498,7 +2498,7 @@ static void wpaint_stroke_done(const bContext *C, struct PaintStroke *stroke)
for (psys = ob->particlesystem.first; psys; psys = psys->next) {
for (i = 0; i < PSYS_TOT_VG; i++) {
if (psys->vgroup[i] == ob->actdef) {
if (psys->vgroup[i] == BKE_object_defgroup_active_index_get(ob)) {
psys->recalc |= ID_RECALC_PSYS_RESET;
break;
}

View File

@ -149,7 +149,7 @@ static bool vertex_paint_from_weight(Object *ob)
/* TODO: respect selection. */
/* TODO: Do we want to take weights from evaluated mesh instead? 2.7x was not doing it anyway. */
mp = me->mpoly;
vgroup_active = ob->actdef - 1;
vgroup_active = me->vertex_group_active_index - 1;
for (int i = 0; i < me->totpoly; i++, mp++) {
MLoopCol *lcol = &me->mloopcol[mp->loopstart];
uint j = 0;

View File

@ -183,7 +183,7 @@ static int weight_sample_invoke(bContext *C, wmOperator *op, const wmEvent *even
ED_view3d_viewcontext_init(C, &vc, depsgraph);
me = BKE_mesh_from_object(vc.obact);
if (me && me->dvert && vc.v3d && vc.rv3d && (vc.obact->actdef != 0)) {
if (me && me->dvert && vc.v3d && vc.rv3d && (me->vertex_group_active_index != 0)) {
const bool use_vert_sel = (me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0;
int v_idx_best = -1;
uint index;
@ -213,9 +213,9 @@ static int weight_sample_invoke(bContext *C, wmOperator *op, const wmEvent *even
if (v_idx_best != -1) { /* should always be valid */
ToolSettings *ts = vc.scene->toolsettings;
Brush *brush = BKE_paint_brush(&ts->wpaint->paint);
const int vgroup_active = vc.obact->actdef - 1;
const int vgroup_active = me->vertex_group_active_index - 1;
float vgroup_weight = BKE_defvert_find_weight(&me->dvert[v_idx_best], vgroup_active);
const int defbase_tot = BLI_listbase_count(&vc.obact->defbase);
const int defbase_tot = BLI_listbase_count(&me->vertex_group_names);
bool use_lock_relative = ts->wpaint_lock_relative;
bool *defbase_locked = NULL, *defbase_unlocked = NULL;
@ -331,8 +331,8 @@ static const EnumPropertyItem *weight_paint_sample_enum_itemf(bContext *C,
ED_view3d_viewcontext_init(C, &vc, depsgraph);
me = BKE_mesh_from_object(vc.obact);
if (me && me->dvert && vc.v3d && vc.rv3d && vc.obact->defbase.first) {
const int defbase_tot = BLI_listbase_count(&vc.obact->defbase);
if (me && me->dvert && vc.v3d && vc.rv3d && me->vertex_group_names.first) {
const int defbase_tot = BLI_listbase_count(&me->vertex_group_names);
const bool use_vert_sel = (me->editflag & ME_EDIT_PAINT_VERT_SEL) != 0;
int *groups = MEM_callocN(defbase_tot * sizeof(int), "groups");
bool found = false;
@ -372,7 +372,7 @@ static const EnumPropertyItem *weight_paint_sample_enum_itemf(bContext *C,
int totitem = 0;
int i = 0;
bDeformGroup *dg;
for (dg = vc.obact->defbase.first; dg && i < defbase_tot; i++, dg = dg->next) {
for (dg = me->vertex_group_names.first; dg && i < defbase_tot; i++, dg = dg->next) {
if (groups[i]) {
item_tmp.identifier = item_tmp.name = dg->name;
item_tmp.value = i;
@ -401,7 +401,7 @@ static int weight_sample_group_exec(bContext *C, wmOperator *op)
ED_view3d_viewcontext_init(C, &vc, depsgraph);
BLI_assert(type + 1 >= 0);
vc.obact->actdef = type + 1;
BKE_object_defgroup_active_index_set(vc.obact, type + 1);
DEG_id_tag_update(&vc.obact->id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, vc.obact);
@ -458,7 +458,7 @@ static bool weight_paint_set(Object *ob, float paintweight)
return false;
}
vgroup_active = ob->actdef - 1;
vgroup_active = BKE_object_defgroup_active_index_get(ob) - 1;
/* if mirror painting, find the other group */
if (ME_USING_MIRROR_X_VERTEX_GROUPS(me)) {
@ -815,7 +815,7 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op)
data.sco_start = sco_start;
data.sco_end = sco_end;
data.sco_line_div = 1.0f / len_v2v2(sco_start, sco_end);
data.def_nr = ob->actdef - 1;
data.def_nr = BKE_object_defgroup_active_index_get(ob) - 1;
data.use_select = (me->editflag & (ME_EDIT_PAINT_FACE_SEL | ME_EDIT_PAINT_VERT_SEL)) != 0;
data.vert_cache = vert_cache;
data.vert_visit = NULL;
@ -863,7 +863,7 @@ static int paint_weight_gradient_exec(bContext *C, wmOperator *op)
}
if (scene->toolsettings->auto_normalize) {
const int vgroup_num = BLI_listbase_count(&ob->defbase);
const int vgroup_num = BLI_listbase_count(&me->vertex_group_names);
bool *vgroup_validmap = BKE_object_defgroup_validmap_get(ob, vgroup_num);
if (vgroup_validmap != NULL) {
MDeformVert *dvert = me->dvert;

View File

@ -79,8 +79,10 @@ bool ED_wpaint_ensure_data(bContext *C,
WM_event_add_notifier(C, NC_GEOM | ND_DATA, me);
}
const ListBase *defbase = BKE_object_defgroup_list(ob);
/* this happens on a Bone select, when no vgroup existed yet */
if (ob->actdef <= 0) {
if (me->vertex_group_active_index <= 0) {
Object *modob;
if ((modob = BKE_modifiers_is_deformed_by_armature(ob))) {
Bone *actbone = ((bArmature *)modob->data)->act_bone;
@ -94,32 +96,33 @@ bool ED_wpaint_ensure_data(bContext *C,
DEG_relations_tag_update(CTX_data_main(C));
}
else {
int actdef = 1 + BLI_findindex(&ob->defbase, dg);
int actdef = 1 + BLI_findindex(defbase, dg);
BLI_assert(actdef >= 0);
ob->actdef = actdef;
me->vertex_group_active_index = actdef;
}
}
}
}
}
if (BLI_listbase_is_empty(&ob->defbase)) {
if (BLI_listbase_is_empty(defbase)) {
BKE_object_defgroup_add(ob);
DEG_relations_tag_update(CTX_data_main(C));
}
/* ensure we don't try paint onto an invalid group */
if (ob->actdef <= 0) {
if (me->vertex_group_active_index <= 0) {
BKE_report(reports, RPT_WARNING, "No active vertex group for painting, aborting");
return false;
}
if (vgroup_index) {
vgroup_index->active = ob->actdef - 1;
vgroup_index->active = me->vertex_group_active_index - 1;
}
if (flag & WPAINT_ENSURE_MIRROR) {
if (ME_USING_MIRROR_X_VERTEX_GROUPS(me)) {
int mirror = ED_wpaint_mirror_vgroup_ensure(ob, ob->actdef - 1);
int mirror = ED_wpaint_mirror_vgroup_ensure(ob, me->vertex_group_active_index - 1);
if (vgroup_index) {
vgroup_index->mirror = mirror;
}
@ -133,7 +136,8 @@ bool ED_wpaint_ensure_data(bContext *C,
/* mirror_vgroup is set to -1 when invalid */
int ED_wpaint_mirror_vgroup_ensure(Object *ob, const int vgroup_active)
{
bDeformGroup *defgroup = BLI_findlink(&ob->defbase, vgroup_active);
const ListBase *defbase = BKE_object_defgroup_list(ob);
bDeformGroup *defgroup = BLI_findlink(defbase, vgroup_active);
if (defgroup) {
int mirrdef;
@ -143,7 +147,7 @@ int ED_wpaint_mirror_vgroup_ensure(Object *ob, const int vgroup_active)
mirrdef = BKE_object_defgroup_name_index(ob, name_flip);
if (mirrdef == -1) {
if (BKE_object_defgroup_new(ob, name_flip)) {
mirrdef = BLI_listbase_count(&ob->defbase) - 1;
mirrdef = BLI_listbase_count(defbase) - 1;
}
}

View File

@ -42,6 +42,7 @@
#include "BKE_collection.h"
#include "BKE_constraint.h"
#include "BKE_context.h"
#include "BKE_deform.h"
#include "BKE_gpencil.h"
#include "BKE_gpencil_modifier.h"
#include "BKE_layer.h"
@ -450,7 +451,7 @@ static void tree_element_defgroup_activate(bContext *C, TreeElement *te, TreeSto
/* id in tselem is object */
Object *ob = (Object *)tselem->id;
BLI_assert(te->index + 1 >= 0);
ob->actdef = te->index + 1;
BKE_object_defgroup_active_index_set(ob, te->index + 1);
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, ob);
@ -830,7 +831,7 @@ static eOLDrawState tree_element_defgroup_state_get(const ViewLayer *view_layer,
{
const Object *ob = (const Object *)tselem->id;
if (ob == OBACT(view_layer)) {
if (ob->actdef == te->index + 1) {
if (BKE_object_defgroup_active_index_get(ob) == te->index + 1) {
return OL_DRAWSEL_NORMAL;
}
}

View File

@ -1,4 +1,4 @@
/*
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
@ -62,6 +62,7 @@
#include "BLT_translation.h"
#include "BKE_armature.h"
#include "BKE_deform.h"
#include "BKE_layer.h"
#include "BKE_lib_id.h"
#include "BKE_main.h"
@ -552,17 +553,20 @@ static void outliner_add_object_contents(SpaceOutliner *space_outliner,
}
/* vertex groups */
if (!BLI_listbase_is_empty(&ob->defbase)) {
TreeElement *tenla = outliner_add_element(
space_outliner, &te->subtree, ob, te, TSE_DEFGROUP_BASE, 0);
tenla->name = IFACE_("Vertex Groups");
if (ELEM(ob->type, OB_MESH, OB_GPENCIL, OB_LATTICE)) {
const ListBase *defbase = BKE_object_defgroup_list(ob);
if (!BLI_listbase_is_empty(defbase)) {
TreeElement *tenla = outliner_add_element(
space_outliner, &te->subtree, ob, te, TSE_DEFGROUP_BASE, 0);
tenla->name = IFACE_("Vertex Groups");
int index;
LISTBASE_FOREACH_INDEX (bDeformGroup *, defgroup, &ob->defbase, index) {
TreeElement *ten = outliner_add_element(
space_outliner, &tenla->subtree, ob, tenla, TSE_DEFGROUP, index);
ten->name = defgroup->name;
ten->directdata = defgroup;
int index;
LISTBASE_FOREACH_INDEX (bDeformGroup *, defgroup, defbase, index) {
TreeElement *ten = outliner_add_element(
space_outliner, &tenla->subtree, ob, tenla, TSE_DEFGROUP, index);
ten->name = defgroup->name;
ten->directdata = defgroup;
}
}
}

View File

@ -414,7 +414,6 @@ GeometrySet spreadsheet_get_display_geometry_set(const SpaceSpreadsheet *sspread
Mesh *mesh = (Mesh *)object_orig->data;
mesh_component.replace(mesh, GeometryOwnershipType::ReadOnly);
}
mesh_component.copy_vertex_group_names_from_object(*object_orig);
}
else if (object_orig->type == OB_POINTCLOUD) {
PointCloud *pointcloud = (PointCloud *)object_orig->data;
@ -432,7 +431,6 @@ GeometrySet spreadsheet_get_display_geometry_set(const SpaceSpreadsheet *sspread
BKE_mesh_wrapper_ensure_mdata(mesh);
MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>();
mesh_component.replace(mesh, GeometryOwnershipType::ReadOnly);
mesh_component.copy_vertex_group_names_from_object(*object_eval);
}
else {
if (BLI_listbase_count(&sspreadsheet->context_path) == 1) {

View File

@ -1310,7 +1310,9 @@ static void view3d_panel_vgroup(const bContext *C, Panel *panel)
vgroup_validmap = BKE_object_defgroup_subset_from_select_type(
ob, subset_type, &vgroup_tot, &subset_count);
for (i = 0, dg = ob->defbase.first; dg; i++, dg = dg->next) {
const ListBase *defbase = BKE_object_defgroup_list(ob);
for (i = 0, dg = defbase->first; dg; i++, dg = dg->next) {
bool locked = (dg->flag & DG_LOCK_WEIGHT) != 0;
if (vgroup_validmap[i]) {
MDeformWeight *dw = BKE_defvert_find_index(dv, i);
@ -1336,7 +1338,7 @@ static void view3d_panel_vgroup(const bContext *C, Panel *panel)
but_ptr = UI_but_operator_ptr_get(but);
RNA_int_set(but_ptr, "weight_group", i);
UI_but_drawflag_enable(but, UI_BUT_TEXT_RIGHT);
if (ob->actdef != i + 1) {
if (BKE_object_defgroup_active_index_get(ob) != i + 1) {
UI_but_flag_enable(but, UI_BUT_INACTIVE);
}
xco += x;

View File

@ -4302,7 +4302,7 @@ static void lineart_gpencil_generate(LineartCache *cache,
int dindex = 0;
Mesh *me = (Mesh *)eval_ob->data;
if (me->dvert) {
LISTBASE_FOREACH (bDeformGroup *, db, &eval_ob->defbase) {
LISTBASE_FOREACH (bDeformGroup *, db, &me->vertex_group_names) {
if ((!source_vgname) || strstr(db->name, source_vgname) == db->name) {
if (match_output) {
gpdg = BKE_object_defgroup_name_index(gpencil_object, db->name);

View File

@ -29,6 +29,7 @@
#include "BKE_action.h"
#include "BKE_armature.h"
#include "BKE_deform.h"
#include "BKE_global.h"
#include "BKE_idprop.h"
#include "BKE_lib_id.h"
@ -194,9 +195,9 @@ void ControllerExporter::export_skin_controller(Object *ob, Object *ob_arm)
add_bind_shape_mat(ob);
std::string joints_source_id = add_joints_source(ob_arm, &ob->defbase, controller_id);
std::string inv_bind_mat_source_id = add_inv_bind_mats_source(
ob_arm, &ob->defbase, controller_id);
const ListBase *defbase = BKE_object_defgroup_list(ob);
std::string joints_source_id = add_joints_source(ob_arm, defbase, controller_id);
std::string inv_bind_mat_source_id = add_inv_bind_mats_source(ob_arm, defbase, controller_id);
std::list<int> vcounts;
std::list<int> joints;
@ -207,9 +208,9 @@ void ControllerExporter::export_skin_controller(Object *ob, Object *ob_arm)
/* def group index -> joint index */
std::vector<int> joint_index_by_def_index;
bDeformGroup *def;
const bDeformGroup *def;
for (def = (bDeformGroup *)ob->defbase.first, i = 0, j = 0; def; def = def->next, i++) {
for (def = (const bDeformGroup *)defbase->first, i = 0, j = 0; def; def = def->next, i++) {
if (is_bone_defgroup(ob_arm, def)) {
joint_index_by_def_index.push_back(j++);
}
@ -269,7 +270,7 @@ void ControllerExporter::export_skin_controller(Object *ob, Object *ob_arm)
}
std::string weights_source_id = add_weights_source(me, controller_id, weights);
add_joints_element(&ob->defbase, joints_source_id, inv_bind_mat_source_id);
add_joints_element(defbase, joints_source_id, inv_bind_mat_source_id);
add_vertex_weights_element(weights_source_id, joints_source_id, vcounts, joints);
BKE_id_free(nullptr, me);
@ -392,7 +393,7 @@ void ControllerExporter::add_weight_extras(Key *key)
}
}
void ControllerExporter::add_joints_element(ListBase *defbase,
void ControllerExporter::add_joints_element(const ListBase *defbase,
const std::string &joints_source_id,
const std::string &inv_bind_mat_source_id)
{
@ -431,7 +432,7 @@ void ControllerExporter::add_bind_shape_mat(Object *ob)
}
std::string ControllerExporter::add_joints_source(Object *ob_arm,
ListBase *defbase,
const ListBase *defbase,
const std::string &controller_id)
{
std::string source_id = controller_id + JOINTS_SOURCE_ID_SUFFIX;
@ -468,7 +469,7 @@ std::string ControllerExporter::add_joints_source(Object *ob_arm,
}
std::string ControllerExporter::add_inv_bind_mats_source(Object *ob_arm,
ListBase *defbase,
const ListBase *defbase,
const std::string &controller_id)
{
std::string source_id = controller_id + BIND_POSES_SOURCE_ID_SUFFIX;
@ -568,13 +569,13 @@ std::string ControllerExporter::add_inv_bind_mats_source(Object *ob_arm,
return source_id;
}
Bone *ControllerExporter::get_bone_from_defgroup(Object *ob_arm, bDeformGroup *def)
Bone *ControllerExporter::get_bone_from_defgroup(Object *ob_arm, const bDeformGroup *def)
{
bPoseChannel *pchan = BKE_pose_channel_find_name(ob_arm->pose, def->name);
return pchan ? pchan->bone : nullptr;
}
bool ControllerExporter::is_bone_defgroup(Object *ob_arm, bDeformGroup *def)
bool ControllerExporter::is_bone_defgroup(Object *ob_arm, const bDeformGroup *def)
{
return get_bone_from_defgroup(ob_arm, def) != nullptr;
}

View File

@ -97,7 +97,7 @@ class ControllerExporter : public COLLADASW::LibraryControllers,
void export_morph_controller(Object *ob, Key *key);
void add_joints_element(ListBase *defbase,
void add_joints_element(const ListBase *defbase,
const std::string &joints_source_id,
const std::string &inv_bind_mat_source_id);
@ -110,16 +110,16 @@ class ControllerExporter : public COLLADASW::LibraryControllers,
void add_weight_extras(Key *key);
std::string add_joints_source(Object *ob_arm,
ListBase *defbase,
const ListBase *defbase,
const std::string &controller_id);
std::string add_inv_bind_mats_source(Object *ob_arm,
ListBase *defbase,
const ListBase *defbase,
const std::string &controller_id);
Bone *get_bone_from_defgroup(Object *ob_arm, bDeformGroup *def);
Bone *get_bone_from_defgroup(Object *ob_arm, const bDeformGroup *def);
bool is_bone_defgroup(Object *ob_arm, bDeformGroup *def);
bool is_bone_defgroup(Object *ob_arm, const bDeformGroup *def);
std::string add_weights_source(Mesh *me,
const std::string &controller_id,

View File

@ -36,6 +36,7 @@
#include "DNA_scene_types.h"
#include "BKE_action.h"
#include "BKE_deform.h"
#include "BKE_object.h"
#include "BKE_object_deform.h"
@ -289,7 +290,8 @@ void SkinInfo::link_armature(bContext *C,
/* -1 means "weight towards the bind shape", we just don't assign it to any group */
if (joint != -1) {
bDeformGroup *def = (bDeformGroup *)BLI_findlink(&ob->defbase, joint);
const ListBase *defbase = BKE_object_defgroup_list(ob);
bDeformGroup *def = (bDeformGroup *)BLI_findlink(defbase, joint);
ED_vgroup_vert_add(ob, def, vertex, weights[joint_weight], WEIGHT_REPLACE);
}

View File

@ -666,6 +666,9 @@ typedef struct bGPdata {
/** List of bGPDpalette's - Deprecated (2.78 - 2.79 only). */
ListBase palettes DNA_DEPRECATED;
/** List of bDeformGroup names and flag only. */
ListBase vertex_group_names;
/* 3D Viewport/Appearance Settings */
/** Factor to define pixel size conversion. */
float pixfactor;
@ -715,7 +718,8 @@ typedef struct bGPdata {
/** Stroke selection last index. Used to generate a unique selection index. */
int select_last_index;
char _pad3[4];
int vertex_group_active_index;
bGPgrid grid;

View File

@ -72,6 +72,11 @@ typedef struct Lattice {
struct MDeformVert *dvert;
/** Multiply the influence, MAX_VGROUP_NAME. */
char vgroup[64];
/** List of bDeformGroup names and flag only. */
ListBase vertex_group_names;
int vertex_group_active_index;
char _pad0[4];
struct EditLatt *editlatt;
void *batch_cache;

View File

@ -166,6 +166,8 @@ typedef struct Mesh {
struct MEdge *medge;
/** Deform-group vertices. */
struct MDeformVert *dvert;
/** List of bDeformGroup names and flag only. */
ListBase vertex_group_names;
/* array of colors for the tessellated faces, must be number of tessellated
* faces * 4 in length */
@ -189,7 +191,7 @@ typedef struct Mesh {
/* END BMESH ONLY */
int attributes_active_index;
int _pad3;
int vertex_group_active_index;
/* the last selected vertex/edge/face are used for the active face however
* this means the active face must always be selected, this is to keep track
@ -279,9 +281,9 @@ enum {
/* We can't have both flags enabled at once,
* flags defined in DNA_scene_types.h */
#define ME_EDIT_PAINT_SEL_MODE(_me) \
(((_me)->editflag & ME_EDIT_PAINT_FACE_SEL) ? \
SCE_SELECT_FACE : \
((_me)->editflag & ME_EDIT_PAINT_VERT_SEL) ? SCE_SELECT_VERTEX : 0)
(((_me)->editflag & ME_EDIT_PAINT_FACE_SEL) ? SCE_SELECT_FACE : \
((_me)->editflag & ME_EDIT_PAINT_VERT_SEL) ? SCE_SELECT_VERTEX : \
0)
/* me->flag */
enum {

View File

@ -272,8 +272,7 @@ typedef struct Object {
ListBase constraintChannels DNA_DEPRECATED; /* XXX deprecated... old animation system */
ListBase effect DNA_DEPRECATED; /* XXX deprecated... keep for readfile */
/** List of bDeformGroup (vertex groups) names and flag only. */
ListBase defbase;
ListBase defbase DNA_DEPRECATED; /* Only for versioning, moved to object data. */
/** List of ModifierData structures. */
ListBase modifiers;
/** List of GpencilModifierData structures. */
@ -375,7 +374,7 @@ typedef struct Object {
/** Custom index, for renderpasses. */
short index;
/** Current deformation group, NOTE: index starts at 1. */
unsigned short actdef;
unsigned short actdef DNA_DEPRECATED;
/** Current face map, NOTE: index starts at 1. */
unsigned short actfmap;
char _pad2[2];

View File

@ -602,6 +602,7 @@ const EnumPropertyItem rna_enum_axis_flag_xyz_items[] = {
# include "BKE_cachefile.h"
# include "BKE_context.h"
# include "BKE_deform.h"
# include "BKE_mesh_runtime.h"
# include "BKE_modifier.h"
# include "BKE_object.h"
@ -1250,12 +1251,13 @@ static const EnumPropertyItem *rna_DataTransferModifier_layers_select_src_itemf(
# endif
if (ob_src) {
bDeformGroup *dg;
const bDeformGroup *dg;
int i;
RNA_enum_item_add_separator(&item, &totitem);
for (i = 0, dg = ob_src->defbase.first; dg; i++, dg = dg->next) {
const ListBase *defbase = BKE_object_defgroup_list(ob_src);
for (i = 0, dg = defbase->first; dg; i++, dg = dg->next) {
tmp_item.value = i;
tmp_item.identifier = tmp_item.name = dg->name;
RNA_enum_item_add(&item, &totitem, &tmp_item);
@ -1349,12 +1351,13 @@ static const EnumPropertyItem *rna_DataTransferModifier_layers_select_dst_itemf(
Object *ob_dst = CTX_data_active_object(C); /* XXX Is this OK? */
if (ob_dst) {
bDeformGroup *dg;
const bDeformGroup *dg;
int i;
RNA_enum_item_add_separator(&item, &totitem);
for (i = 0, dg = ob_dst->defbase.first; dg; i++, dg = dg->next) {
const ListBase *defbase = BKE_object_defgroup_list(ob_dst);
for (i = 0, dg = defbase->first; dg; i++, dg = dg->next) {
tmp_item.value = i;
tmp_item.identifier = tmp_item.name = dg->name;
RNA_enum_item_add(&item, &totitem, &tmp_item);

View File

@ -790,9 +790,27 @@ static void rna_Object_dup_collection_set(PointerRNA *ptr,
}
}
static void rna_Object_vertex_groups_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
{
Object *ob = (Object *)ptr->data;
if (!BKE_object_supports_vertex_groups(ob)) {
iter->valid = 0;
return;
}
ListBase *defbase = BKE_object_defgroup_list_mutable(ob);
iter->valid = defbase != NULL;
rna_iterator_listbase_begin(iter, defbase, NULL);
}
static void rna_VertexGroup_name_set(PointerRNA *ptr, const char *value)
{
Object *ob = (Object *)ptr->owner_id;
if (!BKE_object_supports_vertex_groups(ob)) {
return;
}
bDeformGroup *dg = (bDeformGroup *)ptr->data;
BLI_strncpy_utf8(dg->name, value, sizeof(dg->name));
BKE_object_defgroup_unique_name(dg, ob);
@ -801,15 +819,25 @@ static void rna_VertexGroup_name_set(PointerRNA *ptr, const char *value)
static int rna_VertexGroup_index_get(PointerRNA *ptr)
{
Object *ob = (Object *)ptr->owner_id;
if (!BKE_object_supports_vertex_groups(ob)) {
return -1;
}
return BLI_findindex(&ob->defbase, ptr->data);
const ListBase *defbase = BKE_object_defgroup_list(ob);
return BLI_findindex(defbase, ptr->data);
}
static PointerRNA rna_Object_active_vertex_group_get(PointerRNA *ptr)
{
Object *ob = (Object *)ptr->owner_id;
if (!BKE_object_supports_vertex_groups(ob)) {
return PointerRNA_NULL;
}
const ListBase *defbase = BKE_object_defgroup_list(ob);
return rna_pointer_inherit_refine(
ptr, &RNA_VertexGroup, BLI_findlink(&ob->defbase, ob->actdef - 1));
ptr, &RNA_VertexGroup, BLI_findlink(defbase, BKE_object_defgroup_active_index_get(ob) - 1));
}
static void rna_Object_active_vertex_group_set(PointerRNA *ptr,
@ -817,7 +845,13 @@ static void rna_Object_active_vertex_group_set(PointerRNA *ptr,
struct ReportList *reports)
{
Object *ob = (Object *)ptr->owner_id;
int index = BLI_findindex(&ob->defbase, value.data);
if (!BKE_object_supports_vertex_groups(ob)) {
return;
}
const ListBase *defbase = BKE_object_defgroup_list(ob);
int index = BLI_findindex(defbase, value.data);
if (index == -1) {
BKE_reportf(reports,
RPT_ERROR,
@ -827,19 +861,27 @@ static void rna_Object_active_vertex_group_set(PointerRNA *ptr,
return;
}
ob->actdef = index + 1;
BKE_object_defgroup_active_index_set(ob, index + 1);
}
static int rna_Object_active_vertex_group_index_get(PointerRNA *ptr)
{
Object *ob = (Object *)ptr->owner_id;
return ob->actdef - 1;
if (!BKE_object_supports_vertex_groups(ob)) {
return -1;
}
return BKE_object_defgroup_active_index_get(ob) - 1;
}
static void rna_Object_active_vertex_group_index_set(PointerRNA *ptr, int value)
{
Object *ob = (Object *)ptr->owner_id;
ob->actdef = value + 1;
if (!BKE_object_supports_vertex_groups(ob)) {
return;
}
BKE_object_defgroup_active_index_set(ob, value + 1);
}
static void rna_Object_active_vertex_group_index_range(
@ -848,15 +890,24 @@ static void rna_Object_active_vertex_group_index_range(
Object *ob = (Object *)ptr->owner_id;
*min = 0;
*max = max_ii(0, BLI_listbase_count(&ob->defbase) - 1);
if (!BKE_object_supports_vertex_groups(ob)) {
*max = 0;
return;
}
const ListBase *defbase = BKE_object_defgroup_list(ob);
*max = max_ii(0, BLI_listbase_count(defbase) - 1);
}
void rna_object_vgroup_name_index_get(PointerRNA *ptr, char *value, int index)
{
Object *ob = (Object *)ptr->owner_id;
bDeformGroup *dg;
if (!BKE_object_supports_vertex_groups(ob)) {
value[0] = '\0';
return;
}
dg = BLI_findlink(&ob->defbase, index - 1);
const ListBase *defbase = BKE_object_defgroup_list(ob);
const bDeformGroup *dg = BLI_findlink(defbase, index - 1);
if (dg) {
BLI_strncpy(value, dg->name, sizeof(dg->name));
@ -869,21 +920,34 @@ void rna_object_vgroup_name_index_get(PointerRNA *ptr, char *value, int index)
int rna_object_vgroup_name_index_length(PointerRNA *ptr, int index)
{
Object *ob = (Object *)ptr->owner_id;
bDeformGroup *dg;
if (!BKE_object_supports_vertex_groups(ob)) {
return 0;
}
dg = BLI_findlink(&ob->defbase, index - 1);
const ListBase *defbase = BKE_object_defgroup_list(ob);
bDeformGroup *dg = BLI_findlink(defbase, index - 1);
return (dg) ? strlen(dg->name) : 0;
}
void rna_object_vgroup_name_index_set(PointerRNA *ptr, const char *value, short *index)
{
Object *ob = (Object *)ptr->owner_id;
if (!BKE_object_supports_vertex_groups(ob)) {
*index = -1;
return;
}
*index = BKE_object_defgroup_name_index(ob, value) + 1;
}
void rna_object_vgroup_name_set(PointerRNA *ptr, const char *value, char *result, int maxlen)
{
Object *ob = (Object *)ptr->owner_id;
if (!BKE_object_supports_vertex_groups(ob)) {
result[0] = '\0';
return;
}
bDeformGroup *dg = BKE_object_defgroup_find_name(ob, value);
if (dg) {
/* No need for BLI_strncpy_utf8, since this matches an existing group. */
@ -1960,7 +2024,9 @@ static void rna_Object_vgroup_remove(Object *ob,
PointerRNA *defgroup_ptr)
{
bDeformGroup *defgroup = defgroup_ptr->data;
if (BLI_findindex(&ob->defbase, defgroup) == -1) {
ListBase *defbase = BKE_object_defgroup_list_mutable(ob);
if (BLI_findindex(defbase, defgroup) == -1) {
BKE_reportf(reports,
RPT_ERROR,
"DeformGroup '%s' not in object '%s'",
@ -2687,7 +2753,6 @@ static void rna_def_object_vertex_groups(BlenderRNA *brna, PropertyRNA *cprop)
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, "actdef");
RNA_def_property_int_funcs(prop,
"rna_Object_active_vertex_group_index_get",
"rna_Object_active_vertex_group_index_set",
@ -3274,7 +3339,15 @@ static void rna_def_object(BlenderRNA *brna)
/* vertex groups */
prop = RNA_def_property(srna, "vertex_groups", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "defbase", NULL);
RNA_def_property_collection_funcs(prop,
"rna_Object_vertex_groups_begin",
"rna_iterator_listbase_next",
"rna_iterator_listbase_end",
"rna_iterator_listbase_get",
NULL,
NULL,
NULL,
NULL);
RNA_def_property_struct_type(prop, "VertexGroup");
RNA_def_property_override_clear_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
RNA_def_property_ui_text(prop, "Vertex Groups", "Vertex groups of the object");

View File

@ -1430,9 +1430,10 @@ static void psys_vg_name_get__internal(PointerRNA *ptr, char *value, int index)
{
Object *ob = (Object *)ptr->owner_id;
ParticleSystem *psys = (ParticleSystem *)ptr->data;
const ListBase *defbase = BKE_object_defgroup_list(ob);
if (psys->vgroup[index] > 0) {
bDeformGroup *defGroup = BLI_findlink(&ob->defbase, psys->vgroup[index] - 1);
bDeformGroup *defGroup = BLI_findlink(defbase, psys->vgroup[index] - 1);
if (defGroup) {
strcpy(value, defGroup->name);
@ -1448,7 +1449,8 @@ static int psys_vg_name_len__internal(PointerRNA *ptr, int index)
ParticleSystem *psys = (ParticleSystem *)ptr->data;
if (psys->vgroup[index] > 0) {
bDeformGroup *defGroup = BLI_findlink(&ob->defbase, psys->vgroup[index] - 1);
const ListBase *defbase = BKE_object_defgroup_list(ob);
bDeformGroup *defGroup = BLI_findlink(defbase, psys->vgroup[index] - 1);
if (defGroup) {
return strlen(defGroup->name);

View File

@ -37,6 +37,7 @@
#include "BKE_action.h"
#include "BKE_armature.h"
#include "BKE_context.h"
#include "BKE_deform.h"
#include "BKE_editmesh.h"
#include "BKE_lib_id.h"
#include "BKE_lib_query.h"
@ -122,7 +123,8 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte
/* If neither vertex groups nor envelopes are used, the modifier has no bone dependencies. */
if ((amd->deformflag & ARM_DEF_VGROUP) != 0) {
/* Enumerate groups that match existing bones. */
LISTBASE_FOREACH (bDeformGroup *, dg, &ctx->object->defbase) {
const ListBase *defbase = BKE_object_defgroup_list(ctx->object);
LISTBASE_FOREACH (bDeformGroup *, dg, defbase) {
if (BKE_pose_channel_find_name(amd->object->pose, dg->name) != NULL) {
/* Can't check BONE_NO_DEFORM because it can be animated. */
DEG_add_bone_relation(

View File

@ -167,7 +167,7 @@ static void deformVertsEM(ModifierData *md,
int defgrp_index = -1;
if (ctx->object->type == OB_MESH && cmd->name[0] != '\0') {
defgrp_index = BKE_object_defgroup_name_index(ctx->object, cmd->name);
defgrp_index = BKE_id_defgroup_name_index(&mesh->id, cmd->name);
if (defgrp_index != -1) {
use_dverts = true;
}

View File

@ -119,7 +119,7 @@ static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphConte
/* A vertex will be in the mask if a selected bone influences it more than a certain threshold. */
static void compute_vertex_mask__armature_mode(MDeformVert *dvert,
Object *ob,
Mesh *mesh,
Object *armature_ob,
float threshold,
MutableSpan<bool> r_vertex_mask)
@ -127,7 +127,7 @@ static void compute_vertex_mask__armature_mode(MDeformVert *dvert,
/* Element i is true if there is a selected bone that uses vertex group i. */
Vector<bool> selected_bone_uses_group;
for (bDeformGroup *def : ListBaseWrapper<bDeformGroup>(ob->defbase)) {
LISTBASE_FOREACH (bDeformGroup *, def, &mesh->vertex_group_names) {
bPoseChannel *pchan = BKE_pose_channel_find_name(armature_ob->pose, def->name);
bool bone_for_group_exists = pchan && pchan->bone && (pchan->bone->flag & BONE_SELECTED);
selected_bone_uses_group.append(bone_for_group_exists);
@ -325,10 +325,9 @@ void copy_masked_polys_to_new_mesh(const Mesh &src_mesh,
* 2. Find edges and polygons only using those vertices.
* 3. Create a new mesh that only uses the found vertices, edges and polygons.
*/
static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *UNUSED(ctx), Mesh *mesh)
{
MaskModifierData *mmd = reinterpret_cast<MaskModifierData *>(md);
Object *ob = ctx->object;
const bool invert_mask = mmd->flag & MOD_MASK_INV;
/* Return empty or input mesh when there are no vertex groups. */
@ -339,7 +338,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
/* Quick test to see if we can return early. */
if (!(ELEM(mmd->mode, MOD_MASK_MODE_ARM, MOD_MASK_MODE_VGROUP)) || (mesh->totvert == 0) ||
BLI_listbase_is_empty(&ob->defbase)) {
BLI_listbase_is_empty(&mesh->vertex_group_names)) {
return mesh;
}
@ -348,15 +347,15 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
Object *armature_ob = mmd->ob_arm;
/* Return input mesh if there is no armature with bones. */
if (ELEM(NULL, armature_ob, armature_ob->pose, ob->defbase.first)) {
if (ELEM(NULL, armature_ob, armature_ob->pose)) {
return mesh;
}
vertex_mask = Array<bool>(mesh->totvert);
compute_vertex_mask__armature_mode(dvert, ob, armature_ob, mmd->threshold, vertex_mask);
compute_vertex_mask__armature_mode(dvert, mesh, armature_ob, mmd->threshold, vertex_mask);
}
else {
int defgrp_index = BKE_object_defgroup_name_index(ob, mmd->vgroup);
int defgrp_index = BKE_id_defgroup_name_index(&mesh->id, mmd->vgroup);
/* Return input mesh if the vertex group does not exist. */
if (defgrp_index == -1) {

View File

@ -1018,8 +1018,7 @@ static void modifyGeometry(ModifierData *md,
static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh)
{
GeometrySet geometry_set = GeometrySet::create_with_mesh(mesh, GeometryOwnershipType::Editable);
geometry_set.get_component_for_write<MeshComponent>().copy_vertex_group_names_from_object(
*ctx->object);
modifyGeometry(md, ctx, geometry_set);
if (ctx->flag & MOD_APPLY_TO_BASE_MESH) {

View File

@ -242,9 +242,8 @@ Mesh *MOD_solidify_extrude_modifyMesh(ModifierData *md, const ModifierEvalContex
MDeformVert *dvert;
const bool defgrp_invert = (smd->flag & MOD_SOLIDIFY_VGROUP_INV) != 0;
int defgrp_index;
const int shell_defgrp_index = BKE_object_defgroup_name_index(ctx->object,
smd->shell_defgrp_name);
const int rim_defgrp_index = BKE_object_defgroup_name_index(ctx->object, smd->rim_defgrp_name);
const int shell_defgrp_index = BKE_id_defgroup_name_index(&mesh->id, smd->shell_defgrp_name);
const int rim_defgrp_index = BKE_id_defgroup_name_index(&mesh->id, smd->rim_defgrp_name);
/* array size is doubled in case of using a shell */
const uint stride = do_shell ? 2 : 1;

View File

@ -181,9 +181,8 @@ Mesh *MOD_solidify_nonmanifold_modifyMesh(ModifierData *md,
MDeformVert *dvert;
const bool defgrp_invert = (smd->flag & MOD_SOLIDIFY_VGROUP_INV) != 0;
int defgrp_index;
const int shell_defgrp_index = BKE_object_defgroup_name_index(ctx->object,
smd->shell_defgrp_name);
const int rim_defgrp_index = BKE_object_defgroup_name_index(ctx->object, smd->rim_defgrp_name);
const int shell_defgrp_index = BKE_id_defgroup_name_index(&mesh->id, smd->shell_defgrp_name);
const int rim_defgrp_index = BKE_id_defgroup_name_index(&mesh->id, smd->rim_defgrp_name);
MOD_get_vgroup(ctx->object, mesh, smd->defgrp_name, &dvert, &defgrp_index);

View File

@ -254,15 +254,22 @@ Mesh *MOD_deform_mesh_eval_get(Object *ob,
void MOD_get_vgroup(
Object *ob, struct Mesh *mesh, const char *name, MDeformVert **dvert, int *defgrp_index)
{
*defgrp_index = BKE_object_defgroup_name_index(ob, name);
*dvert = NULL;
if (*defgrp_index != -1) {
if (ob->type == OB_LATTICE) {
if (mesh) {
*defgrp_index = BKE_id_defgroup_name_index(&mesh->id, name);
if (*defgrp_index != -1) {
*dvert = mesh->dvert;
}
else {
*dvert = NULL;
}
}
else {
*defgrp_index = BKE_object_defgroup_name_index(ob, name);
if (*defgrp_index != -1 && ob->type == OB_LATTICE) {
*dvert = BKE_lattice_deform_verts_get(ob);
}
else if (mesh) {
*dvert = mesh->dvert;
else {
*dvert = NULL;
}
}
}

View File

@ -230,7 +230,7 @@ void weightvg_do_mask(const ModifierEvalContext *ctx,
MEM_freeN(tex_co);
}
else if ((ref_didx = BKE_object_defgroup_name_index(ob, defgrp_name)) != -1) {
else if ((ref_didx = BKE_id_defgroup_name_index(&mesh->id, defgrp_name)) != -1) {
MDeformVert *dvert = NULL;
/* Check whether we want to set vgroup weights from a constant weight factor or a vertex

View File

@ -194,12 +194,12 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
/* Check if we can just return the original mesh.
* Must have verts and therefore verts assigned to vgroups to do anything useful!
*/
if ((numVerts == 0) || BLI_listbase_is_empty(&ctx->object->defbase)) {
if ((numVerts == 0) || BLI_listbase_is_empty(&mesh->vertex_group_names)) {
return mesh;
}
/* Get vgroup idx from its name. */
const int defgrp_index = BKE_object_defgroup_name_index(ctx->object, wmd->defgrp_name);
const int defgrp_index = BKE_id_defgroup_name_index(&mesh->id, wmd->defgrp_name);
if (defgrp_index == -1) {
return mesh;
}

View File

@ -245,19 +245,19 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
/* Check if we can just return the original mesh.
* Must have verts and therefore verts assigned to vgroups to do anything useful!
*/
if ((numVerts == 0) || BLI_listbase_is_empty(&ctx->object->defbase)) {
if ((numVerts == 0) || BLI_listbase_is_empty(&mesh->vertex_group_names)) {
return mesh;
}
/* Get vgroup idx from its name. */
const int defgrp_index = BKE_object_defgroup_name_index(ctx->object, wmd->defgrp_name_a);
const int defgrp_index = BKE_id_defgroup_name_index(&mesh->id, wmd->defgrp_name_a);
if (defgrp_index == -1) {
return mesh;
}
/* Get second vgroup idx from its name, if given. */
int defgrp_index_other = -1;
if (wmd->defgrp_name_b[0] != '\0') {
defgrp_index_other = BKE_object_defgroup_name_index(ctx->object, wmd->defgrp_name_b);
defgrp_index_other = BKE_id_defgroup_name_index(&mesh->id, wmd->defgrp_name_b);
if (defgrp_index_other == -1) {
return mesh;
}

View File

@ -468,7 +468,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
/* Check if we can just return the original mesh.
* Must have verts and therefore verts assigned to vgroups to do anything useful!
*/
if ((numVerts == 0) || BLI_listbase_is_empty(&ctx->object->defbase)) {
if ((numVerts == 0) || BLI_listbase_is_empty(&mesh->vertex_group_names)) {
return mesh;
}
@ -479,11 +479,10 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
}
/* Get vgroup idx from its name. */
defgrp_index = BKE_object_defgroup_name_index(ob, wmd->defgrp_name);
defgrp_index = BKE_id_defgroup_name_index(&mesh->id, wmd->defgrp_name);
if (defgrp_index == -1) {
return mesh;
}
const bool has_mdef = CustomData_has_layer(&mesh->vdata, CD_MDEFORMVERT);
/* If no vertices were ever added to an object's vgroup, dvert might be NULL. */
/* As this modifier never add vertices to vgroup, just return. */

View File

@ -1573,11 +1573,12 @@ struct WeldVertexCluster {
uint merged_verts;
};
static Mesh *weldModifier_doWeld(WeldModifierData *wmd, const ModifierEvalContext *ctx, Mesh *mesh)
static Mesh *weldModifier_doWeld(WeldModifierData *wmd,
const ModifierEvalContext *UNUSED(ctx),
Mesh *mesh)
{
Mesh *result = mesh;
Object *ob = ctx->object;
BLI_bitmap *v_mask = NULL;
int v_mask_act = 0;
@ -1590,7 +1591,7 @@ static Mesh *weldModifier_doWeld(WeldModifierData *wmd, const ModifierEvalContex
totvert = mesh->totvert;
/* Vertex Group. */
const int defgrp_index = BKE_object_defgroup_name_index(ob, wmd->defgrp_name);
const int defgrp_index = BKE_id_defgroup_name_index(&mesh->id, wmd->defgrp_name);
if (defgrp_index != -1) {
MDeformVert *dvert, *dv;
dvert = CustomData_get_layer(&mesh->vdata, CD_MDEFORMVERT);

View File

@ -76,7 +76,7 @@ static Mesh *WireframeModifier_do(WireframeModifierData *wmd, Object *ob, Mesh *
Mesh *result;
BMesh *bm;
const int defgrp_index = BKE_object_defgroup_name_index(ob, wmd->defgrp_name);
const int defgrp_index = BKE_id_defgroup_name_index(&mesh->id, wmd->defgrp_name);
bm = BKE_mesh_to_bmesh_ex(mesh,
&(struct BMeshCreateParams){0},

View File

@ -627,7 +627,7 @@ static void delete_mesh_selection(MeshComponent &component,
mesh_out = nullptr;
break;
}
component.replace_mesh_but_keep_vertex_group_names(mesh_out);
component.replace(mesh_out);
}
static void geo_node_delete_geometry_exec(GeoNodeExecParams params)

View File

@ -91,7 +91,7 @@ static void geo_node_mesh_subdivide_exec(GeoNodeExecParams params)
BKE_mesh_calc_normals(mesh_out);
MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>();
mesh_component.replace_mesh_but_keep_vertex_group_names(mesh_out);
mesh_component.replace(mesh_out);
BKE_subdiv_free(subdiv);

View File

@ -96,7 +96,7 @@ static void geo_node_subdivision_surface_exec(GeoNodeExecParams params)
BKE_mesh_calc_normals(mesh_out);
MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>();
mesh_component.replace_mesh_but_keep_vertex_group_names(mesh_out);
mesh_component.replace(mesh_out);
// BKE_subdiv_stats_print(&subdiv->stats);
BKE_subdiv_free(subdiv);

View File

@ -347,9 +347,9 @@ static void pointdensity_cache_vertex_weight(PointDensity *pd,
if (!mdef) {
return;
}
mdef_index = BKE_object_defgroup_name_index(ob, pd->vertex_attribute_name);
mdef_index = BKE_id_defgroup_name_index(&mesh->id, pd->vertex_attribute_name);
if (mdef_index < 0) {
mdef_index = ob->actdef - 1;
mdef_index = BKE_object_defgroup_active_index_get(ob) - 1;
}
if (mdef_index < 0) {
return;