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')
-rw-r--r--source/blender/editors/object/object_intern.h6
-rw-r--r--source/blender/editors/object/object_ops.c6
-rw-r--r--source/blender/editors/object/object_vgroup.c620
3 files changed, 630 insertions, 2 deletions
diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h
index 3da0723ec18..fb119b1d264 100644
--- a/source/blender/editors/object/object_intern.h
+++ b/source/blender/editors/object/object_intern.h
@@ -200,6 +200,12 @@ void OBJECT_OT_vertex_group_copy(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_normalize(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_normalize_all(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_levels(struct wmOperatorType *ot);
+/* Jason was here */
+void OBJECT_OT_vertex_group_lock_all(struct wmOperatorType *ot);
+void OBJECT_OT_vertex_group_invert_locks(struct wmOperatorType *ot);
+void OBJECT_OT_vertex_group_unlock_all(struct wmOperatorType *ot);
+void OBJECT_OT_vertex_group_fix(struct wmOperatorType *ot);
+
void OBJECT_OT_vertex_group_invert(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_blend(struct wmOperatorType *ot);
void OBJECT_OT_vertex_group_clean(struct wmOperatorType *ot);
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index 5eb17268d19..b36357facb1 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -174,6 +174,12 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_vertex_group_copy);
WM_operatortype_append(OBJECT_OT_vertex_group_normalize);
WM_operatortype_append(OBJECT_OT_vertex_group_normalize_all);
+ /* Jason was here */
+ WM_operatortype_append(OBJECT_OT_vertex_group_invert_locks);
+ WM_operatortype_append(OBJECT_OT_vertex_group_lock_all);
+ WM_operatortype_append(OBJECT_OT_vertex_group_unlock_all);
+ WM_operatortype_append(OBJECT_OT_vertex_group_fix);
+
WM_operatortype_append(OBJECT_OT_vertex_group_invert);
WM_operatortype_append(OBJECT_OT_vertex_group_levels);
WM_operatortype_append(OBJECT_OT_vertex_group_blend);
diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c
index 52ba9460818..8d2a584646a 100644
--- a/source/blender/editors/object/object_vgroup.c
+++ b/source/blender/editors/object/object_vgroup.c
@@ -60,6 +60,7 @@
#include "BKE_global.h"
#include "BKE_mesh.h"
#include "BKE_report.h"
+#include "BKE_DerivedMesh.h"//Jason
#include "RNA_access.h"
#include "RNA_define.h"
@@ -701,6 +702,10 @@ static void vgroup_normalize(Object *ob)
MDeformWeight *dw;
MDeformVert *dvert, **dvert_array=NULL;
int i, def_nr, dvert_tot=0;
+ // Jason
+ Mesh *me = ob->data;
+ MVert *mv = me->mvert;
+ int selectedVerts = me->editflag & ME_EDIT_VERT_SEL;
ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot);
@@ -712,6 +717,11 @@ static void vgroup_normalize(Object *ob)
def_nr= ob->actdef-1;
for(i = 0; i < dvert_tot; i++) {
+ // Jason
+ if(selectedVerts && !((mv+i)->flag & SELECT)) {
+ continue;
+ }
+
dvert = dvert_array[i];
dw = defvert_find_index(dvert, def_nr);
if(dw) {
@@ -721,6 +731,11 @@ static void vgroup_normalize(Object *ob)
if(weight_max > 0.0f) {
for(i = 0; i < dvert_tot; i++) {
+ // Jason
+ if(selectedVerts && !((mv+i)->flag & SELECT)) {
+ continue;
+ }
+
dvert = dvert_array[i];
dw = defvert_find_index(dvert, def_nr);
if(dw) {
@@ -735,6 +750,418 @@ static void vgroup_normalize(Object *ob)
if (dvert_array) MEM_freeN(dvert_array);
}
+// Jason
+/* This adds the indices of vertices to a list if they are not already present
+It returns the number that it added (0-2)
+It relies on verts having -1 for unassigned indices
+*/
+static int tryToAddVerts(int *verts, int length, int a, int b) {
+ char containsA = FALSE;
+ char containsB = FALSE;
+ int added = 0;
+ int i;
+ for(i = 0; i < length && (!containsA || !containsB); i++) {
+ if(verts[i] == a) {
+ containsA = TRUE;
+ } else if(verts[i] == b) {
+ containsB = TRUE;
+ } else if(verts[i] == -1) {
+ if(!containsA) {
+ verts[i] = a;
+ containsA = TRUE;
+ added++;
+ } else if(!containsB){
+ verts[i] = b;
+ containsB = TRUE;
+ added++;
+ }
+ }
+ }
+ return added;
+}
+//Jason
+/* This finds all of the vertices connected to vert by an edge
+and returns an array of indices of size count
+
+count is an int passed by reference so it can be assigned the value of the length here.
+*/
+static int* getSurroundingVerts(Mesh *me, int vert, int *count) {
+ int length = 0;
+ int *tverts;
+ int *verts = NULL;
+ MFace *mf = me->mface;
+ int totface = me->totface;
+ int found = 0;
+ int i;
+ for(i = 0; i < totface; i++, mf++) {
+ if(vert == mf->v1 || vert == mf->v2 || vert == mf->v3 || (mf->v4 &&vert == mf->v4)) {
+ length+=2;
+ }
+ }
+ if(!length) {
+ return 0;
+ }
+ tverts = MEM_mallocN(sizeof(int)*length, "tempSurroundingVerts");
+ mf = me->mface;
+ for(i = 0; i < length; i++) {
+ tverts[i] = -1;
+ }
+ for(i = 0; i < totface; i++, mf++) {
+ int a=-1, b=-1;
+ if(mf->v1 == vert) {
+ a = mf->v2;
+ if(mf->v4) {
+ b = mf->v4;
+ } else {
+ b = mf->v3;
+ }
+ } else if(mf->v2 == vert) {
+ a = mf->v1;
+ b = mf->v3;
+ } else if(mf->v3 == vert) {
+ a = mf->v2;
+ if(mf->v4) {
+ b = mf->v4;
+ } else {
+ b = mf->v1;
+ }
+ } else if (mf->v4 && mf->v4 == vert){
+ a = mf->v1;
+ b = mf->v3;
+ } else {
+ continue;
+ }
+ found += tryToAddVerts(tverts, length, a, b);
+ }
+ if(found) {
+ verts = MEM_mallocN(sizeof(int)* found, "surroundingVerts");
+ for(i = 0; i < found; i++) {
+ verts[i] = tverts[i];
+ }
+ *count = found;
+ }
+ MEM_freeN(tverts);
+ return verts;
+}
+/* Jason */
+/* get a single point in space by averaging a point cloud (vectors of size 3)
+coord is the place the average is stored, points is the point cloud, count is the number of points in the cloud
+*/
+static void getSingleCoordinate(MVert **points, int count, float *coord) {
+ int i, k;
+ for(k = 0; k < 3; k++) {
+ coord[k] = 0;
+ }
+ for(i = 0; i < count; i++) {
+ for(k = 0; k < 3; k++) {
+ coord[k] += points[i]->co[k];
+ }
+ }
+ for(k = 0; k < 3; k++) {
+ coord[k] /= count;
+ }
+}
+/* Jason */
+/* find the closest point on a plane to another point and store it in dst */
+/* coord is a point on the plane */
+/* point is the point that you want the nearest of */
+/* norm is the plane's normal, and d is the last number in the plane equation 0 = ax + by + cz + d */
+static void getNearestPointOnPlane(float *norm, float d, float *coord, float *point, float *dst) {
+ float *temp = MEM_callocN(sizeof(float)*3, "temp");
+ int i;
+ float dotprod = 0;
+ for(i = 0; i < 3; i++) {
+ temp[i] = point[i]-coord[i];
+ }
+ for(i = 0; i < 3; i++) {
+ dotprod += temp[i]*norm[i];
+ }
+ MEM_freeN(temp);
+ for(i = 0; i < 3; i++) {
+ dst[i] = point[i] - dotprod*norm[i];
+ }
+}
+/* Jason */
+/* distance of two vectors a and b of size length */
+static float distance(float* a, float *b, int length) {
+ int i;
+ float sum = 0;
+ for(i = 0; i < length; i++) {
+ sum += (b[i]-a[i])*(b[i]-a[i]);
+ }
+ return sqrt(sum);
+}
+/* Jason */
+/* given a plane and a start and end position,
+compute the amount of vertical distance relative to the plane and store it in dists,
+then get the horizontal and vertical change and store them in changes
+*/
+static void getVerticalAndHorizontalChange(float *norm, float d, float *coord, float *start, float distToStart, float *end, float **changes, float *dists, int index) {
+ // A=Q-((Q-P).N)N
+ // D = (a*x0 + b*y0 +c*z0 +d)
+ float *projA, *projB;
+ projA = MEM_callocN(sizeof(float)*3, "projectedA");
+ projB = MEM_callocN(sizeof(float)*3, "projectedB");
+ getNearestPointOnPlane(norm, d, coord, start, projA);
+ getNearestPointOnPlane(norm, d, coord, end, projB);
+ // (vertical and horizontal refer to the plane's y and xz respectively)
+ // vertical distance
+ dists[index] = norm[0]*end[0] + norm[1]*end[1] + norm[2]*end[2] + d;
+ // vertical change
+ changes[index][0] = dists[index] - distToStart;
+ //printf("vc %f %f\n", distance(end, projB, 3)-distance(start, projA, 3), changes[index][0]);
+ // horizontal change
+ changes[index][1] = distance(projA, projB, 3);
+
+ MEM_freeN(projA);
+ MEM_freeN(projB);
+}
+// Jason
+// I need the derived mesh to be forgotten so the positions are recalculated with weight changes (see dm_deform_recalc)
+static int dm_deform_clear(DerivedMesh *dm, Object *ob) {
+ dm->needsFree = 1;
+ dm->release(dm);
+ ob->derivedDeform=NULL;
+ // dm = NULL;
+ return NULL;
+}
+// Jason
+// recalculate the deformation
+static DerivedMesh* dm_deform_recalc(Scene *scene, Object *ob) {
+ return mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH);
+}
+// Jason
+/* by changing nonzero weights, try to move a vertex in me->mverts with index 'index' to distToBe distance away from the provided plane
+strength can change distToBe so that it moves towards distToBe by that percentage
+cp changes how much the weights are adjusted to check the distance
+
+index is the index of the vertex being moved
+norm and d are the plane's properties for the equation: ax + by + cz + d = 0
+coord is a point on the plane
+*/
+static void moveCloserToDistanceFromPlane(Scene *scene, Object *ob, Mesh *me, int index, float *norm, float *coord, float d, float distToBe, float strength, float cp) {
+ DerivedMesh *dm;
+ MDeformWeight *dw;
+ MVert m;
+ MDeformVert *dvert = me->dvert+index;
+ int totweight = dvert->totweight;
+ float oldw = 0;
+ float *oldPos = MEM_callocN(sizeof(float)*3, "oldPosition");
+ float vc, hc, dist;
+ int i, k;
+ float **changes = MEM_mallocN(sizeof(float *)*totweight, "vertHorzChange");
+ float *dists = MEM_mallocN(sizeof(float)*totweight, "distance");
+ int *upDown = MEM_callocN(sizeof(int)*totweight, "upDownTracker");// track if up or down moved it closer for each bone
+ int *dwIndices = MEM_callocN(sizeof(int)*totweight, "dwIndexTracker");
+ float distToStart;
+ int bestIndex = 0;
+ char wasChange;
+ char wasUp;
+ int lastIndex = -1;
+ float originalDistToBe = distToBe;
+ for(i = 0; i < totweight; i++) {
+ changes[i] = MEM_callocN(sizeof(float)*2, "vertHorzChange_"+i);
+ }
+ do {
+ wasChange = FALSE;
+ dm = dm_deform_recalc(scene, ob);
+ dm->getVert(dm, index, &m);
+ oldPos[0] = m.co[0];
+ oldPos[1] = m.co[1];
+ oldPos[2] = m.co[2];
+ distToStart = norm[0]*oldPos[0] + norm[1]*oldPos[1] + norm[2]*oldPos[2] + d;
+
+ if(distToBe == originalDistToBe) {
+ distToBe += distToStart - distToStart*strength;
+ }
+ for(i = 0; i < totweight; i++) {
+ dwIndices[i] = i;
+ dw = (dvert->dw+i);
+ vc = hc = 0;
+ if(!dw->weight) {
+ changes[i][0] = 0;
+ changes[i][1] = 0;
+ dists[i] = distToStart;
+ continue;
+ }
+ for(k = 0; k < 2; k++) {
+ if(dm) {
+ dm = dm_deform_clear(dm, ob);
+ }
+ oldw = dw->weight;
+ if(k) {
+ dw->weight *= 1+cp;
+ } else {
+ dw->weight /= 1+cp;
+ }
+ if(dw->weight == oldw) {
+ changes[i][0] = 0;
+ changes[i][1] = 0;
+ dists[i] = distToStart;
+ break;
+ }
+ if(dw->weight > 1) {
+ dw->weight = 1;
+ }
+ dm = dm_deform_recalc(scene, ob);
+ dm->getVert(dm, index, &m);
+ getVerticalAndHorizontalChange(norm, d, coord, oldPos, distToStart, m.co, changes, dists, i);
+ dw->weight = oldw;
+ if(!k) {
+ vc = changes[i][0];
+ hc = changes[i][1];
+ dist = dists[i];
+ } else {
+ if(fabs(dist - distToBe) < fabs(dists[i] - distToBe)) {
+ upDown[i] = 0;
+ changes[i][0] = vc;
+ changes[i][1] = hc;
+ dists[i] = dist;
+ } else {
+ upDown[i] = 1;
+ }
+ if(fabs(dists[i] - distToBe) > fabs(distToStart - distToBe)) {
+ changes[i][0] = 0;
+ changes[i][1] = 0;
+ dists[i] = distToStart;
+ }
+ }
+ }
+ }
+ // sort the changes by the vertical change
+ for(k = 0; k < totweight; k++) {
+ float tf;
+ int ti;
+ bestIndex = k;
+ for(i = k+1; i < totweight; i++) {
+ dist = dists[i];
+
+ if(fabs(dist) > fabs(dists[i])) {
+ bestIndex = i;
+ }
+ }
+ // switch with k
+ if(bestIndex != k) {
+ ti = upDown[k];
+ upDown[k] = upDown[bestIndex];
+ upDown[bestIndex] = ti;
+
+ ti = dwIndices[k];
+ dwIndices[k] = dwIndices[bestIndex];
+ dwIndices[bestIndex] = ti;
+
+ tf = changes[k][0];
+ changes[k][0] = changes[bestIndex][0];
+ changes[bestIndex][0] = tf;
+
+ tf = changes[k][1];
+ changes[k][1] = changes[bestIndex][1];
+ changes[bestIndex][1] = tf;
+
+ tf = dists[k];
+ dists[k] = dists[bestIndex];
+ dists[bestIndex] = tf;
+ }
+ }
+ bestIndex = -1;
+ // find the best change with an acceptable horizontal change
+ for(i = 0; i < totweight; i++) {
+ if(fabs(changes[i][0]) > fabs(changes[i][1]*2.0f)) {
+ bestIndex = i;
+ break;
+ }
+ }
+ if(bestIndex != -1) {
+ wasChange = TRUE;
+ // it is a good place to stop if it tries to move the opposite direction
+ // (relative to the plane) of last time
+ if(lastIndex != -1) {
+ if(wasUp != upDown[bestIndex]) {
+ wasChange = FALSE;
+ }
+ }
+ lastIndex = bestIndex;
+ wasUp = upDown[bestIndex];
+ dw = (dvert->dw+dwIndices[bestIndex]);
+ oldw = dw->weight;
+ if(upDown[bestIndex]) {
+ dw->weight *= 1+cp;
+ } else {
+ dw->weight /= 1+cp;
+ }
+ if(dw->weight > 1) {
+ dw->weight = 1;
+ }
+ if(oldw == dw->weight) {
+ wasChange = FALSE;
+ }
+ if(dm) {
+ dm = dm_deform_clear(dm, ob);
+ }
+ }
+ }while(wasChange && (distToStart-distToBe)/fabs(distToStart-distToBe) == (dists[bestIndex]-distToBe)/fabs(dists[bestIndex]-distToBe));
+ MEM_freeN(upDown);
+ for(i = 0; i < totweight; i++) {
+ MEM_freeN(changes[i]);
+ }
+ MEM_freeN(changes);
+ MEM_freeN(dists);
+ MEM_freeN(dwIndices);
+ MEM_freeN(oldPos);
+}
+// Jason
+/* this is used to try to smooth a surface by only adjusting the nonzero weights of a vertex
+but it could be used to raise or lower an existing 'bump.' */
+static void vgroup_fix(Scene *scene, Object *ob, float distToBe, float strength, float cp)
+{
+ int i;
+
+ Mesh *me = ob->data;
+ MVert *mv = me->mvert;
+ int selectedVerts = me->editflag & ME_EDIT_VERT_SEL;
+ int *verts = NULL;
+ for(i = 0; i < me->totvert && mv; i++, mv++) {
+ // Jason
+ if(selectedVerts && (mv->flag & SELECT)) {
+
+ int count=0;
+ if((verts = getSurroundingVerts(me, i, &count))) {
+ MVert m;
+ MVert **p = MEM_callocN(sizeof(MVert*)*(count), "deformedPoints");
+ int k;
+
+ DerivedMesh *dm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH);
+ for(k = 0; k < count; k++) {
+ dm->getVert(dm, verts[k], &m);
+ p[k] = &m;
+ }
+
+ if(count >= 3) {
+ float d, dist, mag;
+ float *coord = MEM_callocN(sizeof(float)*3, "deformedCoord");
+ float *norm = MEM_callocN(sizeof(float)*3, "planeNorm");
+ getSingleCoordinate(p, count, coord);
+ dm->getVert(dm, i, &m);
+ norm[0] = m.co[0]-coord[0];
+ norm[1] = m.co[1]-coord[1];
+ norm[2] = m.co[2]-coord[2];
+ mag = sqrt(norm[0]*norm[0] + norm[1]*norm[1] + norm[2]*norm[2]);
+ for(k = 0; k < 3; k++) {
+ norm[k]/=mag;
+ }
+ d = -norm[0]*coord[0] -norm[1]*coord[1] -norm[2]*coord[2];
+ dist = (norm[0]*m.co[0] + norm[1]*m.co[1] + norm[2]*m.co[2] + d);
+ moveCloserToDistanceFromPlane(scene, ob, me, i, norm, coord, d, distToBe, strength, cp);
+ MEM_freeN(coord);
+ MEM_freeN(norm);
+ }
+
+ MEM_freeN(verts);
+ MEM_freeN(p);
+ }
+ }
+ }
+}
static void vgroup_levels(Object *ob, float offset, float gain)
{
@@ -742,7 +1169,11 @@ static void vgroup_levels(Object *ob, float offset, float gain)
MDeformWeight *dw;
MDeformVert *dvert, **dvert_array=NULL;
int i, def_nr, dvert_tot=0;
-
+ // Jason
+ Mesh *me = ob->data;
+ MVert *mv = me->mvert;
+ int selectedVerts = me->editflag & ME_EDIT_VERT_SEL;
+
ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot);
dg = BLI_findlink(&ob->defbase, (ob->actdef-1));
@@ -751,6 +1182,11 @@ static void vgroup_levels(Object *ob, float offset, float gain)
def_nr= ob->actdef-1;
for(i = 0; i < dvert_tot; i++) {
+ // Jason
+ if(selectedVerts && !((mv+i)->flag & SELECT)) {
+ continue;
+ }
+
dvert = dvert_array[i];
dw = defvert_find_index(dvert, def_nr);
if(dw) {
@@ -772,6 +1208,11 @@ static void vgroup_normalize_all(Object *ob, int lock_active)
int i, dvert_tot=0;
float tot_weight;
+ // Jason
+ Mesh *me = ob->data;
+ MVert *mv = me->mvert;
+ int selectedVerts = me->editflag & ME_EDIT_VERT_SEL;
+
ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot);
if(dvert_array) {
@@ -781,6 +1222,10 @@ static void vgroup_normalize_all(Object *ob, int lock_active)
for(i = 0; i < dvert_tot; i++) {
float lock_iweight= 1.0f;
int j;
+ // Jason
+ if(selectedVerts && !((mv+i)->flag & SELECT)) {
+ continue;
+ }
tot_weight= 0.0f;
dw_act= NULL;
@@ -821,6 +1266,11 @@ static void vgroup_normalize_all(Object *ob, int lock_active)
else {
for(i = 0; i < dvert_tot; i++) {
int j;
+ // Jason
+ if(selectedVerts && !((mv+i)->flag & SELECT)) {
+ continue;
+ }
+
tot_weight= 0.0f;
dvert = dvert_array[i];
@@ -846,7 +1296,33 @@ static void vgroup_normalize_all(Object *ob, int lock_active)
if (dvert_array) MEM_freeN(dvert_array);
}
-
+/* Jason was here */
+static void vgroup_invert_locks(Object *ob)
+{
+ bDeformGroup *dg = ob->defbase.first;
+ while(dg) {
+ dg->flag = !dg->flag;
+ dg = dg->next;
+ }
+}
+/* Jason was here */
+static void vgroup_lock_all(Object *ob)
+{
+ bDeformGroup *dg = ob->defbase.first;
+ while(dg) {
+ dg->flag = TRUE;
+ dg = dg->next;
+ }
+}
+/* Jason was here */
+static void vgroup_unlock_all(Object *ob)
+{
+ bDeformGroup *dg = ob->defbase.first;
+ while(dg) {
+ dg->flag = FALSE;
+ dg = dg->next;
+ }
+}
static void vgroup_invert(Object *ob, int auto_assign, int auto_remove)
{
@@ -854,6 +1330,10 @@ static void vgroup_invert(Object *ob, int auto_assign, int auto_remove)
MDeformWeight *dw;
MDeformVert *dvert, **dvert_array=NULL;
int i, def_nr, dvert_tot=0;
+ // Jason
+ Mesh *me = ob->data;
+ MVert *mv = me->mvert;
+ int selectedVerts = me->editflag & ME_EDIT_VERT_SEL;
ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot);
@@ -864,6 +1344,10 @@ static void vgroup_invert(Object *ob, int auto_assign, int auto_remove)
for(i = 0; i < dvert_tot; i++) {
+ // Jason
+ if(selectedVerts && !((mv+i)->flag & SELECT)) {
+ continue;
+ }
dvert = dvert_array[i];
if(auto_assign) {
@@ -976,6 +1460,10 @@ static void vgroup_clean(Object *ob, float eul, int keep_single)
MDeformWeight *dw;
MDeformVert *dvert, **dvert_array=NULL;
int i, def_nr, dvert_tot=0;
+ // Jason
+ Mesh *me = ob->data;
+ MVert *mv = me->mvert;
+ int selectedVerts = me->editflag & ME_EDIT_VERT_SEL;
ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot);
@@ -985,6 +1473,10 @@ static void vgroup_clean(Object *ob, float eul, int keep_single)
def_nr= ob->actdef-1;
for(i = 0; i < dvert_tot; i++) {
+ // Jason
+ if(selectedVerts && !((mv+i)->flag & SELECT)) {
+ continue;
+ }
dvert = dvert_array[i];
dw= defvert_find_index(dvert, def_nr);
@@ -1006,12 +1498,21 @@ static void vgroup_clean_all(Object *ob, float eul, int keep_single)
MDeformWeight *dw;
MDeformVert *dvert, **dvert_array=NULL;
int i, dvert_tot=0;
+ // Jason
+ Mesh *me = ob->data;
+ MVert *mv = me->mvert;
+ int selectedVerts = me->editflag & ME_EDIT_VERT_SEL;
ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot);
if(dvert_array) {
for(i = 0; i < dvert_tot; i++) {
int j;
+ // Jason
+ if(selectedVerts && !((mv+i)->flag & SELECT)) {
+ continue;
+ }
+
dvert = dvert_array[i];
j= dvert->totweight;
@@ -1831,7 +2332,122 @@ void OBJECT_OT_vertex_group_normalize_all(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "lock_active", TRUE, "Lock Active", "Keep the values of the active group while normalizing others.");
}
+/* Jason */
+static int vertex_group_fix_exec(bContext *C, wmOperator *op)
+{
+ Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Scene *scene= CTX_data_scene(C);
+
+ float distToBe= RNA_float_get(op->ptr,"dist");
+ float strength= RNA_float_get(op->ptr,"strength");
+ float cp= RNA_float_get(op->ptr,"cp");
+ ModifierData *md = ob->modifiers.first;
+
+ while(md) {
+ if(md->type == eModifierType_Mirror && (md->mode&eModifierMode_Realtime)) {
+ break;
+ }
+ md = md->next;
+ }
+
+ if(md && md->type == eModifierType_Mirror) {
+ BKE_report(op->reports, RPT_ERROR_INVALID_CONTEXT, "This operator does not support an active mirror modifier");
+ return OPERATOR_CANCELLED;
+ }
+ vgroup_fix(scene, ob, distToBe, strength, cp);
+
+ 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;
+}
+
+void OBJECT_OT_vertex_group_fix(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Fix Vertex Group Deform";
+ ot->idname= "OBJECT_OT_vertex_group_fix";
+
+ /* api callbacks */
+ ot->poll= vertex_group_poll;
+ ot->exec= vertex_group_fix_exec;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+ RNA_def_float(ot->srna, "dist", 0.0f, -FLT_MAX, FLT_MAX, "Distance", "The distance to move to.", -10.0f, 10.0f);
+ RNA_def_float(ot->srna, "strength", 1.f, -2.0f, FLT_MAX, "Strength", "The distance moved can be changed by this multiplier.", -2.0f, 2.0f);
+ RNA_def_float(ot->srna, "cp", 1.0f, 0.05f, FLT_MAX, "Change Sensitivity", "Changes the amount weights are altered with each iteration: lower values are slower.", 0.05f, 1.f);
+}
+/* Jason was here */
+static int vertex_group_invert_locks_exec(bContext *C, wmOperator *op)
+{
+ Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+
+ vgroup_invert_locks(ob);
+
+ return OPERATOR_FINISHED;
+}
+/* Jason was here */
+void OBJECT_OT_vertex_group_invert_locks(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Invert All Vertex Group Locks";
+ ot->idname= "OBJECT_OT_vertex_group_invert_locks";
+
+ /* api callbacks */
+ ot->poll= vertex_group_poll;
+ ot->exec= vertex_group_invert_locks_exec;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+/* Jason was here */
+static int vertex_group_lock_all_exec(bContext *C, wmOperator *op)
+{
+ Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+
+ vgroup_lock_all(ob);
+
+ return OPERATOR_FINISHED;
+}
+/* Jason was here */
+void OBJECT_OT_vertex_group_lock_all(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Turn on all Vertex Group Locks";
+ ot->idname= "OBJECT_OT_vertex_group_lock_all";
+
+ /* api callbacks */
+ ot->poll= vertex_group_poll;
+ ot->exec= vertex_group_lock_all_exec;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+/* Jason was here */
+static int vertex_group_unlock_all_exec(bContext *C, wmOperator *op)
+{
+ Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+
+ vgroup_unlock_all(ob);
+ return OPERATOR_FINISHED;
+}
+/* Jason was here */
+void OBJECT_OT_vertex_group_unlock_all(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Turn off all Vertex Group Locks";
+ ot->idname= "OBJECT_OT_vertex_group_unlock_all";
+
+ /* api callbacks */
+ ot->poll= vertex_group_poll;
+ ot->exec= vertex_group_unlock_all_exec;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
static int vertex_group_invert_exec(bContext *C, wmOperator *op)
{
Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;