vertex group changes,

use more api functions more (some vertex group editing functions were copied about), also make some functions int oapi calls.

- remove defgroup_find_index(), use BLI_findlink instead since they both work the same way.
- move static function getNearestPointOnPlane() to BLI_math api function closest_to_plane_v3()
- ED_vgroup_give_parray() added option to return an array where unselected verts are NULL (simplifies code & works for lattice when it didn't before).
- more consistant error checking of ob->actdef.
This commit is contained in:
Campbell Barton 2011-12-14 21:08:08 +00:00
parent b9614b0e52
commit 3d5330f789
8 changed files with 471 additions and 590 deletions

@ -43,7 +43,6 @@ struct MDeformVert;
void defgroup_copy_list(struct ListBase *lb1, struct ListBase *lb2);
struct bDeformGroup *defgroup_duplicate(struct bDeformGroup *ingroup);
struct bDeformGroup *defgroup_find_name(struct Object *ob, const char *name);
int defgroup_find_index(struct Object *ob, struct bDeformGroup *dg);
int *defgroup_flip_map(struct Object *ob, int *flip_map_len, int use_default);
int *defgroup_flip_map_single(struct Object *ob, int *flip_map_len, int use_default, int defgroup);
int defgroup_flip_index(struct Object *ob, int index, int use_default);
@ -66,6 +65,7 @@ void defvert_sync_mapped(struct MDeformVert *dvert_dst, const struct MDeformVert
void defvert_remap (struct MDeformVert *dvert, int *map, const int map_len);
void defvert_flip(struct MDeformVert *dvert, const int *flip_map, const int flip_map_len);
void defvert_normalize(struct MDeformVert *dvert);
void defvert_normalize_lock(struct MDeformVert *dvert, const int def_nr_lock);
/* utility function, note that 32 chars is the maximum string length since its only
* used with defgroups currently */

@ -163,33 +163,85 @@ void defvert_sync_mapped(MDeformVert *dvert_dst, const MDeformVert *dvert_src,
/* be sure all flip_map values are valid */
void defvert_remap(MDeformVert *dvert, int *map, const int map_len)
{
MDeformWeight *dw;
int i;
for (i=0, dw=dvert->dw; i<dvert->totweight; i++, dw++) {
MDeformWeight *dw= dvert->dw;
unsigned int i;
for (i= dvert->totweight; i != 0; i--, dw++) {
if (dw->def_nr < map_len) {
dw->def_nr= map[dw->def_nr];
/* just incase */
BLI_assert(dw->def_nr >= 0);
}
}
}
void defvert_normalize(MDeformVert *dvert)
{
if (dvert->totweight<=0) {
if (dvert->totweight <= 0) {
/* nothing */
}
else if (dvert->totweight==1) {
dvert->dw[0].weight= 1.0f;
}
else {
int i;
float tot= 0.0f;
MDeformWeight *dw;
for (i=0, dw=dvert->dw; i < dvert->totweight; i++, dw++)
tot += dw->weight;
unsigned int i;
float tot_weight= 0.0f;
if (tot > 0.0f) {
for (i=0, dw=dvert->dw; i < dvert->totweight; i++, dw++)
dw->weight /= tot;
for (i= dvert->totweight, dw= dvert->dw; i != 0; i--, dw++) {
tot_weight += dw->weight;
}
if (tot_weight > 0.0f) {
float scalar= 1.0f / tot_weight;
for (i= dvert->totweight, dw= dvert->dw; i != 0; i--, dw++) {
dw->weight *= scalar;
/* incase of division errors with very low weights */
CLAMP(dw->weight, 0.0f, 1.0f);
}
}
}
}
void defvert_normalize_lock(MDeformVert *dvert, const int def_nr_lock)
{
if (dvert->totweight <= 0) {
/* nothing */
}
else if (dvert->totweight==1) {
dvert->dw[0].weight= 1.0f;
}
else {
MDeformWeight *dw_lock;
MDeformWeight *dw;
unsigned int i;
float tot_weight= 0.0f;
float lock_iweight= 1.0f;
for (i= dvert->totweight, dw= dvert->dw; i != 0; i--, dw++) {
if(dw->def_nr != def_nr_lock) {
tot_weight += dw->weight;
}
else {
dw_lock= dw;
lock_iweight = (1.0f - dw_lock->weight);
CLAMP(lock_iweight, 0.0f, 1.0f);
}
}
if (tot_weight > 0.0f) {
/* paranoid, should be 1.0 but incase of float error clamp anyway */
float scalar= (1.0f / tot_weight) * lock_iweight;
for (i= dvert->totweight, dw= dvert->dw; i != 0; i--, dw++) {
if(dw != dw_lock) {
dw->weight *= scalar;
/* incase of division errors with very low weights */
CLAMP(dw->weight, 0.0f, 1.0f);
}
}
}
}
}
@ -227,7 +279,7 @@ bDeformGroup *defgroup_find_name(Object *ob, const char *name)
int defgroup_name_index(Object *ob, const char *name)
{
/* Return the location of the named deform group within the list of
* deform groups. This function is a combination of defgroup_find_index and
* deform groups. This function is a combination of BLI_findlink and
* defgroup_find_name. The other two could be called instead, but that
* require looping over the vertexgroups twice.
*/
@ -244,46 +296,6 @@ int defgroup_name_index(Object *ob, const char *name)
return -1;
}
int defgroup_find_index(Object *ob, bDeformGroup *dg)
{
/* Fetch the location of this deform group
* within the linked list of deform groups.
* (this number is stored in the deform
* weights of the deform verts to link them
* to this deform group).
*
* note: this is zero based, ob->actdef starts at 1.
*/
bDeformGroup *eg;
int def_nr;
eg = ob->defbase.first;
def_nr = 0;
/* loop through all deform groups */
while (eg != NULL) {
/* if the current deform group is
* the one we are after, return
* def_nr
*/
if (eg == dg) {
break;
}
++def_nr;
eg = eg->next;
}
/* if there was no deform group found then
* return -1 (should set up a nice symbolic
* constant for this)
*/
if (eg == NULL) return -1;
return def_nr;
}
/* note, must be freed */
int *defgroup_flip_map(Object *ob, int *flip_map_len, int use_default)
{
@ -540,9 +552,9 @@ MDeformWeight *defvert_find_index(const MDeformVert *dvert, const int defgroup)
{
if (dvert && defgroup >= 0) {
MDeformWeight *dw = dvert->dw;
int i;
unsigned int i;
for (i=dvert->totweight; i>0; i--, dw++) {
for (i= dvert->totweight; i != 0; i--, dw++) {
if (dw->def_nr == defgroup) {
return dw;
}
@ -626,7 +638,7 @@ void defvert_remove_group(MDeformVert *dvert, MDeformWeight *dw)
*/
if (dvert->totweight) {
dw_new = MEM_mallocN(sizeof(MDeformWeight)*(dvert->totweight), __func__);
if (dvert->dw){
if (dvert->dw) {
memcpy(dw_new, dvert->dw, sizeof(MDeformWeight)*i);
memcpy(dw_new+i, dvert->dw+i+1, sizeof(MDeformWeight)*(dvert->totweight-i));
MEM_freeN(dvert->dw);

@ -65,7 +65,9 @@ float dist_to_plane_v3(const float p[3], const float plane_co[3], const float pl
float dist_to_line_segment_v3(const float p[3], const float l1[3], const float l2[3]);
float closest_to_line_v3(float r[3], const float p[3], const float l1[3], const float l2[3]);
float closest_to_line_v2(float r[2], const float p[2], const float l1[2], const float l2[2]);
void closest_to_line_segment_v3(float r[3], const float p[3], const float l1[3], const float l2[3]);
void closest_to_line_segment_v3(float r[3], const float p[3], const float l1[3], const float l2[3]);
void closest_to_plane_v3(float r[3], const float plane_co[3], const float plane_no_unit[3], const float pt[3]);
float line_point_factor_v3(const float p[3], const float l1[3], const float l2[3]);
float line_point_factor_v2(const float p[2], const float l1[2], const float l2[2]);

@ -209,33 +209,54 @@ float dist_to_line_segment_v2(const float v1[2], const float v2[2], const float
}
/* point closest to v1 on line v2-v3 in 2D */
void closest_to_line_segment_v2(float closest[2], const float p[2], const float l1[2], const float l2[2])
void closest_to_line_segment_v2(float close_r[2], const float p[2], const float l1[2], const float l2[2])
{
float lambda, cp[2];
lambda= closest_to_line_v2(cp,p, l1, l2);
if(lambda <= 0.0f)
copy_v2_v2(closest, l1);
copy_v2_v2(close_r, l1);
else if(lambda >= 1.0f)
copy_v2_v2(closest, l2);
copy_v2_v2(close_r, l2);
else
copy_v2_v2(closest, cp);
copy_v2_v2(close_r, cp);
}
/* point closest to v1 on line v2-v3 in 3D */
void closest_to_line_segment_v3(float closest[3], const float v1[3], const float v2[3], const float v3[3])
void closest_to_line_segment_v3(float close_r[3], const float v1[3], const float v2[3], const float v3[3])
{
float lambda, cp[3];
lambda= closest_to_line_v3(cp,v1, v2, v3);
if(lambda <= 0.0f)
copy_v3_v3(closest, v2);
copy_v3_v3(close_r, v2);
else if(lambda >= 1.0f)
copy_v3_v3(closest, v3);
copy_v3_v3(close_r, v3);
else
copy_v3_v3(closest, cp);
copy_v3_v3(close_r, cp);
}
/* find the closest point on a plane to another point and store it in close_r
* close_r: return coordinate
* plane_co: a point on the plane
* plane_no_unit: the plane's normal, and d is the last number in the plane equation 0 = ax + by + cz + d
* pt: the point that you want the nearest of
*/
// const float norm[3], const float coord[3], const float point[3], float dst_r[3]
void closest_to_plane_v3(float close_r[3], const float plane_co[3], const float plane_no_unit[3], const float pt[3])
{
float temp[3];
float dotprod;
sub_v3_v3v3(temp, pt, plane_co);
dotprod= dot_v3v3(temp, plane_no_unit);
close_r[0] = pt[0] - (plane_no_unit[0] * dotprod);
close_r[1] = pt[1] - (plane_no_unit[1] * dotprod);
close_r[2] = pt[2] - (plane_no_unit[2] * dotprod);
}
/* signed distance from the point to the plane in 3D */

@ -8725,9 +8725,9 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
}
if(ob->soft && ob->soft->vertgroup==0) {
bDeformGroup *locGroup = defgroup_find_name(ob, "SOFTGOAL");
if(locGroup){
if (locGroup) {
/* retrieve index for that group */
ob->soft->vertgroup = 1 + defgroup_find_index(ob, locGroup);
ob->soft->vertgroup = 1 + BLI_findindex(&ob->defbase, locGroup);
}
}
}

File diff suppressed because it is too large Load Diff

@ -1432,15 +1432,15 @@ static float get_mp_change(MDeformVert *odv, const int defbase_tot, const char *
/* change the weights back to the wv's weights
* it assumes you already have the correct pointer index */
static void reset_to_prev(MDeformVert *wv, MDeformVert *dvert)
static void defvert_reset_to_prev(MDeformVert *dv_prev, MDeformVert *dv)
{
MDeformWeight *dw= dvert->dw;
MDeformWeight *w;
MDeformWeight *dw= dv->dw;
MDeformWeight *dw_prev;
unsigned int i;
for (i= dvert->totweight; i != 0; i--, dw++) {
w= defvert_find_index(wv, dw->def_nr);
for (i= dv->totweight; i != 0; i--, dw++) {
dw_prev= defvert_find_index(dv_prev, dw->def_nr);
/* if there was no w when there is a d, then the old weight was 0 */
dw->weight = w ? w->weight : 0.0f;
dw->weight = dw_prev ? dw_prev->weight : 0.0f;
}
}
@ -1652,7 +1652,7 @@ static void do_weight_paint_vertex( /* vars which remain the same for every vert
if( testw > tuw->weight ) {
if(change > oldChange) {
/* reset the weights and use the new change */
reset_to_prev(wp->wpaint_prev+index, dv);
defvert_reset_to_prev(wp->wpaint_prev+index, dv);
}
else {
/* the old change was more significant, so set
@ -1662,7 +1662,7 @@ static void do_weight_paint_vertex( /* vars which remain the same for every vert
}
else {
if(change < oldChange) {
reset_to_prev(wp->wpaint_prev+index, dv);
defvert_reset_to_prev(wp->wpaint_prev+index, dv);
}
else {
change = 0;
@ -1677,7 +1677,7 @@ static void do_weight_paint_vertex( /* vars which remain the same for every vert
}
if(apply_mp_locks_normalize(me, wpi, index, dw, tdw, change, oldChange, oldw, neww)) {
reset_to_prev(&dv_copy, dv);
defvert_reset_to_prev(&dv_copy, dv);
change = 0;
oldChange = 0;
}
@ -1918,7 +1918,7 @@ static int wpaint_stroke_test_start(bContext *C, wmOperator *op, wmEvent *UNUSED
dg= ED_vgroup_add_name(ob, pchan->name); /* sets actdef */
}
else {
ob->actdef= 1 + defgroup_find_index(ob, dg);
ob->actdef= 1 + BLI_findindex(&ob->defbase, dg);
BLI_assert(ob->actdef >= 0);
}
}

@ -359,7 +359,7 @@ static void rna_Mesh_assign_verts_to_group(Object *ob, bDeformGroup *group, int
}
Mesh *me = (Mesh*)ob->data;
int group_index = defgroup_find_index(ob, group);
int group_index = BLI_findlink(&ob->defbase, group);
if (group_index == -1) {
BKE_report(reports, RPT_ERROR, "No deform groups assigned to mesh");
return;