diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2009-04-02 18:38:40 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2009-04-02 18:38:40 +0400 |
commit | e9ad9f894e2151fb192e8a4215b4ac6e73a28d0c (patch) | |
tree | 53e10812f555c7b41bb4f7b7cdd83619795988e8 | |
parent | 4bb41c3dcdd029db63435e83700520070703a9bc (diff) |
2.5: weight paint mode fix for corrupted layer data, and added
a customdata layer specifically to store weightpaint colors
instead of abusing the vertex colors layers.
-rw-r--r-- | source/blender/blenkernel/intern/DerivedMesh.c | 227 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/cdderivedmesh.c | 13 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/customdata.c | 8 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_draw.c | 4 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_customdata_types.h | 6 |
5 files changed, 123 insertions, 135 deletions
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 2ecc8cb1754..cbdbe19f0b9 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -1433,6 +1433,8 @@ static float *get_editmesh_orco_verts(EditMesh *em) return orco; } +/* orco custom data layer */ + static DerivedMesh *create_orco_dm(Object *ob, Mesh *me, EditMesh *em) { DerivedMesh *dm; @@ -1484,6 +1486,96 @@ static void add_orco_dm(Object *ob, EditMesh *em, DerivedMesh *dm, DerivedMesh * DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, orco); } +/* weight paint colors */ + +/* Something of a hack, at the moment deal with weightpaint + * by tucking into colors during modifier eval, only in + * wpaint mode. Works ok but need to make sure recalc + * happens on enter/exit wpaint. + */ + +void weight_to_rgb(float input, float *fr, float *fg, float *fb) +{ + float blend; + + blend= ((input/2.0f)+0.5f); + + if (input<=0.25f){ // blue->cyan + *fr= 0.0f; + *fg= blend*input*4.0f; + *fb= blend; + } + else if (input<=0.50f){ // cyan->green + *fr= 0.0f; + *fg= blend; + *fb= blend*(1.0f-((input-0.25f)*4.0f)); + } + else if (input<=0.75){ // green->yellow + *fr= blend * ((input-0.50f)*4.0f); + *fg= blend; + *fb= 0.0f; + } + else if (input<=1.0){ // yellow->red + *fr= blend; + *fg= blend * (1.0f-((input-0.75f)*4.0f)); + *fb= 0.0f; + } +} + +static void calc_weightpaint_vert_color(Object *ob, ColorBand *coba, int vert, unsigned char *col) +{ + Mesh *me = ob->data; + float colf[4], input = 0.0f; + int i; + + if (me->dvert) { + for (i=0; i<me->dvert[vert].totweight; i++) + if (me->dvert[vert].dw[i].def_nr==ob->actdef-1) + input+=me->dvert[vert].dw[i].weight; + } + + CLAMP(input, 0.0f, 1.0f); + + if(coba) + do_colorband(coba, input, colf); + else + weight_to_rgb(input, colf, colf+1, colf+2); + + col[3] = (unsigned char)(colf[0] * 255.0f); + col[2] = (unsigned char)(colf[1] * 255.0f); + col[1] = (unsigned char)(colf[2] * 255.0f); + col[0] = 255; +} + +static ColorBand *stored_cb= NULL; + +void vDM_ColorBand_store(ColorBand *coba) +{ + stored_cb= coba; +} + +static void add_weight_mcol_dm(Object *ob, DerivedMesh *dm) +{ + Mesh *me = ob->data; + MFace *mf = me->mface; + ColorBand *coba= stored_cb; /* warning, not a local var */ + unsigned char *wtcol; + int i; + + wtcol = MEM_callocN (sizeof (unsigned char) * me->totface*4*4, "weightmap"); + + memset(wtcol, 0x55, sizeof (unsigned char) * me->totface*4*4); + for (i=0; i<me->totface; i++, mf++) { + calc_weightpaint_vert_color(ob, coba, mf->v1, &wtcol[(i*4 + 0)*4]); + calc_weightpaint_vert_color(ob, coba, mf->v2, &wtcol[(i*4 + 1)*4]); + calc_weightpaint_vert_color(ob, coba, mf->v3, &wtcol[(i*4 + 2)*4]); + if (mf->v4) + calc_weightpaint_vert_color(ob, coba, mf->v4, &wtcol[(i*4 + 3)*4]); + } + + CustomData_add_layer(&dm->faceData, CD_WEIGHT_MCOL, CD_ASSIGN, wtcol, dm->numFaceData); +} + static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos)[3], DerivedMesh **deform_r, DerivedMesh **final_r, int useRenderParams, int useDeform, @@ -1547,6 +1639,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos */ if (deform_r) { *deform_r = CDDM_from_mesh(me, ob); + if(deformedVerts) { CDDM_apply_vert_coords(*deform_r, deformedVerts); CDDM_calc_normals(*deform_r); @@ -1632,6 +1725,9 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos CDDM_apply_vert_coords(dm, deformedVerts); CDDM_calc_normals(dm); } + + if(dataMask & CD_MASK_WEIGHT_MCOL) + add_weight_mcol_dm(ob, dm); } /* create an orco derivedmesh in parallel */ @@ -1695,14 +1791,21 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos CDDM_apply_vert_coords(finaldm, deformedVerts); CDDM_calc_normals(finaldm); + + if(dataMask & CD_MASK_WEIGHT_MCOL) + add_weight_mcol_dm(ob, finaldm); } else if(dm) { finaldm = dm; } else { finaldm = CDDM_from_mesh(me, ob); + if(deformedVerts) { CDDM_apply_vert_coords(finaldm, deformedVerts); CDDM_calc_normals(finaldm); } + + if(dataMask & CD_MASK_WEIGHT_MCOL) + add_weight_mcol_dm(ob, finaldm); } /* add an orco layer if needed */ @@ -1932,96 +2035,6 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri MEM_freeN(deformedVerts); } -/***/ - - - /* Something of a hack, at the moment deal with weightpaint - * by tucking into colors during modifier eval, only in - * wpaint mode. Works ok but need to make sure recalc - * happens on enter/exit wpaint. - */ - -void weight_to_rgb(float input, float *fr, float *fg, float *fb) -{ - float blend; - - blend= ((input/2.0f)+0.5f); - - if (input<=0.25f){ // blue->cyan - *fr= 0.0f; - *fg= blend*input*4.0f; - *fb= blend; - } - else if (input<=0.50f){ // cyan->green - *fr= 0.0f; - *fg= blend; - *fb= blend*(1.0f-((input-0.25f)*4.0f)); - } - else if (input<=0.75){ // green->yellow - *fr= blend * ((input-0.50f)*4.0f); - *fg= blend; - *fb= 0.0f; - } - else if (input<=1.0){ // yellow->red - *fr= blend; - *fg= blend * (1.0f-((input-0.75f)*4.0f)); - *fb= 0.0f; - } -} -static void calc_weightpaint_vert_color(Object *ob, ColorBand *coba, int vert, unsigned char *col) -{ - Mesh *me = ob->data; - float colf[4], input = 0.0f; - int i; - - if (me->dvert) { - for (i=0; i<me->dvert[vert].totweight; i++) - if (me->dvert[vert].dw[i].def_nr==ob->actdef-1) - input+=me->dvert[vert].dw[i].weight; - } - - CLAMP(input, 0.0f, 1.0f); - - if(coba) - do_colorband(coba, input, colf); - else - weight_to_rgb(input, colf, colf+1, colf+2); - - col[3] = (unsigned char)(colf[0] * 255.0f); - col[2] = (unsigned char)(colf[1] * 255.0f); - col[1] = (unsigned char)(colf[2] * 255.0f); - col[0] = 255; -} - -static ColorBand *stored_cb= NULL; - -void vDM_ColorBand_store(ColorBand *coba) -{ - stored_cb= coba; -} - -static unsigned char *calc_weightpaint_colors(Object *ob) -{ - Mesh *me = ob->data; - MFace *mf = me->mface; - ColorBand *coba= stored_cb; /* warning, not a local var */ - unsigned char *wtcol; - int i; - - wtcol = MEM_callocN (sizeof (unsigned char) * me->totface*4*4, "weightmap"); - - memset(wtcol, 0x55, sizeof (unsigned char) * me->totface*4*4); - for (i=0; i<me->totface; i++, mf++) { - calc_weightpaint_vert_color(ob, coba, mf->v1, &wtcol[(i*4 + 0)*4]); - calc_weightpaint_vert_color(ob, coba, mf->v2, &wtcol[(i*4 + 1)*4]); - calc_weightpaint_vert_color(ob, coba, mf->v3, &wtcol[(i*4 + 2)*4]); - if (mf->v4) - calc_weightpaint_vert_color(ob, coba, mf->v4, &wtcol[(i*4 + 3)*4]); - } - - return wtcol; -} - static void clear_mesh_caches(Object *ob) { Mesh *me= ob->data; @@ -2052,42 +2065,16 @@ static void clear_mesh_caches(Object *ob) static void mesh_build_data(Scene *scene, Object *ob, CustomDataMask dataMask) { - Mesh *me = ob->data; - float min[3], max[3]; - //int needMapping= 0; - Object *obact = scene->basact?scene->basact->object:NULL; int editing = (FACESEL_PAINT_TEST)|(G.f & G_PARTICLEEDIT); int needMapping = editing && (ob==obact); + float min[3], max[3]; clear_mesh_caches(ob); - if( (G.f & G_WEIGHTPAINT) && ob==obact ) { -// if(dataMask & CD_MASK_WEIGHTPAINT) { - MCol *wpcol = (MCol*)calc_weightpaint_colors(ob); - int layernum = CustomData_number_of_layers(&me->fdata, CD_MCOL); - int prevactive = CustomData_get_active_layer(&me->fdata, CD_MCOL); - int prevrender = CustomData_get_render_layer(&me->fdata, CD_MCOL); - - /* ugly hack here, we temporarily add a new active mcol layer with - weightpaint colors in it, that is then duplicated in CDDM_from_mesh */ - CustomData_add_layer(&me->fdata, CD_MCOL, CD_ASSIGN, wpcol, me->totface); - CustomData_set_layer_active(&me->fdata, CD_MCOL, layernum); - CustomData_set_layer_render(&me->fdata, CD_MCOL, layernum); - - mesh_calc_modifiers(scene, ob, NULL, &ob->derivedDeform, - &ob->derivedFinal, 0, 1, - needMapping, dataMask, -1); - - CustomData_free_layer_active(&me->fdata, CD_MCOL, me->totface); - CustomData_set_layer_active(&me->fdata, CD_MCOL, prevactive); - CustomData_set_layer_render(&me->fdata, CD_MCOL, prevrender); - } - else { - mesh_calc_modifiers(scene, ob, NULL, &ob->derivedDeform, - &ob->derivedFinal, G.rendering, 1, - needMapping, dataMask, -1); - } + mesh_calc_modifiers(scene, ob, NULL, &ob->derivedDeform, + &ob->derivedFinal, 0, 1, + needMapping, dataMask, -1); INIT_MINMAX(min, max); diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 538e65bfdc9..7969eac2bf0 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -482,10 +482,14 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us CDDerivedMesh *cddm = (CDDerivedMesh*) dm; MVert *mv = cddm->mvert; MFace *mf = cddm->mface; - MCol *mc = DM_get_face_data_layer(dm, CD_MCOL); + MCol *mc; float *nors= dm->getFaceDataArray(dm, CD_NORMAL); int i, orig, *index = DM_get_face_data_layer(dm, CD_ORIGINDEX); + mc = DM_get_face_data_layer(dm, CD_WEIGHT_MCOL); + if(!mc) + mc = DM_get_face_data_layer(dm, CD_MCOL); + for(i = 0; i < dm->numFaceData; i++, mf++) { int drawSmooth = (mf->flag & ME_SMOOTH); @@ -926,13 +930,6 @@ DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *ob) index = CustomData_get_layer(&dm->faceData, CD_ORIGINDEX); for(i = 0; i < mesh->totface; ++i, ++index) *index = i; - - /* works in conjunction with hack during modifier calc, where active mcol - layer with weight paint colors is temporarily added */ - /* XXX make this real but temporary layer */ -// if ((G.f & G_WEIGHTPAINT) && -// (ob && ob==(scene->basact?scene->basact->object:NULL))) -// CustomData_duplicate_referenced_layer(&dm->faceData, CD_MCOL); return dm; } diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index d9f76256529..8c1065c1d84 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -707,14 +707,16 @@ const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = { {sizeof(MLoopCol), "MLoopCol", 1, "Col", NULL, NULL, layerInterp_mloopcol, NULL, layerDefault_mloopcol}, {sizeof(float)*3*4, "", 0, NULL, NULL, NULL, NULL, NULL, NULL}, {sizeof(MDisps), "MDisps", 1, NULL, layerCopy_mdisps, - layerFree_mdisps, layerInterp_mdisps, layerSwap_mdisps, NULL} + layerFree_mdisps, layerInterp_mdisps, layerSwap_mdisps, NULL}, + {sizeof(MCol)*4, "MCol", 4, "WeightCol", NULL, NULL, layerInterp_mcol, + layerSwap_mcol, layerDefault_mcol}, }; const char *LAYERTYPENAMES[CD_NUMTYPES] = { "CDMVert", "CDMSticky", "CDMDeformVert", "CDMEdge", "CDMFace", "CDMTFace", "CDMCol", "CDOrigIndex", "CDNormal", "CDFlags","CDMFloatProperty", "CDMIntProperty","CDMStringProperty", "CDOrigSpace", "CDOrco", "CDMTexPoly", "CDMLoopUV", - "CDMloopCol", "CDTangent", "CDMDisps"}; + "CDMloopCol", "CDTangent", "CDMDisps", "CDWeightMCol"}; const CustomDataMask CD_MASK_BAREMESH = CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE; @@ -728,7 +730,7 @@ const CustomDataMask CD_MASK_EDITMESH = const CustomDataMask CD_MASK_DERIVEDMESH = CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_ORIGINDEX | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | - CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORCO | CD_MASK_TANGENT; + CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORCO | CD_MASK_TANGENT | CD_MASK_WEIGHT_MCOL; const CustomDataMask CD_MASK_BMESH = CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR; const CustomDataMask CD_MASK_FACECORNERS = diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 00843a58ba7..0a063182368 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -1858,8 +1858,10 @@ static CustomDataMask get_viewedit_datamask(bScreen *screen) } /* check if we need mcols due to vertex paint or weightpaint */ - if(G.f & G_VERTEXPAINT || G.f & G_WEIGHTPAINT) + if(G.f & G_VERTEXPAINT) mask |= CD_MASK_MCOL; + if(G.f & G_WEIGHTPAINT) + mask |= CD_MASK_WEIGHT_MCOL; if(G.f & G_SCULPTMODE) mask |= CD_MASK_MDISPS; diff --git a/source/blender/makesdna/DNA_customdata_types.h b/source/blender/makesdna/DNA_customdata_types.h index 510ccfb67fc..18c18d9e9dd 100644 --- a/source/blender/makesdna/DNA_customdata_types.h +++ b/source/blender/makesdna/DNA_customdata_types.h @@ -75,9 +75,8 @@ typedef struct CustomData { #define CD_MLOOPCOL 17 #define CD_TANGENT 18 #define CD_MDISPS 19 -#define CD_NUMTYPES 20 - /* fake type, derivedmesh wants CustomDataMask for weightpaint too, is not stored */ -#define CD_WEIGHTPAINT 30 +#define CD_WEIGHT_MCOL 20 /* for displaying weightpaint colors */ +#define CD_NUMTYPES 21 /* Bits for CustomDataMask */ #define CD_MASK_MVERT (1 << CD_MVERT) @@ -100,6 +99,7 @@ typedef struct CustomData { #define CD_MASK_MLOOPCOL (1 << CD_MLOOPCOL) #define CD_MASK_TANGENT (1 << CD_TANGENT) #define CD_MASK_MDISPS (1 << CD_MDISPS) +#define CD_MASK_WEIGHT_MCOL (1 << CD_WEIGHT_MCOL) /* derivedmesh wants CustomDataMask for weightpaint too, is not customdata though */ #define CD_MASK_WEIGHTPAINT (1 << CD_WEIGHTPAINT) |