Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/object/object_vgroup.c')
-rw-r--r--source/blender/editors/object/object_vgroup.c566
1 files changed, 9 insertions, 557 deletions
diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c
index dea7eb984ad..b31d2b8b076 100644
--- a/source/blender/editors/object/object_vgroup.c
+++ b/source/blender/editors/object/object_vgroup.c
@@ -20,7 +20,7 @@
*
* The Original Code is: all of this file.
*
- * Contributor(s): Ove M Henriksen.
+ * Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -29,6 +29,7 @@
* \ingroup edobj
*/
+
#include <string.h>
#include <stddef.h>
#include <math.h>
@@ -82,19 +83,6 @@ static void vgroup_delete_edit_mode(Object *ob, bDeformGroup *defgroup);
static void vgroup_delete_object_mode(Object *ob, bDeformGroup *dg);
static void vgroup_delete_all(Object *ob);
-static int vertex_group_use_vert_sel(Object *ob)
-{
- if (ob->mode == OB_MODE_EDIT) {
- return TRUE;
- }
- else if (ob->type == OB_MESH && ((Mesh *)ob->data)->editflag & ME_EDIT_VERT_SEL) {
- return TRUE;
- }
- else {
- return FALSE;
- }
-}
-
static Lattice *vgroup_edit_lattice(Object *ob)
{
Lattice *lt = ob->data;
@@ -389,316 +377,6 @@ int ED_vgroup_copy_array(Object *ob, Object *ob_from)
return 1;
}
-/***********************Start weight transfer (WT)*********************************/
-
-typedef enum WT_VertexGroupMode {
- WT_REPLACE_ACTIVE_VERTEX_GROUP = 1,
- WT_REPLACE_ALL_VERTEX_GROUPS = 2
-} WT_VertexGroupMode;
-
-typedef enum WT_Method {
- WT_BY_INDEX = 1,
- WT_BY_NEAREST_VERTEX = 2,
- WT_BY_NEAREST_FACE = 3,
- WT_BY_NEAREST_VERTEX_IN_FACE = 4
-} WT_Method;
-
-typedef enum WT_ReplaceMode {
- WT_REPLACE_ALL_WEIGHTS = 1,
- WT_REPLACE_EMPTY_WEIGHTS = 2,
- WT_REPLACE_SELECTED_WEIGHTS = 3
-} WT_ReplaceMode;
-
-static EnumPropertyItem WT_vertex_group_mode_item[] = {
- {WT_REPLACE_ACTIVE_VERTEX_GROUP, "WT_REPLACE_ACTIVE_VERTEX_GROUP", 1, "Active", "Transfer active vertex group from selected to active mesh."},
- {WT_REPLACE_ALL_VERTEX_GROUPS, "WT_REPLACE_ALL_VERTEX_GROUPS", 1, "All", "Transfer all vertex groups from selected to active mesh."},
- {0, NULL, 0, NULL, NULL}
-};
-
-static EnumPropertyItem WT_method_item[] = {
- {WT_BY_INDEX, "WT_BY_INDEX", 1, "Vertex index", "Copy for identical meshes."},
- {WT_BY_NEAREST_VERTEX, "WT_BY_NEAREST_VERTEX", 1, "Nearest vertex", "Copy weight from closest vertex."},
- {WT_BY_NEAREST_FACE, "WT_BY_NEAREST_FACE", 1, "Nearest face", "Barycentric interpolation from nearest face."},
- {WT_BY_NEAREST_VERTEX_IN_FACE, "WT_BY_NEAREST_VERTEX_IN_FACE", 1, "Nearest vertex in face", "Copy weight from closest vertex in nearest face."},
- {0, NULL, 0, NULL, NULL}
-};
-
-static EnumPropertyItem WT_replace_mode_item[] = {
- {WT_REPLACE_ALL_WEIGHTS, "WT_REPLACE_ALL_WEIGHTS", 1, "All", "Overwrites all weights."},
- {WT_REPLACE_EMPTY_WEIGHTS, "WT_REPLACE_EMPTY_WEIGHTS", 1, "Empty", "Adds weights to vertices with no weight."},
- {WT_REPLACE_SELECTED_WEIGHTS, "WT_REPLACE_SELECTED_WEIGHTS", 1, "Selected", "Replace selected weights."},
- {0, NULL, 0, NULL, NULL}
-};
-
-/*copy weight*/
-static void vgroup_transfer_weight(MVert *mv_dst, float *weight_dst, float weight_src, WT_ReplaceMode replace_mode)
-{
- switch (replace_mode) {
-
- case WT_REPLACE_ALL_WEIGHTS:
- *weight_dst = weight_src;
- break;
-
- case WT_REPLACE_EMPTY_WEIGHTS:
- if (*weight_dst == 0) *weight_dst = weight_src;
- break;
-
- case WT_REPLACE_SELECTED_WEIGHTS:
- if (mv_dst->flag & SELECT) *weight_dst = weight_src;
- break;
-
- default:
- BLI_assert(0);
- break;
- }
-}
-
-/* could be exposed externally */
-static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_src, Scene *scene,
- WT_Method method, WT_ReplaceMode replace_mode, wmOperator *op)
-{
- bDeformGroup *dg_dst;
- Mesh *me_dst, *me_src;
- DerivedMesh *dmesh_src;
- BVHTreeFromMesh tree_mesh_vertices_src, tree_mesh_faces_src = {NULL};
- MDeformVert **dv_array_src, **dv_array_dst, **dv_src, **dv_dst;
- MVert *mv_dst, *mv_src;
- MFace *mface_src, *mf;
- BVHTreeNearest nearest;
- MDeformWeight *dw_dst, *dw_src;
- int dv_tot_src, dv_tot_dst, i, v_index, index_dst, index_src, index_nearest, index_nearest_vertex;
- unsigned int f_index;
- float weight, tmp_weight[4], tmp_co[3], normal[3], tmp_mat[4][4], dist_v1, dist_v2, dist_v3, dist_v4;
-
- /* create new and overwrite vertex group on destination without data */
- if (!defgroup_find_name(ob_dst, dg_src->name) || replace_mode == WT_REPLACE_ALL_WEIGHTS) {
- ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name));
- ED_vgroup_add_name(ob_dst, dg_src->name);
- }
-
- /* get destination deformgroup */
- dg_dst = defgroup_find_name(ob_dst, dg_src->name);
-
- /* get meshes */
- dmesh_src = mesh_get_derived_deform(scene, ob_src, CD_MASK_BAREMESH);
- me_dst = ob_dst->data;
- me_src = ob_src->data;
-
- /* sanity check */
- if (!me_src->dvert) {
- BKE_reportf(op->reports, RPT_ERROR, "Transfer failed. Source mesh does not have any vertex groups");
- return 0;
- }
-
- /* create data in memory when nothing there */
- if (!me_dst->dvert) ED_vgroup_data_create(ob_dst->data);
-
- /* get vertex group arrays */
- ED_vgroup_give_parray(ob_src->data, &dv_array_src, &dv_tot_src, FALSE);
- ED_vgroup_give_parray(ob_dst->data, &dv_array_dst, &dv_tot_dst, FALSE);
-
- /* get indexes of vertex groups */
- index_src = BLI_findindex(&ob_src->defbase, dg_src);
- index_dst = BLI_findindex(&ob_dst->defbase, dg_dst);
-
- /* get vertices */
- mv_dst = me_dst->mvert;
- mv_src = dmesh_src->getVertArray(dmesh_src);
-
- /* prepare transformation matrix */
- invert_m4_m4(ob_src->imat, ob_src->obmat);
- mult_m4_m4m4(tmp_mat, ob_src->imat, ob_dst->obmat);
-
- /* clear weights */
- if (replace_mode == WT_REPLACE_ALL_WEIGHTS) {
- for(i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++) {
- dw_dst = defvert_verify_index(*dv_dst, index_dst);
- if (dw_dst) (*dw_dst).weight = 0;
- }
- }
-
- switch (method) {
-
- case WT_BY_INDEX:
- /* check if indices are matching, delete and return if not */
- if (ob_dst == ob_src || dv_tot_dst == 0 || dv_tot_dst != dv_tot_src ||
- dv_array_src == NULL || dv_array_dst == NULL)
- {
- ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_dst->name));
- if (dv_array_src) MEM_freeN(dv_array_src);
- if (dv_array_dst) MEM_freeN(dv_array_dst);
- dmesh_src->release(dmesh_src);
- BKE_reportf(op->reports, RPT_ERROR, "Transfer failed. Indices are not matching");
- return 0;
- }
-
- /* loop through the vertices*/
- for(i = 0, dv_src = dv_array_src, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, dv_src++, mv_src++) {
-
- /* copy weight */
- dw_src = defvert_find_index(*dv_src, index_src);
- if (dw_src && dw_src->weight) {
- dw_dst = defvert_verify_index(*dv_dst, index_dst);
- vgroup_transfer_weight(mv_dst, &dw_dst->weight, dw_src->weight, replace_mode);
- }
- }
- break;
-
- case WT_BY_NEAREST_VERTEX:
- /* make node tree */
- bvhtree_from_mesh_verts(&tree_mesh_vertices_src, dmesh_src, FLT_EPSILON, 2, 6);
-
- /* loop trough vertices */
- for(i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_dst++){
-
- /* reset nearest */
- nearest.dist = FLT_MAX;
- /* With current binary tree its marginally faster to start searching at the top, as opposed to previous search. */
- nearest.index = -1;
-
- /* transform into target space */
- mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co);
-
- /* node tree accelerated search for closest vetex */
- BLI_bvhtree_find_nearest(tree_mesh_vertices_src.tree, tmp_co,
- &nearest, tree_mesh_vertices_src.nearest_callback, &tree_mesh_vertices_src);
-
- /* copy weight that are not NULL including weight value 0. Existing target weights are overwritten prior to this in relevant cases. */
- dw_src = defvert_find_index(dv_array_src[nearest.index], index_src);
- if (dw_src && dw_src->weight) {
- dw_dst = defvert_verify_index(*dv_dst, index_dst);
- vgroup_transfer_weight(mv_dst, &dw_dst->weight, dw_src->weight, replace_mode);
- }
- }
-
- /* free memory */
- free_bvhtree_from_mesh(&tree_mesh_vertices_src);
- break;
-
- case WT_BY_NEAREST_FACE:
- /* get faces */
- DM_ensure_tessface(dmesh_src);
- mface_src = dmesh_src->getTessFaceArray(dmesh_src);
-
- /* make node tree */
- bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, FLT_EPSILON, 2, 6);
-
- /* loop through the vertices */
- for(i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_dst++) {
-
- /* reset nearest */
- nearest.dist = FLT_MAX;
- /* With current binary tree its marginally faster to start searching at the top, as opposed to previous search. */
- nearest.index = -1;
-
- /* transform into target space */
- mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co);
-
- /* node tree accelerated search for closest face */
- BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co,
- &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src);
- index_nearest = nearest.index;
-
- /* project onto face */
- mf = &mface_src[index_nearest];
- normal_tri_v3(normal, mv_src[mf->v1].co, mv_src[mf->v2].co, mv_src[mf->v3].co);
- project_v3_plane(tmp_co, normal, mv_src[mf->v1].co);
-
- /* interpolate weights over face*/
- f_index = mf->v4 ? 3 : 2;
- if (f_index == 3) {
- interp_weights_face_v3(tmp_weight, mv_src[mf->v1].co, mv_src[mf->v2].co, mv_src[mf->v3].co, mv_src[mf->v4].co, tmp_co);
- }
- else {
- interp_weights_face_v3(tmp_weight, mv_src[mf->v1].co, mv_src[mf->v2].co, mv_src[mf->v3].co, NULL, tmp_co);
- }
-
- /* get weights from face*/
- weight = 0;
- do {
- v_index = (&mf->v1)[f_index];
- weight += tmp_weight[f_index] * defvert_find_weight(dv_array_src[v_index], index_src);
- } while (f_index--);
-
- /* copy weight that are not NULL including weight value 0. Existing target weights are overwritten prior to this in relevant cases. */
- if (weight > 0) {
- dw_dst = defvert_verify_index(*dv_dst, index_dst);
- vgroup_transfer_weight(mv_dst, &dw_dst->weight, weight, replace_mode);
- }
- }
-
- /* free memory */
- free_bvhtree_from_mesh(&tree_mesh_faces_src);
- break;
-
- case WT_BY_NEAREST_VERTEX_IN_FACE:
- /* get faces */
- DM_ensure_tessface(dmesh_src);
- mface_src = dmesh_src->getTessFaceArray(dmesh_src);
-
- /* make node tree */
- bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, FLT_EPSILON, 2, 6);
-
- /* loop through the vertices */
- for(i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_dst++){
-
- /* reset nearest */
- nearest.dist = FLT_MAX;
- /* With current binary tree its marginally faster to start searching at the top, as opposed to previous search. */
- nearest.index = -1;
-
- /* transform into target space */
- mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co);
-
- /* node tree accelerated search for closest face */
- BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co,
- &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src);
- index_nearest = nearest.index;
-
- /* get distances */
- mf = &mface_src[index_nearest];
- dist_v1 = len_squared_v3v3(tmp_co, mv_src[mf->v1].co);
- dist_v2 = len_squared_v3v3(tmp_co, mv_src[mf->v2].co);
- dist_v3 = len_squared_v3v3(tmp_co, mv_src[mf->v3].co);
-
- /* get closest vertex */
- f_index = mf->v4 ? 3 : 2;
- if (dist_v1 < dist_v2 && dist_v1 < dist_v3) index_nearest_vertex = mf->v1;
- else if (dist_v2 < dist_v3) index_nearest_vertex = mf->v2;
- else index_nearest_vertex = mf->v3;
- if (f_index == 3) {
- dist_v4 = len_squared_v3v3(tmp_co, mv_src[mf->v4].co);
- if (dist_v4 < dist_v1 && dist_v4 < dist_v2 && dist_v4 < dist_v3) {
- index_nearest_vertex = mf->v4;
- }
- }
-
- /* copy weight that are not NULL including weight value 0. Existing target weights are overwritten prior to this in relevant cases. */
- dw_src = defvert_find_index(dv_array_src[index_nearest_vertex], index_src);
- if (dw_src && dw_src->weight) {
- dw_dst = defvert_verify_index(*dv_dst, index_dst);
- vgroup_transfer_weight(mv_dst, &dw_dst->weight, dw_src->weight, replace_mode);
- }
- }
-
- /* free memory */
- free_bvhtree_from_mesh(&tree_mesh_faces_src);
- break;
-
- default:
- BLI_assert(0);
- break;
- }
-
- /*free memory*/
- if (dv_array_src) MEM_freeN(dv_array_src);
- if (dv_array_dst) MEM_freeN(dv_array_dst);
- dmesh_src->release(dmesh_src);
-
- return 1;
-}
-
-/***********************End weight transfer (WT)***********************************/
/* for Mesh in Object mode */
/* allows editmode for Lattice */
@@ -1026,7 +704,7 @@ static void vgroup_normalize(Object *ob)
int i, dvert_tot = 0;
const int def_nr = ob->actdef - 1;
- const int use_vert_sel = vertex_group_use_vert_sel(ob);
+ const int use_vert_sel = (ob->type == OB_MESH && ((Mesh *)ob->data)->editflag & ME_EDIT_VERT_SEL) != 0;
if (!BLI_findlink(&ob->defbase, def_nr)) {
return;
@@ -1431,7 +1109,7 @@ static void vgroup_levels(Object *ob, float offset, float gain)
int i, dvert_tot = 0;
const int def_nr = ob->actdef - 1;
- const int use_vert_sel = vertex_group_use_vert_sel(ob);
+ const int use_vert_sel = (ob->type == OB_MESH && ((Mesh *)ob->data)->editflag & ME_EDIT_VERT_SEL) != 0;
if (!BLI_findlink(&ob->defbase, def_nr)) {
return;
@@ -1465,7 +1143,7 @@ static void vgroup_normalize_all(Object *ob, int lock_active)
int i, dvert_tot = 0;
const int def_nr = ob->actdef - 1;
- const int use_vert_sel = vertex_group_use_vert_sel(ob);
+ const int use_vert_sel = (ob->type == OB_MESH && ((Mesh *)ob->data)->editflag & ME_EDIT_VERT_SEL) != 0;
if (lock_active && !BLI_findlink(&ob->defbase, def_nr)) {
return;
@@ -1543,7 +1221,7 @@ static void vgroup_invert(Object *ob, const short auto_assign, const short auto_
MDeformVert *dv, **dvert_array = NULL;
int i, dvert_tot = 0;
const int def_nr = ob->actdef - 1;
- const int use_vert_sel = vertex_group_use_vert_sel(ob);
+ const int use_vert_sel = (ob->type == OB_MESH && ((Mesh *)ob->data)->editflag & ME_EDIT_VERT_SEL) != 0;
if (!BLI_findlink(&ob->defbase, def_nr)) {
return;
@@ -1711,119 +1389,13 @@ static void vgroup_blend(Object *ob, const float fac)
}
}
-static int inv_cmp_mdef_vert_weights(const void *a1, const void *a2)
-{
- /* qsort sorts in ascending order. We want descending order to save a memcopy
- * so this compare function is inverted from the standard greater than comparison qsort needs.
- * A normal compare function is called with two pointer arguments and should return an integer less than, equal to,
- * or greater than zero corresponding to whether its first argument is considered less than, equal to,
- * or greater than its second argument. This does the opposite. */
- const struct MDeformWeight *dw1 = a1, *dw2 = a2;
-
- if (dw1->weight < dw2->weight) return 1;
- else if (dw1->weight > dw2->weight) return -1;
- else if (&dw1 < &dw2) return 1; /* compare addresses so we have a stable sort algorithm */
- else return -1;
-}
-
-/* Used for limiting the number of influencing bones per vertex when exporting
- * skinned meshes. if all_deform_weights is True, limit all deform modifiers
- * to max_weights regardless of type, otherwise, only limit the number of influencing bones per vertex*/
-static int vertex_group_limit_total(Object *ob,
- const int max_weights,
- const int all_deform_weights)
-{
- MDeformVert *dv, **dvert_array = NULL;
- int i, dvert_tot = 0;
- const int use_vert_sel = vertex_group_use_vert_sel(ob);
- int is_change = FALSE;
-
- ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot, use_vert_sel);
-
- if (dvert_array) {
- int defbase_tot = BLI_countlist(&ob->defbase);
- const char *vgroup_validmap = (all_deform_weights == FALSE) ?
- BKE_objdef_validmap_get(ob, defbase_tot) :
- NULL;
- int num_to_drop = 0;
-
- /* only the active group */
- for (i = 0; i < dvert_tot; i++) {
-
- /* in case its not selected */
- if (!(dv = dvert_array[i])) {
- continue;
- }
-
- if (all_deform_weights) {
- /* keep only the largest weights, discarding the rest
- * qsort will put array in descending order because of invCompare function */
- num_to_drop = dv->totweight - max_weights;
- if (num_to_drop > 0) {
- qsort(dv->dw, dv->totweight, sizeof(MDeformWeight), inv_cmp_mdef_vert_weights);
- dv->dw = MEM_reallocN(dv->dw, sizeof(MDeformWeight) * max_weights);
- dv->totweight = max_weights;
- is_change = TRUE;
- }
- }
- else {
- MDeformWeight *dw_temp;
- int bone_count = 0, non_bone_count = 0;
- int j;
- /* only consider vgroups with bone modifiers attached (in vgroup_validmap) */
-
- num_to_drop = dv->totweight - max_weights;
-
- /* first check if we even need to test further */
- if (num_to_drop > 0) {
- /* re-pack dw array so that non-bone weights are first, bone-weighted verts at end
- * sort the tail, then copy only the truncated array back to dv->dw */
- dw_temp = MEM_mallocN(sizeof(MDeformWeight) * (dv->totweight), __func__);
- bone_count = 0; non_bone_count = 0;
- for (j = 0; j < dv->totweight; j++) {
- BLI_assert(dv->dw[j].def_nr < defbase_tot);
- if (!vgroup_validmap[(dv->dw[j]).def_nr]) {
- dw_temp[non_bone_count] = dv->dw[j];
- non_bone_count += 1;
- }
- else {
- dw_temp[dv->totweight - 1 - bone_count] = dv->dw[j];
- bone_count += 1;
- }
- }
- BLI_assert(bone_count + non_bone_count == dv->totweight);
- num_to_drop = bone_count - max_weights;
- if (num_to_drop > 0) {
- qsort(&dw_temp[non_bone_count], bone_count, sizeof(MDeformWeight), inv_cmp_mdef_vert_weights);
- dv->totweight -= num_to_drop;
- /* Do we want to clean/normalize here? */
- MEM_freeN(dv->dw);
- dv->dw = MEM_reallocN(dw_temp, sizeof(MDeformWeight) * dv->totweight);
- is_change = TRUE;
- }
- else {
- MEM_freeN(dw_temp);
- }
- }
- }
- }
- MEM_freeN(dvert_array);
-
- if (vgroup_validmap) {
- MEM_freeN((void *)vgroup_validmap);
- }
- }
-
- return is_change;
-}
-
static void vgroup_clean(Object *ob, const float epsilon, int keep_single)
{
MDeformWeight *dw;
MDeformVert *dv, **dvert_array = NULL;
int i, dvert_tot = 0;
const int def_nr = ob->actdef - 1;
- const int use_vert_sel = vertex_group_use_vert_sel(ob);
+ const int use_vert_sel = (ob->type == OB_MESH && ((Mesh *)ob->data)->editflag & ME_EDIT_VERT_SEL) != 0;
if (!BLI_findlink(&ob->defbase, def_nr)) {
return;
@@ -1859,7 +1431,7 @@ static void vgroup_clean_all(Object *ob, const float epsilon, const int keep_sin
{
MDeformVert **dvert_array = NULL;
int i, dvert_tot = 0;
- const int use_vert_sel = vertex_group_use_vert_sel(ob);
+ const int use_vert_sel = (ob->type == OB_MESH && ((Mesh *)ob->data)->editflag & ME_EDIT_VERT_SEL) != 0;
ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot, use_vert_sel);
@@ -3093,47 +2665,6 @@ void OBJECT_OT_vertex_group_clean(wmOperatorType *ot)
"Keep verts assigned to at least one group when cleaning");
}
-static int vertex_group_limit_total_exec(bContext *C, wmOperator *op)
-{
- Object *ob = ED_object_context(C);
-
- const int limit = RNA_int_get(op->ptr, "limit");
- const int all_deform_weights = RNA_boolean_get(op->ptr, "all_deform_weights");
-
- if (vertex_group_limit_total(ob, limit, all_deform_weights)) {
-
- DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
- WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
-
- return OPERATOR_FINISHED;
- }
- else {
- BKE_reportf(op->reports, RPT_WARNING, "No vertex groups limited");
-
- /* note, would normally return cancelled, except we want the redo
- * UI to show up for users to change */
- return OPERATOR_FINISHED;
- }
-}
-
-void OBJECT_OT_vertex_group_limit_total(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name = "Limit Number of Weights per Vertex";
- ot->idname = "OBJECT_OT_vertex_group_limit_total";
- ot->description = "Limits deform weights associated with a vertex to a specified number by removing lowest weights";
-
- /* api callbacks */
- ot->poll = vertex_group_poll;
- ot->exec = vertex_group_limit_total_exec;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- RNA_def_int(ot->srna, "limit", 4, 1, 32, "Limit", "Maximum number of deform weights", 1, 32);
- RNA_def_boolean(ot->srna, "all_deform_weights", FALSE, "All Deform Weights", "Cull all deform weights, not just bones");
-}
static int vertex_group_mirror_exec(bContext *C, wmOperator *op)
{
@@ -3238,6 +2769,7 @@ static int vertex_group_copy_to_selected_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
+
void OBJECT_OT_vertex_group_copy_to_selected(wmOperatorType *ot)
{
/* identifiers */
@@ -3253,86 +2785,6 @@ void OBJECT_OT_vertex_group_copy_to_selected(wmOperatorType *ot)
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op)
-{
- Scene *scene = CTX_data_scene(C);
- Object *ob_act = CTX_data_active_object(C);
- bDeformGroup *dg_src;
- int fail = 0;
-
- WT_VertexGroupMode vertex_group_mode = RNA_enum_get(op->ptr, "WT_vertex_group_mode");
- WT_Method method = RNA_enum_get(op->ptr, "WT_method");
- WT_ReplaceMode replace_mode = RNA_enum_get(op->ptr, "WT_replace_mode");
-
- /* Macro to loop through selected objects and perform operation depending on function, option and method */
- CTX_DATA_BEGIN (C, Object *, ob_slc, selected_editable_objects)
- {
-
- if (ob_act != ob_slc && ob_slc->defbase.first) {
- switch (vertex_group_mode) {
-
- case WT_REPLACE_ACTIVE_VERTEX_GROUP:
- if (!ed_vgroup_transfer_weight(ob_act, ob_slc,
- BLI_findlink(&ob_slc->defbase, ob_slc->actdef - 1),
- scene, method, replace_mode, op))
- {
- fail++;
- }
- break;
-
- case WT_REPLACE_ALL_VERTEX_GROUPS:
- for (dg_src = ob_slc->defbase.first; dg_src; dg_src = dg_src->next) {
- if (!ed_vgroup_transfer_weight(ob_act, ob_slc,
- dg_src, scene, method, replace_mode, op))
- {
- fail++;
- }
- }
- break;
-
- default:
- BLI_assert(0);
- break;
- }
- }
- }
-
- /* Event notifiers for correct display of data */
- DAG_id_tag_update(&ob_slc->id, OB_RECALC_DATA);
- WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob_slc);
- WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob_slc->data);
-
- CTX_DATA_END;
-
- if (fail != 0) {
- return OPERATOR_CANCELLED;
- }
- else {
- return OPERATOR_FINISHED;
- }
-}
-
-/* transfers weight from active to selected */
-void OBJECT_OT_vertex_group_transfer_weight(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name = "Transfer weight";
- ot->idname = "OBJECT_OT_vertex_group_transfer_weight";
- ot->description = "Transfer weight paint to active from selected mesh";
-
- /* api callbacks */
- ot->poll = vertex_group_poll;
- ot->exec = vertex_group_transfer_weight_exec;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* properties */
- ot->prop = RNA_def_enum(ot->srna, "WT_vertex_group_mode", WT_vertex_group_mode_item, 1, "Group", "");
- ot->prop = RNA_def_enum(ot->srna, "WT_method", WT_method_item, 3, "Method", "");
- ot->prop = RNA_def_enum(ot->srna, "WT_replace_mode", WT_replace_mode_item, 1, "Replace", "");
-}
-
static EnumPropertyItem vgroup_items[] = {
{0, NULL, 0, NULL, NULL}
};