forked from bartvdbraak/blender
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:
parent
b9614b0e52
commit
3d5330f789
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user