diff options
author | Ton Roosendaal <ton@blender.org> | 2005-10-22 18:05:25 +0400 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2005-10-22 18:05:25 +0400 |
commit | 5e8131309e43c5638548d622c1df806ca9e63c4d (patch) | |
tree | d74ec7f5b40bb3237c239dac8daec97e50992d69 /source | |
parent | ed7fb486a13e42f4ae095ee09d6b89769f3570e0 (diff) |
New: X-axis mirror weightpainting.
- Set the button in Paint Panel, Edit buttons context
- It assumes the mesh to be near-perfectly mirrored. Current threshold is
set to 0.0001 (maximum difference allowed).
In order to evaluate proper mirroring, a new option will be added in
Mesh editmode later.
- When the flipped group doesn't exist yet, it creates the group
- Of course this doesn't work for mirror modifier!
New: Select/activate flipped bone or vertex group
- Press SHIFT+F in PoseMode or WeightPaint mode to get the flipped bone.
Is especially to see while painting if the mirror copying works OK.
New: "Apply Envelope to VertexGroup" uses X-mirror option too.
Todo; check on mirror vertex painting, and mirror Mesh editmode....
The implementation is based on a 8x8x8 Octree, where vertex locations are
stored. Vertices on the threshold boundary of an Octree node are filled in
the neighbour nodes as well, ensuring that the lookup works with threshold.
The current size of the Octree gives good speedup, even for 128k vertices
it only needs 256 lookup cycles per checked vertex.
Same code could be used for the bevel tool for example.
src/meshtools.c:
int mesh_octree_table(Object *ob, float *co, char mode)
- mode 's' or 'e' is "start octree" or "end octree"
- mode 'u' is "use", it then returns an index nr of the found vertex.
(return -1 if not found)
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/BKE_bad_level_calls.h | 7 | ||||
-rw-r--r-- | source/blender/blenkernel/bad_level_call_stubs/stubs.c | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/blender.c | 2 | ||||
-rw-r--r-- | source/blender/include/BIF_meshtools.h | 4 | ||||
-rw-r--r-- | source/blender/include/BIF_poseobject.h | 1 | ||||
-rw-r--r-- | source/blender/include/blendef.h | 3 | ||||
-rw-r--r-- | source/blender/src/buttons_editing.c | 7 | ||||
-rw-r--r-- | source/blender/src/meshtools.c | 183 | ||||
-rw-r--r-- | source/blender/src/poseobject.c | 82 | ||||
-rw-r--r-- | source/blender/src/space.c | 14 | ||||
-rw-r--r-- | source/blender/src/vpaint.c | 87 |
11 files changed, 361 insertions, 30 deletions
diff --git a/source/blender/blenkernel/BKE_bad_level_calls.h b/source/blender/blenkernel/BKE_bad_level_calls.h index ac91ea746eb..905b6d3bf74 100644 --- a/source/blender/blenkernel/BKE_bad_level_calls.h +++ b/source/blender/blenkernel/BKE_bad_level_calls.h @@ -37,6 +37,11 @@ #ifndef BKE_BAD_LEVEL_CALLS_H #define BKE_BAD_LEVEL_CALLS_H +/* blender.c */ +void freeAllRad(void); +void free_editText(void); +void free_vertexpaint(void); + /* readfile.c */ struct PluginSeq; void open_plugin_seq(struct PluginSeq *pis, char *seqname); @@ -47,8 +52,6 @@ void check_imasel_copy(struct SpaceImaSel *simasel); struct ScrArea; struct bScreen; void unlink_screen(struct bScreen *sc); -void freeAllRad(void); -void free_editText(void); void setscreen(struct bScreen *sc); void force_draw_all(int); /* otherwise the WHILE_SEQ doesn't work */ diff --git a/source/blender/blenkernel/bad_level_call_stubs/stubs.c b/source/blender/blenkernel/bad_level_call_stubs/stubs.c index 332706419d6..ca3b30fae96 100644 --- a/source/blender/blenkernel/bad_level_call_stubs/stubs.c +++ b/source/blender/blenkernel/bad_level_call_stubs/stubs.c @@ -55,6 +55,7 @@ void unlink_screen(struct bScreen *sc){} void freeAllRad(void){} void free_editText(void){} void free_editArmature(void){} +void free_vertexpaint(void){} char *getIpoCurveName( struct IpoCurve * icu ) { diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 2fca941a651..16ed62d9222 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -260,6 +260,8 @@ static void clear_global(void) G.sima= NULL; G.sipo= NULL; + free_vertexpaint(); + G.f &= ~(G_WEIGHTPAINT + G_VERTEXPAINT + G_FACESELECT); } diff --git a/source/blender/include/BIF_meshtools.h b/source/blender/include/BIF_meshtools.h index d12087bc309..b5f5a91c50c 100644 --- a/source/blender/include/BIF_meshtools.h +++ b/source/blender/include/BIF_meshtools.h @@ -33,6 +33,8 @@ #ifndef BIF_MESHTOOLS_H #define BIF_MESHTOOLS_H +struct Object; + extern void join_mesh(void); extern void fasterdraw(void); @@ -40,6 +42,8 @@ extern void slowerdraw(void); extern void sort_faces(void); +extern int mesh_octree_table(struct Object *ob, float *co, char mode); +extern int mesh_get_x_mirror_vert(struct Object *ob, int index); #endif diff --git a/source/blender/include/BIF_poseobject.h b/source/blender/include/BIF_poseobject.h index e559e7da0f5..2842da796bf 100644 --- a/source/blender/include/BIF_poseobject.h +++ b/source/blender/include/BIF_poseobject.h @@ -61,6 +61,7 @@ void paste_posebuf (int flip); void pose_adds_vgroups(struct Object *meshobj); void pose_flip_names(void); +void pose_activate_flipped_bone(void); #endif diff --git a/source/blender/include/blendef.h b/source/blender/include/blendef.h index e0c40760061..9826e6cc2f7 100644 --- a/source/blender/include/blendef.h +++ b/source/blender/include/blendef.h @@ -393,11 +393,12 @@ #define R_DISPLAYWIN 1 #define R_DISPLAYAUTO 2 - /* Gvp.flag */ + /* Gvp.flag and Gwp.flag */ #define VP_COLINDEX 1 #define VP_AREA 2 #define VP_SOFT 4 #define VP_NORMALS 8 #define VP_SPRAY 16 +#define VP_MIRROR_X 32 #endif diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 93751c5b655..c774b50d30e 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -3311,7 +3311,7 @@ static void editing_panel_links(Object *ob) if (ob->actdef){ defGroup = BLI_findlink(&ob->defbase, ob->actdef-1); - but= uiDefBut(block, TEX, REDRAWBUTSEDIT,"", 161,132,140-18,21, defGroup->name, 0, 32, 0, 0, "Displays current vertex group name. Click to change. (Match bone name for deformation.)"); + but= uiDefBut(block, TEX, REDRAWBUTSEDIT,"", 161,132,140-18,21, defGroup->name, 0, 31, 0, 0, "Displays current vertex group name. Click to change. (Match bone name for deformation.)"); uiButSetFunc(but, verify_vertexgroup_name_func, defGroup, NULL); uiDefButF(block, NUM, REDRAWVIEW3D, "Weight:", 143, 111, 140, 21, &editbutvweight, 0, 1, 10, 0, "Sets the current vertex group's bone deformation strength"); @@ -3543,8 +3543,9 @@ static void editing_panel_mesh_paint(void) if(ob){ uiBlockBeginAlign(block); - uiDefButBitC(block, TOG, OB_DRAWWIRE, REDRAWVIEW3D, "Wire", 10,10,150,19, &ob->dtx, 0, 0, 0, 0, "Displays the active object's wireframe in shaded drawing modes"); - uiDefBut(block, BUT, B_CLR_WPAINT, "Clear", 160,10,150,19, NULL, 0, 0, 0, 0, "Removes reference to this deform group from all vertices"); + uiDefButBitS(block, TOG, VP_MIRROR_X, REDRAWVIEW3D, "X-Mirror", 10,10,100,19, &Gwp.flag, 0, 0, 0, 0, "Mirrored Paint, applying on mirrored Weight Group name"); + uiDefButBitC(block, TOG, OB_DRAWWIRE, REDRAWVIEW3D, "Wire", 110,10,100,19, &ob->dtx, 0, 0, 0, 0, "Displays the active object's wireframe in shaded drawing modes"); + uiDefBut(block, BUT, B_CLR_WPAINT, "Clear", 210,10,100,19, NULL, 0, 0, 0, 0, "Removes reference to this deform group from all vertices"); uiBlockEndAlign(block); } } diff --git a/source/blender/src/meshtools.c b/source/blender/src/meshtools.c index 1fd3abd3145..d55df548bfb 100644 --- a/source/blender/src/meshtools.c +++ b/source/blender/src/meshtools.c @@ -590,4 +590,187 @@ void sort_faces(void) DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); } +/* ********************* MESH VERTEX OCTREE LOOKUP ************* */ +#define MOC_RES 8 +#define MOC_NODE_RES 8 +#define MOC_THRESH 0.0001f + +typedef struct MocNode { + struct MocNode *next; + int index[MOC_NODE_RES]; +} MocNode; + +static int mesh_octree_get_base_offs(float *co, float *offs, float *div) +{ + int vx, vy, vz; + + vx= floor( (co[0]-offs[0])/div[0] ); + vy= floor( (co[1]-offs[1])/div[1] ); + vz= floor( (co[2]-offs[2])/div[2] ); + + CLAMP(vx, 0, MOC_RES-1); + CLAMP(vy, 0, MOC_RES-1); + CLAMP(vz, 0, MOC_RES-1); + + return (vx*MOC_RES*MOC_RES) + vy*MOC_RES + vz; +} + +static void mesh_octree_add_node(MocNode **bt, int index) +{ + if(*bt==NULL) { + *bt= MEM_callocN(sizeof(MocNode), "MocNode"); + (*bt)->index[0]= index; + } + else { + int a; + for(a=0; a<MOC_NODE_RES; a++) { + if((*bt)->index[a]==index) + return; + else if((*bt)->index[a]==0) { + (*bt)->index[a]= index; + return; + } + } + mesh_octree_add_node(&(*bt)->next, index); + } +} + +static void mesh_octree_free_node(MocNode **bt) +{ + if( (*bt)->next ) { + mesh_octree_free_node(&(*bt)->next); + } + MEM_freeN(*bt); +} + +static int mesh_octree_find_index(MocNode **bt, MVert *mvert, float *co) +{ + MVert *testvert; + int a; + + if(*bt==NULL) + return -1; + + for(a=0; a<MOC_NODE_RES; a++) { + if((*bt)->index[a]) { + testvert= mvert+(*bt)->index[a]-1; + + if(FloatCompare(testvert->co, co, MOC_THRESH)) + return (*bt)->index[a]-1; + } + else return -1; + } + if( (*bt)->next) + return mesh_octree_find_index(&(*bt)->next, mvert, co); + + return -1; +} + +/* temporal define, just to make nicer code below */ +#define MOC_ADDNODE(vx, vy, vz) mesh_octree_add_node(basetable + ((vx)*MOC_RES*MOC_RES) + (vy)*MOC_RES + (vz), index) + +static void mesh_octree_add_nodes(MocNode **basetable, float *co, float *offs, float *div, int index) +{ + float fx, fy, fz; + int vx, vy, vz; + + fx= (co[0]-offs[0])/div[0]; + fy= (co[1]-offs[1])/div[1]; + fz= (co[2]-offs[2])/div[2]; + CLAMP(fx, 0.0f, MOC_RES-MOC_THRESH); + CLAMP(fy, 0.0f, MOC_RES-MOC_THRESH); + CLAMP(fz, 0.0f, MOC_RES-MOC_THRESH); + + vx= floor(fx); + vy= floor(fy); + vz= floor(fz); + + MOC_ADDNODE(vx, vy, vz); + + if( vx>0 ) + if( fx-((float)vx)-MOC_THRESH < 0.0f) + MOC_ADDNODE(vx-1, vy, vz); + if( vx<MOC_RES-2 ) + if( fx-((float)vx)+MOC_THRESH > 1.0f) + MOC_ADDNODE(vx+1, vy, vz); + + if( vy>0 ) + if( fy-((float)vy)-MOC_THRESH < 0.0f) + MOC_ADDNODE(vx, vy-1, vz); + if( vy<MOC_RES-2 ) + if( fy-((float)vy)+MOC_THRESH > 1.0f) + MOC_ADDNODE(vx, vy+1, vz); + + if( vz>0 ) + if( fz-((float)vz)-MOC_THRESH < 0.0f) + MOC_ADDNODE(vx, vy, vz-1); + if( vz<MOC_RES-2 ) + if( fz-((float)vz)+MOC_THRESH > 1.0f) + MOC_ADDNODE(vx, vy, vz+1); + +} + +/* mode is 's' start, or 'e' end, or 'u' use */ +/* if end, ob can be NULL */ +int mesh_octree_table(Object *ob, float *co, char mode) +{ + MocNode **bt; + static MocNode **basetable= NULL; + static float offs[3], div[3]; + int a; + + if(mode=='u') { /* use table */ + if(basetable) { + Mesh *me= ob->data; + bt= basetable + mesh_octree_get_base_offs(co, offs, div); + return mesh_octree_find_index(bt, me->mvert, co); + } + return -1; + } + else if(mode=='s') { /* start table */ + Mesh *me= ob->data; + BoundBox *bb = mesh_get_bb(me); + MVert *mvert; + + /* for quick unit coordinate calculus */ + VECCOPY(offs, bb->vec[0]); + VecSubf(div, bb->vec[6], offs); + VecMulf(div, 1.0f/MOC_RES); + if(div[0]==0.0f) div[0]= 1.0f; + if(div[1]==0.0f) div[1]= 1.0f; + if(div[2]==0.0f) div[2]= 1.0f; + + if(basetable) /* error should not happen, added to prevent coding errors */ + error("Mesh octree table coding error"); + + basetable= MEM_callocN(MOC_RES*MOC_RES*MOC_RES*sizeof(void *), "sym table"); + + for(a=1, mvert= me->mvert; a<=me->totvert; a++, mvert++) { + mesh_octree_add_nodes(basetable, mvert->co, offs, div, a); + } + } + else if(mode=='e') { /* end table */ + if(basetable) { + for(a=0, bt=basetable; a<MOC_RES*MOC_RES*MOC_RES; a++, bt++) { + if(*bt) mesh_octree_free_node(bt); + } + MEM_freeN(basetable); + basetable= NULL; + } + } + return 0; +} + +int mesh_get_x_mirror_vert(Object *ob, int index) +{ + Mesh *me= ob->data; + MVert *mvert= me->mvert+index; + float vec[3]; + + vec[0]= -mvert->co[0]; + vec[1]= mvert->co[1]; + vec[2]= mvert->co[2]; + + return mesh_octree_table(ob, vec, 'u'); +} diff --git a/source/blender/src/poseobject.c b/source/blender/src/poseobject.c index 2300a3b6be7..499c55b688d 100644 --- a/source/blender/src/poseobject.c +++ b/source/blender/src/poseobject.c @@ -65,6 +65,7 @@ #include "BIF_graphics.h" #include "BIF_interface.h" #include "BIF_poseobject.h" +#include "BIF_meshtools.h" #include "BIF_space.h" #include "BIF_toolbox.h" #include "BIF_screen.h" @@ -73,6 +74,7 @@ #include "BSE_edit.h" #include "BSE_editipo.h" +#include "BSE_trans_types.h" #include "mydevice.h" #include "blendef.h" @@ -582,7 +584,7 @@ void paste_posebuf (int flip) struct vgroup_map { float head[3], tail[3]; Bone *bone; - bDeformGroup *dg; + bDeformGroup *dg, *dgflip; Object *meshobj; }; @@ -591,7 +593,6 @@ static void pose_adds_vgroups__mapFunc(void *userData, int index, float *co, flo struct vgroup_map *map= userData; float vec[3], fac; - VECCOPY(vec, co); Mat4MulVecfl(map->meshobj->obmat, vec); @@ -604,17 +605,27 @@ static void pose_adds_vgroups__mapFunc(void *userData, int index, float *co, flo else remove_vert_defgroup (map->meshobj, map->dg, index); + if(map->dgflip) { + int j= mesh_get_x_mirror_vert(map->meshobj, index); + if(j>=0) { + if(fac!=0.0f) + add_vert_to_defgroup (map->meshobj, map->dgflip, j, fac, WEIGHT_REPLACE); + else + remove_vert_defgroup (map->meshobj, map->dgflip, j); + } + } } - +/* context weightpaint and deformer in posemode */ void pose_adds_vgroups(Object *meshobj) { + extern VPaint Gwp; /* from vpaint */ struct vgroup_map map; DerivedMesh *dm; Object *poseobj= modifiers_isDeformedByArmature(meshobj); bPoseChannel *pchan; Bone *bone; - bDeformGroup *dg; + bDeformGroup *dg, *curdef; int DMneedsFree; if(poseobj==NULL || (poseobj->flag & OB_POSEMODE)==0) return; @@ -632,6 +643,20 @@ void pose_adds_vgroups(Object *meshobj) if(dg==NULL) dg= add_defgroup_name(meshobj, bone->name); + /* flipped bone */ + if(Gwp.flag & VP_MIRROR_X) { + char name[32]; + + BLI_strncpy(name, dg->name, 32); + bone_flip_name(name, 0); // 0 = don't strip off number extensions + + for (curdef = meshobj->defbase.first; curdef; curdef=curdef->next) + if (!strcmp(curdef->name, name)) + break; + map.dgflip= curdef; + } + else map.dgflip= NULL; + /* get the root of the bone in global coords */ VECCOPY(map.head, bone->arm_head); Mat4MulVecfl(poseobj->obmat, map.head); @@ -693,3 +718,52 @@ void pose_flip_names(void) BIF_undo_push("Flip names"); } + +/* context active object, or weightpainted object with armature in posemode */ +void pose_activate_flipped_bone(void) +{ + Object *ob= OBACT; + + if(ob==NULL) return; + + if(G.f & G_WEIGHTPAINT) { + ob= modifiers_isDeformedByArmature(ob); + } + if(ob && (ob->flag & OB_POSEMODE)) { + bPoseChannel *pchan, *pchanf; + + for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) { + if(pchan->bone->flag & BONE_ACTIVE) { + break; + } + } + if(pchan) { + char name[32]; + + BLI_strncpy(name, pchan->name, 32); + bone_flip_name(name, 1); // 0 = do not strip off number extensions + + pchanf= get_pose_channel(ob->pose, name); + if(pchanf && pchanf!=pchan) { + pchan->bone->flag &= ~(BONE_SELECTED|BONE_ACTIVE); + pchanf->bone->flag |= (BONE_SELECTED|BONE_ACTIVE); + + /* in weightpaint we select the associated vertex group too */ + if(G.f & G_WEIGHTPAINT) { + vertexgroup_select_by_name(OBACT, name); + DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA); + } + + select_actionchannel_by_name(ob->action, name, 1); + + allqueue(REDRAWVIEW3D, 0); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWIPO, 0); /* To force action/constraint ipo update */ + allqueue(REDRAWBUTSEDIT, 0); + allqueue(REDRAWBUTSOBJECT, 0); + allqueue(REDRAWOOPS, 0); + } + } + } +} + diff --git a/source/blender/src/space.c b/source/blender/src/space.c index 4f64b0fd87e..84ddf2c6aa7 100644 --- a/source/blender/src/space.c +++ b/source/blender/src/space.c @@ -1243,11 +1243,17 @@ static void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt) } else if(G.qual==LR_CTRLKEY) sort_faces(); - else if((G.qual==LR_SHIFTKEY)) - fly(); + else if((G.qual==LR_SHIFTKEY)) { + if(ob && (ob->flag & OB_POSEMODE)) + pose_activate_flipped_bone(); + else if(G.f & G_WEIGHTPAINT) + pose_activate_flipped_bone(); + else + fly(); + } else { - set_faceselect(); - } + set_faceselect(); + } break; case GKEY: diff --git a/source/blender/src/vpaint.c b/source/blender/src/vpaint.c index 5391e72853a..0a4a0c7805c 100644 --- a/source/blender/src/vpaint.c +++ b/source/blender/src/vpaint.c @@ -63,6 +63,7 @@ #include "DNA_view3d_types.h" #include "DNA_userdef_types.h" +#include "BKE_armature.h" #include "BKE_DerivedMesh.h" #include "BKE_depsgraph.h" #include "BKE_deform.h" @@ -73,15 +74,16 @@ #include "BKE_object.h" #include "BKE_utildefines.h" +#include "BIF_editview.h" #include "BIF_graphics.h" +#include "BIF_glutil.h" +#include "BIF_gl.h" #include "BIF_interface.h" +#include "BIF_meshtools.h" #include "BIF_mywindow.h" -#include "BIF_editview.h" #include "BIF_space.h" #include "BIF_screen.h" #include "BIF_toolbox.h" -#include "BIF_glutil.h" -#include "BIF_gl.h" #include "BDR_vpaint.h" @@ -459,6 +461,8 @@ void free_vertexpaint() if(wpaintundobuf) free_dverts(wpaintundobuf, totwpaintundo); wpaintundobuf= NULL; + + mesh_octree_table(NULL, NULL, 'e'); } @@ -882,17 +886,38 @@ void sample_wpaint() } +static void do_weight_paint_vertex(Object *ob, int index, int alpha, float paintweight, int vgroup_mirror) +{ + Mesh *me= ob->data; + MDeformWeight *dw, *uw; + int vgroup= ob->actdef-1; + + dw= verify_defweight(me->dvert+index, vgroup); + uw= verify_defweight(wpaintundobuf+index, vgroup); + wpaint_blend(dw, uw, (float)alpha/255.0, paintweight); + + if(Gwp.flag & VP_MIRROR_X) { /* x mirror painting */ + if(vgroup_mirror != -1) { + int j= mesh_get_x_mirror_vert(ob, index); + if(j>=0) { + /* copy, not paint again */ + uw= verify_defweight(me->dvert+j, vgroup_mirror); + uw->weight= dw->weight; + } + } + } +} void weight_paint(void) { extern float editbutvweight; - MDeformWeight *dw, *uw; Object *ob; Mesh *me; MFace *mface; TFace *tface; float mat[4][4], imat[4][4], paintweight; int index, totindex, alpha, totw; + int vgroup_mirror= -1; short mval[2], mvalo[2], firsttime=1, mousebut; if((G.f & G_WEIGHTPAINT)==0) return; @@ -964,6 +989,26 @@ void weight_paint(void) if (U.flag & USER_LMOUSESELECT) mousebut = R_MOUSE; else mousebut = L_MOUSE; + /* if mirror painting, find the other group */ + if(Gwp.flag & VP_MIRROR_X) { + bDeformGroup *defgroup= BLI_findlink(&ob->defbase, ob->actdef-1); + if(defgroup) { + bDeformGroup *curdef; + int actdef= 0; + char name[32]; + + BLI_strncpy(name, defgroup->name, 32); + bone_flip_name(name, 0); // 0 = don't strip off number extensions + + for (curdef = ob->defbase.first; curdef; curdef=curdef->next, actdef++) + if (!strcmp(curdef->name, name)) + break; + + if(curdef && curdef!=defgroup) + vgroup_mirror= actdef; + } + } + while (get_mbut() & mousebut) { getmouseco_areawin(mval); @@ -1029,6 +1074,7 @@ void weight_paint(void) if(mface->v4) (me->dvert+mface->v4)->flag= 1; if(Gwp.mode==VP_FILT) { + MDeformWeight *dw; dw= verify_defweight(me->dvert+mface->v1, ob->actdef-1); if(dw) {paintweight+= dw->weight; totw++;} dw= verify_defweight(me->dvert+mface->v2, ob->actdef-1); @@ -1056,9 +1102,7 @@ void weight_paint(void) if((me->dvert+mface->v1)->flag) { alpha= calc_vp_alpha_dl(&Gwp, dm, mface->v1, mval); if(alpha) { - dw= verify_defweight(me->dvert+mface->v1, ob->actdef-1); - uw= verify_defweight(wpaintundobuf+mface->v1, ob->actdef-1); - wpaint_blend(dw, uw, (float)alpha/255.0, paintweight); + do_weight_paint_vertex(ob, mface->v1, alpha, paintweight, vgroup_mirror); } (me->dvert+mface->v1)->flag= 0; } @@ -1066,9 +1110,7 @@ void weight_paint(void) if((me->dvert+mface->v2)->flag) { alpha= calc_vp_alpha_dl(&Gwp, dm, mface->v2, mval); if(alpha) { - dw= verify_defweight(me->dvert+mface->v2, ob->actdef-1); - uw= verify_defweight(wpaintundobuf+mface->v2, ob->actdef-1); - wpaint_blend(dw, uw, (float)alpha/255.0, paintweight); + do_weight_paint_vertex(ob, mface->v2, alpha, paintweight, vgroup_mirror); } (me->dvert+mface->v2)->flag= 0; } @@ -1076,9 +1118,7 @@ void weight_paint(void) if((me->dvert+mface->v3)->flag) { alpha= calc_vp_alpha_dl(&Gwp, dm, mface->v3, mval); if(alpha) { - dw= verify_defweight(me->dvert+mface->v3, ob->actdef-1); - uw= verify_defweight(wpaintundobuf+mface->v3, ob->actdef-1); - wpaint_blend(dw, uw, (float)alpha/255.0, paintweight); + do_weight_paint_vertex(ob, mface->v3, alpha, paintweight, vgroup_mirror); } (me->dvert+mface->v3)->flag= 0; } @@ -1087,9 +1127,7 @@ void weight_paint(void) if(mface->v4) { alpha= calc_vp_alpha_dl(&Gwp, dm, mface->v4, mval); if(alpha) { - dw= verify_defweight(me->dvert+mface->v4, ob->actdef-1); - uw= verify_defweight(wpaintundobuf+mface->v4, ob->actdef-1); - wpaint_blend(dw, uw, (float)alpha/255.0, paintweight); + do_weight_paint_vertex(ob, mface->v4, alpha, paintweight, vgroup_mirror); } (me->dvert+mface->v4)->flag= 0; } @@ -1339,12 +1377,29 @@ void set_wpaint(void) /* toggle */ } if(G.f & G_WEIGHTPAINT) { + Object *par; + setcursor_space(SPACE_VIEW3D, CURSOR_VPAINT); + + mesh_octree_table(ob, NULL, 's'); + + /* verify if active weight group is also active bone */ + par= modifiers_isDeformedByArmature(ob); + if(par && (par->flag & OB_POSEMODE)) { + bPoseChannel *pchan; + for(pchan= par->pose->chanbase.first; pchan; pchan= pchan->next) + if(pchan->bone->flag & BONE_ACTIVE) + break; + if(pchan) + vertexgroup_select_by_name(ob, pchan->name); + } } else { freefastshade(); /* to be sure */ if(!(G.f & G_FACESELECT)) setcursor_space(SPACE_VIEW3D, CURSOR_STD); + + mesh_octree_table(ob, NULL, 'e'); } } |