diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2011-10-11 18:30:53 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2011-10-11 18:30:53 +0400 |
commit | 4f33d65ba1f02f2cd3f340d0123900ea1beffd2c (patch) | |
tree | 05ef40081ce6be190a171e0fee09b12344e16eb6 /source/blender/editors/sculpt_paint | |
parent | 1ab9fc59b750b1dc5ebaacd30c6891949895a10d (diff) | |
parent | 79f21f88c2be305962f6432bf8b1af94056fd92b (diff) |
Cycles: svn merge -r40411:40934 ^/trunk/blender
Diffstat (limited to 'source/blender/editors/sculpt_paint')
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_image.c | 53 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_undo.c | 3 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_vertex.c | 172 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt.c | 6 |
4 files changed, 125 insertions, 109 deletions
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index 9dbede754f3..c0ced572515 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -358,9 +358,13 @@ typedef struct UndoImageTile { struct UndoImageTile *next, *prev; char idname[MAX_ID_NAME]; /* name instead of pointer*/ + char ibufname[IB_FILENAME_SIZE]; void *rect; int x, y; + + short source; + char gen_type; } UndoImageTile; static ImagePaintPartialRedraw imapaintpartial = {0, 0, 0, 0, 0}; @@ -391,8 +395,9 @@ static void *image_undo_push_tile(Image *ima, ImBuf *ibuf, ImBuf **tmpibuf, int int allocsize; for(tile=lb->first; tile; tile=tile->next) - if(tile->x == x_tile && tile->y == y_tile && strcmp(tile->idname, ima->id.name)==0) - return tile->rect; + if(tile->x == x_tile && tile->y == y_tile && ima->gen_type == tile->gen_type && ima->source == tile->source) + if(strcmp(tile->idname, ima->id.name)==0 && strcmp(tile->ibufname, ibuf->name)==0) + return tile->rect; if (*tmpibuf==NULL) *tmpibuf = IMB_allocImBuf(IMAPAINT_TILE_SIZE, IMAPAINT_TILE_SIZE, 32, IB_rectfloat|IB_rect); @@ -406,6 +411,11 @@ static void *image_undo_push_tile(Image *ima, ImBuf *ibuf, ImBuf **tmpibuf, int allocsize *= (ibuf->rect_float)? sizeof(float): sizeof(char); tile->rect= MEM_mapallocN(allocsize, "UndeImageTile.rect"); + strcpy(tile->ibufname, ibuf->name); + + tile->gen_type= ima->gen_type; + tile->source= ima->source; + undo_copy_tile(tile, *tmpibuf, ibuf, 0); undo_paint_push_count_alloc(UNDO_PAINT_IMAGE, allocsize); @@ -426,18 +436,30 @@ static void image_undo_restore(bContext *C, ListBase *lb) for(tile=lb->first; tile; tile=tile->next) { /* find image based on name, pointer becomes invalid with global undo */ - if(ima && strcmp(tile->idname, ima->id.name)==0); + if(ima && strcmp(tile->idname, ima->id.name)==0) { + /* ima is valid */ + } else { - for(ima=bmain->image.first; ima; ima=ima->id.next) - if(strcmp(tile->idname, ima->id.name)==0) - break; + ima= BLI_findstring(&bmain->image, tile->idname, offsetof(ID, name)); } ibuf= BKE_image_get_ibuf(ima, NULL); + if(ima && ibuf && strcmp(tile->ibufname, ibuf->name)!=0) { + /* current ImBuf filename was changed, probably current frame + was changed when paiting on image sequence, rather than storing + full image user (which isn't so obvious, btw) try to find ImBuf with + matched file name in list of already loaded images */ + + ibuf= BLI_findstring(&ima->ibufs, tile->ibufname, offsetof(ImBuf, name)); + } + if (!ima || !ibuf || !(ibuf->rect || ibuf->rect_float)) continue; + if (ima->gen_type != tile->gen_type || ima->source != tile->source) + continue; + undo_copy_tile(tile, tmpibuf, ibuf, 1); GPU_free_image(ima); /* force OpenGL reload */ @@ -1900,11 +1922,13 @@ static int IsectPT2Df_limit(float pt[2], float v1[2], float v2[2], float v3[2], /* Clip the face by a bucket and set the uv-space bucket_bounds_uv * so we have the clipped UV's to do pixel intersection tests with * */ -static int float_z_sort_flip(const void *p1, const void *p2) { +static int float_z_sort_flip(const void *p1, const void *p2) +{ return (((float *)p1)[2] < ((float *)p2)[2] ? 1:-1); } -static int float_z_sort(const void *p1, const void *p2) { +static int float_z_sort(const void *p1, const void *p2) +{ return (((float *)p1)[2] < ((float *)p2)[2] ?-1:1); } @@ -2706,9 +2730,7 @@ static void project_bucket_init(const ProjPaintState *ps, const int thread_index tpage = project_paint_face_image(ps, face_index); if (tpage_last != tpage) { tpage_last = tpage; - - image_index = -1; /* sanity check */ - + for (image_index=0; image_index < ps->image_tot; image_index++) { if (ps->projImages[image_index].ima == tpage_last) { ibuf = ps->projImages[image_index].ibuf; @@ -3728,7 +3750,8 @@ static void do_projectpaint_draw(ProjPaintState *ps, ProjPixel *projPixel, float } } -static void do_projectpaint_draw_f(ProjPaintState *ps, ProjPixel *projPixel, float *rgba, float alpha, float mask, int use_color_correction) { +static void do_projectpaint_draw_f(ProjPaintState *ps, ProjPixel *projPixel, float *rgba, float alpha, float mask, int use_color_correction) +{ if (ps->is_texbrush) { /* rgba already holds a texture result here from higher level function */ float rgba_br[3]; @@ -3744,7 +3767,7 @@ static void do_projectpaint_draw_f(ProjPaintState *ps, ProjPixel *projPixel, flo if(use_color_correction){ srgb_to_linearrgb_v3_v3(rgba, ps->brush->rgb); } - else { + else { VECCOPY(rgba, ps->brush->rgb); } rgba[3] = 1.0; @@ -4917,7 +4940,6 @@ static void paint_apply_event(bContext *C, wmOperator *op, wmEvent *event) time= PIL_check_seconds_timer(); tablet= 0; - pressure= 0; pop->s.blend= pop->s.brush->blend; if(event->custom == EVT_DATA_TABLET) { @@ -4928,8 +4950,9 @@ static void paint_apply_event(bContext *C, wmOperator *op, wmEvent *event) if(wmtab->Active == EVT_TABLET_ERASER) pop->s.blend= IMB_BLEND_ERASE_ALPHA; } - else /* otherwise airbrush becomes 1.0 pressure instantly */ + else { /* otherwise airbrush becomes 1.0 pressure instantly */ pressure= pop->prev_pressure ? pop->prev_pressure : 1.0f; + } if(pop->first) { pop->prevmouse[0]= event->mval[0]; diff --git a/source/blender/editors/sculpt_paint/paint_undo.c b/source/blender/editors/sculpt_paint/paint_undo.c index ba0c2c8be92..345cda63f5a 100644 --- a/source/blender/editors/sculpt_paint/paint_undo.c +++ b/source/blender/editors/sculpt_paint/paint_undo.c @@ -34,6 +34,7 @@ #include "BLI_listbase.h" #include "BLI_utildefines.h" +#include "BLI_string.h" #include "DNA_userdef_types.h" @@ -106,7 +107,7 @@ static void undo_stack_push_begin(UndoStack *stack, const char *name, UndoRestor BLI_addtail(&stack->elems, uel); /* name can be a dynamic string */ - strncpy(uel->name, name, MAXUNDONAME-1); + BLI_strncpy(uel->name, name, sizeof(uel->name)); /* limit amount to the maximum amount*/ nr= 0; diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 11a46bb373b..cf90c43f3e1 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -290,7 +290,7 @@ static void make_vertexcol(Object *ob) /* single ob */ } /* mirror_vgroup is set to -1 when invalid */ -static void wpaint_mirror_vgroup_ensure(Object *ob, int *vgroup_mirror) +static int wpaint_mirror_vgroup_ensure(Object *ob) { bDeformGroup *defgroup= BLI_findlink(&ob->defbase, ob->actdef - 1); @@ -317,13 +317,12 @@ static void wpaint_mirror_vgroup_ensure(Object *ob, int *vgroup_mirror) /* curdef should never be NULL unless this is * a lamp and ED_vgroup_add_name fails */ if(curdef) { - *vgroup_mirror= mirrdef; - return; + return mirrdef; } } } - *vgroup_mirror= -1; + return -1; } static void copy_vpaint_prev(VPaint *vp, unsigned int *mcol, int tot) @@ -424,9 +423,9 @@ void wpaint_fill(VPaint *wp, Object *ob, float paintweight) vgroup= ob->actdef-1; - /* if mirror painting, find the other group */ + /* if mirror painting, find the other group */ if(me->editflag & ME_EDIT_MIRROR_X) { - wpaint_mirror_vgroup_ensure(ob, &vgroup_mirror); + vgroup_mirror= wpaint_mirror_vgroup_ensure(ob); } copy_wpaint_prev(wp, me->dvert, me->totvert); @@ -1114,31 +1113,33 @@ static void do_weight_paint_auto_normalize(MDeformVert *dvert, #endif /* the active group should be involved in auto normalize */ -static void do_weight_paint_auto_normalize_all_groups(MDeformVert *dvert, char *map, char do_auto_normalize) +static void do_weight_paint_auto_normalize_all_groups(MDeformVert *dvert, const char *vgroup_validmap, char do_auto_normalize) { -// MDeformWeight *dw = dvert->dw; - float sum=0.0f, fac=0.0f; - int i, tot=0; - - if (do_auto_normalize == FALSE) + if (do_auto_normalize == FALSE) { return; + } + else { + float sum= 0.0f, fac; + unsigned int i, tot=0; + MDeformWeight *dw; + + for (i= dvert->totweight, dw= dvert->dw; i != 0; i--, dw++) { + if (vgroup_validmap[dw->def_nr]) { + tot++; + sum += dw->weight; + } + } - for (i=0; i<dvert->totweight; i++) { - if (map[dvert->dw[i].def_nr]) { - tot += 1; - sum += dvert->dw[i].weight; + if ((tot == 0) || (sum == 1.0f) || (sum == 0.0f)) { + return; } - } - - if (!tot || sum == 1.0f) - return; - fac = sum; - fac = fac==0.0f ? 1.0f : 1.0f / fac; + fac= 1.0f / sum; - for (i=0; i<dvert->totweight; i++) { - if (map[dvert->dw[i].def_nr]) { - dvert->dw[i].weight *= fac; + for (i= dvert->totweight, dw= dvert->dw; i != 0; i--, dw++) { + if (vgroup_validmap[dw->def_nr]) { + dw->weight *= fac; + } } } } @@ -1580,43 +1581,49 @@ static void do_weight_paint_vertex( /* vars which remain the same for every vert ) { Mesh *me= ob->data; + MDeformVert *dv= &me->dvert[index]; MDeformWeight *dw, *uw; int vgroup= ob->actdef-1; if(wp->flag & VP_ONLYVGROUP) { - dw= defvert_find_index(&me->dvert[index], vgroup); + dw= defvert_find_index(dv, vgroup); uw= defvert_find_index(wp->wpaint_prev+index, vgroup); } else { - dw= defvert_verify_index(&me->dvert[index], vgroup); + dw= defvert_verify_index(dv, vgroup); uw= defvert_verify_index(wp->wpaint_prev+index, vgroup); } - if(dw==NULL || uw==NULL) + + if(dw==NULL || uw==NULL) { return; + } /* TODO: De-duplicate the simple weight paint - jason */ /* ... or not, since its <10 SLOC - campbell */ /* If there are no locks or multipaint, * then there is no need to run the more complicated checks */ - if( (wpi->do_multipaint == FALSE || wpi->defbase_tot_sel <= 1) && - (wpi->lock_flags == NULL || has_locked_group(&me->dvert[index], wpi->lock_flags) == FALSE)) + if( (wpi->do_multipaint == FALSE || wpi->defbase_tot_sel <= 1) && + (wpi->lock_flags == NULL || has_locked_group(dv, wpi->lock_flags) == FALSE)) { wpaint_blend(wp, dw, uw, alpha, paintweight, wpi->do_flip, FALSE); - do_weight_paint_auto_normalize_all_groups(&me->dvert[index], wpi->vgroup_validmap, wpi->do_auto_normalize); if(me->editflag & ME_EDIT_MIRROR_X) { /* x mirror painting */ - int j= mesh_get_x_mirror_vert(ob, index); - if(j>=0) { + int index_mirr= mesh_get_x_mirror_vert(ob, index); + if(index_mirr != -1) { + MDeformVert *dv_mirr= &me->dvert[index_mirr]; /* copy, not paint again */ - uw= defvert_verify_index(me->dvert+j, (wpi->vgroup_mirror != -1) ? wpi->vgroup_mirror : vgroup); - + uw= defvert_verify_index(dv_mirr, (wpi->vgroup_mirror != -1) ? wpi->vgroup_mirror : vgroup); uw->weight= dw->weight; - - do_weight_paint_auto_normalize_all_groups(me->dvert+j, wpi->vgroup_validmap, wpi->do_auto_normalize); } } + + /* important to normalize after mirror, otherwise mirror gets wight + * which has already been scaled down in relation to other weights, + * then scales a second time [#26193]. Tricky multi-paint code doesn't + * suffer from this problem - campbell */ + do_weight_paint_auto_normalize_all_groups(dv, wpi->vgroup_validmap, wpi->do_auto_normalize); } else { /* use locks and/or multipaint */ @@ -1627,7 +1634,7 @@ static void do_weight_paint_vertex( /* vars which remain the same for every vert float oldChange = 0; int i; MDeformWeight *tdw = NULL, *tuw; - MDeformVert dv= {NULL}; + MDeformVert dv_copy= {NULL}; oldw = dw->weight; wpaint_blend(wp, dw, uw, alpha, paintweight, wpi->do_flip, wpi->do_multipaint && wpi->defbase_tot_sel >1); @@ -1636,17 +1643,17 @@ static void do_weight_paint_vertex( /* vars which remain the same for every vert /* setup multi-paint */ if(wpi->defbase_tot_sel > 1 && wpi->do_multipaint) { - dv.dw= MEM_dupallocN(me->dvert[index].dw); - dv.flag = me->dvert[index].flag; - dv.totweight = me->dvert[index].totweight; + dv_copy.dw= MEM_dupallocN(dv->dw); + dv_copy.flag = dv->flag; + dv_copy.totweight = dv->totweight; tdw = dw; tuw = uw; change = get_mp_change(wp->wpaint_prev+index, wpi->defbase_sel, neww - oldw); if(change) { if(!tdw->weight) { - i = get_first_selected_nonzero_weight(&me->dvert[index], wpi->defbase_sel); + i = get_first_selected_nonzero_weight(dv, wpi->defbase_sel); if(i>=0) { - tdw = &(me->dvert[index].dw[i]); + tdw = &(dv->dw[i]); tuw = defvert_verify_index(wp->wpaint_prev+index, tdw->def_nr); } else { @@ -1660,7 +1667,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, &me->dvert[index]); + reset_to_prev(wp->wpaint_prev+index, dv); } else { /* the old change was more significant, so set @@ -1670,7 +1677,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, &me->dvert[index]); + reset_to_prev(wp->wpaint_prev+index, dv); } else { change = 0; @@ -1685,25 +1692,24 @@ 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, &me->dvert[index]); + reset_to_prev(&dv_copy, dv); change = 0; oldChange = 0; } - if(dv.dw) { - MEM_freeN(dv.dw); + if(dv_copy.dw) { + MEM_freeN(dv_copy.dw); } - /* dvert may have been altered greatly */ - dw = defvert_find_index(&me->dvert[index], vgroup); + /* dv may have been altered greatly */ + dw = defvert_find_index(dv, vgroup); if(me->editflag & ME_EDIT_MIRROR_X) { /* x mirror painting */ - int j= mesh_get_x_mirror_vert(ob, index); - if(j>=0) { + int index_mirr= mesh_get_x_mirror_vert(ob, index); + if(index_mirr != -1) { + MDeformVert *dv_mirr= &me->dvert[index_mirr]; /* copy, not paint again */ - uw= defvert_verify_index(me->dvert+j, (wpi->vgroup_mirror != -1) ? wpi->vgroup_mirror : vgroup); - + uw= defvert_verify_index(dv_mirr, (wpi->vgroup_mirror != -1) ? wpi->vgroup_mirror : vgroup); //uw->weight= dw->weight; - - apply_mp_locks_normalize(me, wpi, j, uw, tdw, change, oldChange, oldw, neww); + apply_mp_locks_normalize(me, wpi, index_mirr, uw, tdw, change, oldChange, oldw, neww); } } } @@ -1799,7 +1805,6 @@ struct WPaintData { float wpimat[3][3]; /*variables for auto normalize*/ - int auto_normalize; char *vgroup_validmap; /*stores if vgroups tie to deforming bones or not*/ char *lock_flags; int defbase_tot; @@ -1810,26 +1815,26 @@ static char *wpaint_make_validmap(Object *ob) bDeformGroup *dg; ModifierData *md; char *vgroup_validmap; - GHash *gh = BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "wpaint_make_validmap gh"); - int i = 0, step1=1; + GHash *gh; + int i, step1=1; - /*add all names to a hash table*/ - for (dg=ob->defbase.first, i=0; dg; dg=dg->next, i++) { - BLI_ghash_insert(gh, dg->name, NULL); + if(ob->defbase.first == NULL) { + return NULL; } - if (!i) - return NULL; + gh= BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "wpaint_make_validmap gh"); - vgroup_validmap= MEM_callocN(i, "wpaint valid map"); + /*add all names to a hash table*/ + for (dg=ob->defbase.first; dg; dg=dg->next) { + BLI_ghash_insert(gh, dg->name, NULL); + } /*now loop through the armature modifiers and identify deform bones*/ for (md = ob->modifiers.first; md; md= !md->next && step1 ? (step1=0), modifiers_getVirtualModifierList(ob) : md->next) { if (!(md->mode & (eModifierMode_Realtime|eModifierMode_Virtual))) continue; - if (md->type == eModifierType_Armature) - { + if (md->type == eModifierType_Armature) { ArmatureModifierData *amd= (ArmatureModifierData*) md; if(amd->object && amd->object->pose) { @@ -1848,12 +1853,12 @@ static char *wpaint_make_validmap(Object *ob) } } } - + + vgroup_validmap= MEM_mallocN(BLI_ghash_size(gh), "wpaint valid map"); + /*add all names to a hash table*/ for (dg=ob->defbase.first, i=0; dg; dg=dg->next, i++) { - if (BLI_ghash_lookup(gh, dg->name) != NULL) { - vgroup_validmap[i] = TRUE; - } + vgroup_validmap[i]= (BLI_ghash_lookup(gh, dg->name) != NULL); } BLI_ghash_free(gh, NULL, NULL); @@ -1891,21 +1896,12 @@ static int wpaint_stroke_test_start(bContext *C, wmOperator *op, wmEvent *UNUSED /*set up auto-normalize, and generate map for detecting which vgroups affect deform bones*/ - wpd->auto_normalize = ts->auto_normalize; wpd->defbase_tot = BLI_countlist(&ob->defbase); wpd->lock_flags = gen_lock_flags(ob, wpd->defbase_tot); - if (wpd->auto_normalize || ts->multipaint || wpd->lock_flags) + if (ts->auto_normalize || ts->multipaint || wpd->lock_flags) { wpd->vgroup_validmap = wpaint_make_validmap(ob); - - // if(qual & LR_CTRLKEY) { - // sample_wpaint(scene, ar, v3d, 0); - // return; - // } - // if(qual & LR_SHIFTKEY) { - // sample_wpaint(scene, ar, v3d, 1); - // return; - // } - + } + /* ALLOCATIONS! no return after this line */ /* painting on subsurfs should give correct points too, this returns me->totvert amount */ wpd->vertexcosnos= mesh_get_mapped_verts_nors(scene, ob); @@ -1933,9 +1929,7 @@ static int wpaint_stroke_test_start(bContext *C, wmOperator *op, wmEvent *UNUSED if(ob->defbase.first==NULL) { ED_vgroup_add(ob); } - - // if(ob->lay & v3d->lay); else error("Active object is not in this layer"); - + /* imat for normals */ mul_m4_m4m4(mat, ob->obmat, wpd->vc.rv3d->viewmat); invert_m4_m4(imat, mat); @@ -1943,7 +1937,7 @@ static int wpaint_stroke_test_start(bContext *C, wmOperator *op, wmEvent *UNUSED /* if mirror painting, find the other group */ if(me->editflag & ME_EDIT_MIRROR_X) { - wpaint_mirror_vgroup_ensure(ob, &wpd->vgroup_mirror); + wpd->vgroup_mirror= wpaint_mirror_vgroup_ensure(ob); } return 1; @@ -2006,7 +2000,7 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P wpi.vgroup_validmap= wpd->vgroup_validmap; wpi.do_flip= RNA_boolean_get(itemptr, "pen_flip"); wpi.do_multipaint= (ts->multipaint != 0); - wpi.do_auto_normalize= (ts->auto_normalize != 0); + wpi.do_auto_normalize= ((ts->auto_normalize != 0) && (wpi.vgroup_validmap != NULL)); /* *** done setting up WeightPaintInfo *** */ @@ -2108,7 +2102,7 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P if(indexar[index] && indexar[index]<=me->totface) { MFace *mf= me->mface + (indexar[index]-1); - unsigned int fidx= mf->v4 ? 3:2;; + unsigned int fidx= mf->v4 ? 3:2; do { unsigned int vidx= *(&mf->v1 + fidx); diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 0bdb027a903..5a888e6f595 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -154,7 +154,7 @@ static int sculpt_modifiers_active(Scene *scene, Sculpt *sd, Object *ob) if(mmd) return 0; - /* non-locked shaoe keys could be handled in the same way as deformed mesh */ + /* non-locked shape keys could be handled in the same way as deformed mesh */ if((ob->shapeflag&OB_SHAPE_LOCK)==0 && me->key && ob->shapenr) return 1; @@ -484,13 +484,11 @@ static float integrate_overlap(Brush* br) int i; int m= 10; float g = 1.0f/m; - float overlap; float max; - overlap= 0; max= 0; for(i= 0; i < m; i++) { - overlap = overlapped_curve(br, i*g); + float overlap= overlapped_curve(br, i*g); if (overlap > max) max = overlap; |