diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2011-09-20 16:01:16 +0400 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2011-09-20 16:01:16 +0400 |
commit | 7172316b945c62797e6beba953ff203766614531 (patch) | |
tree | 640ac56fadded9c7686399b5a1f1c64f1a135700 /source | |
parent | 2015eefef70350382931881dd65ed2da09f8f2cd (diff) | |
parent | 78d4260144dbf01166fac8bc9303e6d5aa022f71 (diff) |
Merging r40366 through r40392 from trunk into soc-2011-garlicsoc-2011-garlic
Diffstat (limited to 'source')
110 files changed, 3229 insertions, 698 deletions
diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h index 7d60c00156d..8836999bc9b 100644 --- a/source/blender/blenkernel/BKE_armature.h +++ b/source/blender/blenkernel/BKE_armature.h @@ -100,6 +100,8 @@ void get_objectspace_bone_matrix (struct Bone* bone, float M_accumulatedMatrix[] void vec_roll_to_mat3(float *vec, float roll, float mat[][3]); void mat3_to_vec_roll(float mat[][3], float *vec, float *roll); +int get_selected_defgroups(struct Object *ob, char *defbase_sel, int defbase_len); + /* Common Conversions Between Co-ordinate Spaces */ void armature_mat_world_to_pose(struct Object *ob, float inmat[][4], float outmat[][4]); void armature_loc_world_to_pose(struct Object *ob, float *inloc, float *outloc); diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index 742240d53b5..333c00c3f2a 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -44,7 +44,7 @@ extern "C" { * and keep comment above the defines. * Use STRINGIFY() rather than defining with quotes */ #define BLENDER_VERSION 259 -#define BLENDER_SUBVERSION 2 +#define BLENDER_SUBVERSION 3 #define BLENDER_MINVERSION 250 #define BLENDER_MINSUBVERSION 0 diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h index 0c31083a266..8181ad6421c 100644 --- a/source/blender/blenkernel/BKE_image.h +++ b/source/blender/blenkernel/BKE_image.h @@ -168,6 +168,9 @@ struct Image *copy_image(struct Image *ima); /* merge source into dest, and free source */ void BKE_image_merge(struct Image *dest, struct Image *source); +/* check if texture has alpha (depth=32) */ +int BKE_image_has_alpha(struct Image *image); + /* image_gen.c */ void BKE_image_buf_fill_color(unsigned char *rect, float *rect_float, int width, int height, float color[4]); void BKE_image_buf_fill_checker(unsigned char *rect, float *rect_float, int height, int width); diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h index 85b6f8f78fb..cb6a0b9ab37 100644 --- a/source/blender/blenkernel/BKE_material.h +++ b/source/blender/blenkernel/BKE_material.h @@ -42,6 +42,8 @@ struct Main; struct Material; struct ID; struct Object; +struct Mesh; +struct MTFace; /* materials */ @@ -50,6 +52,7 @@ void free_material(struct Material *sc); void test_object_materials(struct ID *id); void resize_object_material(struct Object *ob, const short totcol); void init_material(struct Material *ma); +struct Material *add_material_main(struct Main *main, const char *name); struct Material *add_material(const char *name); struct Material *copy_material(struct Material *ma); struct Material *localize_material(struct Material *ma); @@ -66,19 +69,19 @@ short *give_totcolp(struct Object *ob); struct Material ***give_matarar_id(struct ID *id); /* same but for ID's */ short *give_totcolp_id(struct ID *id); -struct Material *give_current_material(struct Object *ob, int act); -struct ID *material_from(struct Object *ob, int act); -void assign_material(struct Object *ob, struct Material *ma, int act); -void assign_matarar(struct Object *ob, struct Material ***matar, int totcol); +struct Material *give_current_material(struct Object *ob, short act); +struct ID *material_from(struct Object *ob, short act); +void assign_material(struct Object *ob, struct Material *ma, short act); +void assign_matarar(struct Object *ob, struct Material ***matar, short totcol); -int find_material_index(struct Object *ob, struct Material *ma); +short find_material_index(struct Object *ob, struct Material *ma); int object_add_material_slot(struct Object *ob); int object_remove_material_slot(struct Object *ob); /* rna api */ void material_append_id(struct ID *id, struct Material *ma); -struct Material *material_pop_id(struct ID *id, int index, int remove_material_slot); +struct Material *material_pop_id(struct ID *id, int index, int remove_material_slot); /* index is an int because of RNA */ /* rendering */ @@ -101,6 +104,9 @@ void clear_mat_mtex_copybuf(void); void copy_mat_mtex_copybuf(struct ID *id); void paste_mat_mtex_copybuf(struct ID *id); +/* handle backward compatibility for tface/materials called from doversion (fileload=1) or Help Menu (fileload=0) */ +int do_version_tface(struct Main *main, int fileload); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index 08c150e30e3..95490b1aff6 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -84,7 +84,7 @@ void nurbs_to_mesh(struct Object *ob); void mesh_to_curve(struct Scene *scene, struct Object *ob); void free_dverts(struct MDeformVert *dvert, int totvert); void copy_dverts(struct MDeformVert *dst, struct MDeformVert *src, int totvert); /* __NLA */ -void mesh_delete_material_index(struct Mesh *me, int index); +void mesh_delete_material_index(struct Mesh *me, short index); void mesh_set_smooth_flag(struct Object *meshOb, int enableSmooth); struct BoundBox *mesh_get_bb(struct Object *ob); diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h index 0400f229083..2578a90808a 100644 --- a/source/blender/blenkernel/BKE_paint.h +++ b/source/blender/blenkernel/BKE_paint.h @@ -59,6 +59,7 @@ void paint_brush_set(struct Paint *paint, struct Brush *br); * Texture paint could be removed since selected faces are not used * however hiding faces is useful */ int paint_facesel_test(struct Object *ob); +int paint_vertsel_test(struct Object *ob); /* Session data (mode-specific) */ diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 7a02da57350..0b3bb4cc7cd 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -40,6 +40,7 @@ #include "DNA_cloth_types.h" #include "DNA_key_types.h" #include "DNA_meshdata_types.h" +#include "DNA_armature_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" // N_T @@ -59,6 +60,7 @@ #include "BKE_paint.h" #include "BKE_texture.h" #include "BKE_multires.h" +#include "BKE_armature.h" #include "BLO_sys_types.h" // for intptr_t support @@ -986,17 +988,14 @@ static void emDM_drawMappedFacesGLSL(DerivedMesh *dm, EditFace *efa; DMVertexAttribs attribs= {{{0}}}; GPUVertexAttribs gattribs; - MTFace *tf; - int transp, new_transp, orig_transp, tfoffset; - int i, b, matnr, new_matnr, dodraw, layer; + /* int tfoffset; */ /* UNUSED */ + int i, b, matnr, new_matnr, dodraw /* , layer */ /* UNUSED */; dodraw = 0; matnr = -1; - transp = GPU_get_material_blend_mode(); - orig_transp = transp; - layer = CustomData_get_layer_index(&em->fdata, CD_MTFACE); - tfoffset = (layer == -1)? -1: em->fdata.layers[layer].offset; + /* layer = CustomData_get_layer_index(&em->fdata, CD_MTFACE); */ /* UNUSED */ + /* tfoffset = (layer == -1)? -1: em->fdata.layers[layer].offset; */ /* UNUSED */ /* always use smooth shading even for flat faces, else vertex colors wont interpolate */ glShadeModel(GL_SMOOTH); @@ -1038,19 +1037,6 @@ static void emDM_drawMappedFacesGLSL(DerivedMesh *dm, DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs); } - if(tfoffset != -1) { - tf = (MTFace*)((char*)efa->data)+tfoffset; - new_transp = tf->transp; - - if(new_transp != transp) { - if(new_transp == GPU_BLEND_SOLID && orig_transp != GPU_BLEND_SOLID) - GPU_set_material_blend_mode(orig_transp); - else - GPU_set_material_blend_mode(new_transp); - transp = new_transp; - } - } - if(dodraw) { glBegin(efa->v4?GL_QUADS:GL_TRIANGLES); if (!drawSmooth) { @@ -1673,20 +1659,64 @@ void weight_to_rgb(float input, float *fr, float *fg, float *fb) } } -static void calc_weightpaint_vert_color(Object *ob, ColorBand *coba, int vert, unsigned char *col) +/* draw_flag's for calc_weightpaint_vert_color */ +enum { + CALC_WP_MULTIPAINT= (1<<0), + CALC_WP_AUTO_NORMALIZE= (1<<1), +}; + +static void calc_weightpaint_vert_color(Object *ob, ColorBand *coba, int vert, unsigned char *col, char *dg_flags, int selected, int UNUSED(unselected), const int draw_flag) { Mesh *me = ob->data; float colf[4], input = 0.0f; int i; + + int make_black= FALSE; + 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; - } + if ((selected > 1) && (draw_flag & CALC_WP_MULTIPAINT)) { + + int was_a_nonzero= FALSE; + for (i=0; i<me->dvert[vert].totweight; i++) { + /* in multipaint, get the average if auto normalize is inactive + * get the sum if it is active */ + if(dg_flags[me->dvert[vert].dw[i].def_nr]) { + if(me->dvert[vert].dw[i].weight) { + input+= me->dvert[vert].dw[i].weight; + was_a_nonzero= TRUE; + } + } + } - CLAMP(input, 0.0f, 1.0f); + /* make it black if the selected groups have no weight on a vertex */ + if(was_a_nonzero == FALSE) { + make_black = TRUE; + } + else if ((draw_flag & CALC_WP_AUTO_NORMALIZE) == FALSE) { + input /= selected; /* get the average */ + } + } + else { + /* default, non tricky behavior */ + 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; + } + } + } + } + if (make_black) { + col[3] = 0; + col[2] = 0; + col[1] = 0; + col[0] = 255; + return; + } + + CLAMP(input, 0.0f, 1.0f); + if(coba) do_colorband(coba, input, colf); else @@ -1705,7 +1735,7 @@ void vDM_ColorBand_store(ColorBand *coba) stored_cb= coba; } -static void add_weight_mcol_dm(Object *ob, DerivedMesh *dm) +static void add_weight_mcol_dm(Object *ob, DerivedMesh *dm, int const draw_flag) { Mesh *me = ob->data; MFace *mf = me->mface; @@ -1713,17 +1743,24 @@ static void add_weight_mcol_dm(Object *ob, DerivedMesh *dm) unsigned char *wtcol; int i; + int defbase_len = BLI_countlist(&ob->defbase); + char *defbase_sel = MEM_mallocN(defbase_len * sizeof(char), __func__); + int selected = get_selected_defgroups(ob, defbase_sel, defbase_len); + int unselected = defbase_len - selected; + 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]); + calc_weightpaint_vert_color(ob, coba, mf->v1, &wtcol[(i*4 + 0)*4], defbase_sel, selected, unselected, draw_flag); + calc_weightpaint_vert_color(ob, coba, mf->v2, &wtcol[(i*4 + 1)*4], defbase_sel, selected, unselected, draw_flag); + calc_weightpaint_vert_color(ob, coba, mf->v3, &wtcol[(i*4 + 2)*4], defbase_sel, selected, unselected, draw_flag); if (mf->v4) - calc_weightpaint_vert_color(ob, coba, mf->v4, &wtcol[(i*4 + 3)*4]); + calc_weightpaint_vert_color(ob, coba, mf->v4, &wtcol[(i*4 + 3)*4], defbase_sel, selected, unselected, draw_flag); } + MEM_freeN(defbase_sel); + CustomData_add_layer(&dm->faceData, CD_WEIGHT_MCOL, CD_ASSIGN, wtcol, dm->numFaceData); } @@ -1751,6 +1788,9 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos int has_multires = mmd != NULL, multires_applied = 0; int sculpt_mode = ob->mode & OB_MODE_SCULPT && ob->sculpt; + int draw_flag= ((scene->toolsettings->multipaint ? CALC_WP_MULTIPAINT : 0) | + (scene->toolsettings->auto_normalize ? CALC_WP_AUTO_NORMALIZE : 0)); + if(mmd && !mmd->sculptlvl) has_multires = 0; @@ -1930,7 +1970,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos } if((dataMask & CD_MASK_WEIGHT_MCOL) && (ob->mode & OB_MODE_WEIGHT_PAINT)) - add_weight_mcol_dm(ob, dm); + add_weight_mcol_dm(ob, dm, draw_flag); /* Constructive modifiers need to have an origindex * otherwise they wont have anywhere to copy the data from. @@ -2042,7 +2082,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos CDDM_calc_normals(finaldm); if((dataMask & CD_MASK_WEIGHT_MCOL) && (ob->mode & OB_MODE_WEIGHT_PAINT)) - add_weight_mcol_dm(ob, finaldm); + add_weight_mcol_dm(ob, finaldm, draw_flag); } else if(dm) { finaldm = dm; } else { @@ -2054,7 +2094,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos } if((dataMask & CD_MASK_WEIGHT_MCOL) && (ob->mode & OB_MODE_WEIGHT_PAINT)) - add_weight_mcol_dm(ob, finaldm); + add_weight_mcol_dm(ob, finaldm, draw_flag); } /* add an orco layer if needed */ @@ -2327,7 +2367,7 @@ static void clear_mesh_caches(Object *ob) static void mesh_build_data(Scene *scene, Object *ob, CustomDataMask dataMask) { Object *obact = scene->basact?scene->basact->object:NULL; - int editing = paint_facesel_test(ob); + int editing = paint_facesel_test(ob) || paint_vertsel_test(ob);/* paint_vertsel_test */ /* weight paint and face select need original indices because of selection buffer drawing */ int needMapping = (ob==obact) && (editing || (ob->mode & (OB_MODE_WEIGHT_PAINT|OB_MODE_VERTEX_PAINT))); diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c index b690c9b4a91..5d01db87422 100644 --- a/source/blender/blenkernel/intern/anim_sys.c +++ b/source/blender/blenkernel/intern/anim_sys.c @@ -1557,7 +1557,7 @@ static NlaEvalChannel *nlaevalchan_verify (PointerRNA *ptr, ListBase *channels, PropertyRNA *prop; PointerRNA new_ptr; char *path = NULL; - short free_path=0; + /* short free_path=0; */ /* sanity checks */ if (channels == NULL) @@ -1565,7 +1565,7 @@ static NlaEvalChannel *nlaevalchan_verify (PointerRNA *ptr, ListBase *channels, /* get RNA pointer+property info from F-Curve for more convenient handling */ /* get path, remapped as appropriate to work in its new environment */ - free_path= animsys_remap_path(strip->remap, fcu->rna_path, &path); + /* free_path= */ /* UNUSED */ animsys_remap_path(strip->remap, fcu->rna_path, &path); /* a valid property must be available, and it must be animateable */ if (RNA_path_resolve(ptr, path, &new_ptr, &prop) == 0) { diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index 08a95477c2e..1149d8eee25 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -2464,3 +2464,33 @@ void where_is_pose (Scene *scene, Object *ob) } } } + + +/* Returns total selected vgroups, + * wpi.defbase_sel is assumed malloc'd, all values are set */ +int get_selected_defgroups(Object *ob, char *dg_selection, int defbase_len) +{ + bDeformGroup *defgroup; + unsigned int i; + Object *armob= object_pose_armature_get(ob); + int dg_flags_sel_tot= 0; + + if(armob) { + bPose *pose= armob->pose; + for (i= 0, defgroup= ob->defbase.first; i < defbase_len && defgroup; defgroup = defgroup->next, i++) { + bPoseChannel *pchan= get_pose_channel(pose, defgroup->name); + if(pchan && (pchan->bone->flag & BONE_SELECTED)) { + dg_selection[i]= TRUE; + dg_flags_sel_tot++; + } + else { + dg_selection[i]= FALSE; + } + } + } + else { + memset(dg_selection, FALSE, sizeof(char) * defbase_len); + } + + return dg_flags_sel_tot; +} diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 2b6261b1c81..218b83fc52a 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -500,7 +500,7 @@ static int read_undosave(bContext *C, UndoElem *uel) void BKE_write_undo(bContext *C, const char *name) { uintptr_t maxmem, totmem, memused; - int nr, success; + int nr /*, success */ /* UNUSED */; UndoElem *uel; if( (U.uiflag & USER_GLOBALUNDO)==0) return; @@ -552,7 +552,7 @@ void BKE_write_undo(bContext *C, const char *name) BLI_snprintf(numstr, sizeof(numstr), "%d.blend", counter); BLI_make_file_string("/", filepath, btempdir, numstr); - success= BLO_write_file(CTX_data_main(C), filepath, fileflags, NULL, NULL); + /* success= */ /* UNUSED */ BLO_write_file(CTX_data_main(C), filepath, fileflags, NULL, NULL); BLI_strncpy(curundo->str, filepath, sizeof(curundo->str)); } @@ -562,7 +562,7 @@ void BKE_write_undo(bContext *C, const char *name) if(curundo->prev) prevfile= &(curundo->prev->memfile); memused= MEM_get_memory_in_use(); - success= BLO_write_file_mem(CTX_data_main(C), prevfile, &curundo->memfile, G.fileflags); + /* success= */ /* UNUSED */ BLO_write_file_mem(CTX_data_main(C), prevfile, &curundo->memfile, G.fileflags); curundo->undosize= MEM_get_memory_in_use() - memused; } diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 44359a142c9..e1939335268 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -1060,18 +1060,15 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, vo DMVertexAttribs attribs; MVert *mvert = cddm->mvert; MFace *mface = cddm->mface; - MTFace *tf = dm->getFaceDataArray(dm, CD_MTFACE); + /* MTFace *tf = dm->getFaceDataArray(dm, CD_MTFACE); */ /* UNUSED */ float (*nors)[3] = dm->getFaceDataArray(dm, CD_NORMAL); int a, b, dodraw, matnr, new_matnr; - int transp, new_transp, orig_transp; int orig, *index = dm->getFaceDataArray(dm, CD_ORIGINDEX); cdDM_update_normals_from_pbvh(dm); matnr = -1; dodraw = 0; - transp = GPU_get_material_blend_mode(); - orig_transp = transp; glShadeModel(GL_SMOOTH); @@ -1111,22 +1108,6 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, vo continue; } - if(tf) { - new_transp = tf[a].transp; - - if(new_transp != transp) { - glEnd(); - - if(new_transp == GPU_BLEND_SOLID && orig_transp != GPU_BLEND_SOLID) - GPU_set_material_blend_mode(orig_transp); - else - GPU_set_material_blend_mode(new_transp); - transp = new_transp; - - glBegin(GL_QUADS); - } - } - if(!smoothnormal) { if(nors) { glNormal3fv(nors[a]); @@ -1158,7 +1139,7 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, vo GPUBuffer *buffer = NULL; char *varray = NULL; int numdata = 0, elementsize = 0, offset; - int start = 0, numfaces = 0, prevdraw = 0, curface = 0; + int start = 0, numfaces = 0 /* , prevdraw = 0 */ /* UNUSED */, curface = 0; int i; MFace *mf = mface; @@ -1202,7 +1183,7 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, vo } numdata = 0; start = curface; - prevdraw = dodraw; + /* prevdraw = dodraw; */ /* UNUSED */ dodraw = setMaterial(matnr = new_matnr, &gattribs); if(dodraw) { DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs); @@ -1250,7 +1231,7 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, vo else { /* if the buffer was set, dont use it again. * prevdraw was assumed true but didnt run so set to false - [#21036] */ - prevdraw= 0; + /* prevdraw= 0; */ /* UNUSED */ buffer= NULL; } } @@ -1259,33 +1240,6 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, vo continue; } - if(tf) { - new_transp = tf[a].transp; - - if(new_transp != transp) { - numfaces = curface - start; - if( numfaces > 0 ) { - if( dodraw ) { - if( numdata != 0 ) { - GPU_buffer_unlock(buffer); - GPU_interleaved_attrib_setup(buffer,datatypes,numdata); - } - glDrawArrays(GL_TRIANGLES,start*3,(curface-start)*3); - if( numdata != 0 ) { - varray = GPU_buffer_lock_stream(buffer); - } - } - } - start = curface; - - if(new_transp == GPU_BLEND_SOLID && orig_transp != GPU_BLEND_SOLID) - GPU_set_material_blend_mode(orig_transp); - else - GPU_set_material_blend_mode(new_transp); - transp = new_transp; - } - } - if( numdata != 0 ) { offset = 0; if(attribs.totorco) { diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index 883f67c3061..30da2e01011 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -326,7 +326,7 @@ static void layerSwap_tface(void *data, const int *corner_indices) static void layerDefault_tface(void *data, int count) { static MTFace default_tf = {{{0, 0}, {1, 0}, {1, 1}, {0, 1}}, NULL, - 0, 0, TF_DYNAMIC, 0, 0}; + 0, 0, TF_DYNAMIC|TF_CONVERTED, 0, 0}; MTFace *tf = (MTFace*)data; int i; diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 002cfdbf41a..d764826cd47 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -2290,3 +2290,20 @@ void BKE_image_user_calc_frame(ImageUser *iuser, int cfra, int fieldnr) iuser->framenr= framenr; if(iuser->ok==0) iuser->ok= 1; } + +int BKE_image_has_alpha(struct Image *image) +{ + ImBuf *ibuf; + void *lock; + int depth; + + ibuf= BKE_image_acquire_ibuf(image, NULL, &lock); + depth = (ibuf?ibuf->depth:0); + BKE_image_release_ibuf(image, lock); + + if (depth == 32) + return 1; + else + return 0; +} + diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index 2a9e786d139..f5df6efd622 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -37,12 +37,16 @@ #include <string.h> #include <math.h> +#include <stddef.h> #include "MEM_guardedalloc.h" #include "DNA_curve_types.h" #include "DNA_material_types.h" #include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_customdata_types.h" +#include "DNA_ID.h" #include "DNA_meta_types.h" #include "DNA_node_types.h" #include "DNA_object_types.h" @@ -56,6 +60,7 @@ #include "BKE_displist.h" #include "BKE_global.h" #include "BKE_icons.h" +#include "BKE_image.h" #include "BKE_library.h" #include "BKE_main.h" #include "BKE_material.h" @@ -188,6 +193,10 @@ void init_material(Material *ma) ma->vol.ms_diff = 1.f; ma->vol.ms_intensity = 1.f; + ma->game.flag=0; + ma->game.alpha_blend=0; + ma->game.face_orientation=0; + ma->mode= MA_TRACEBLE|MA_SHADBUF|MA_SHADOW|MA_RAYBIAS|MA_TANGENT_STR|MA_ZTRANSP; ma->shade_flag= MA_APPROX_OCCLUSION; ma->preview = NULL; @@ -515,7 +524,7 @@ short *give_totcolp_id(ID *id) return NULL; } -static void data_delete_material_index_id(ID *id, int index) +static void data_delete_material_index_id(ID *id, short index) { switch(GS(id->name)) { case ID_ME: @@ -547,8 +556,9 @@ void material_append_id(ID *id, Material *ma) } } -Material *material_pop_id(ID *id, int index, int remove_material_slot) +Material *material_pop_id(ID *id, int index_i, int remove_material_slot) { + short index= (short)index_i; Material *ret= NULL; Material ***matar; if((matar= give_matarar_id(id))) { @@ -591,7 +601,7 @@ Material *material_pop_id(ID *id, int index, int remove_material_slot) return ret; } -Material *give_current_material(Object *ob, int act) +Material *give_current_material(Object *ob, short act) { Material ***matarar, *ma; short *totcolp; @@ -629,7 +639,7 @@ Material *give_current_material(Object *ob, int act) return ma; } -ID *material_from(Object *ob, int act) +ID *material_from(Object *ob, short act) { if(ob==NULL) return NULL; @@ -713,7 +723,7 @@ void test_object_materials(ID *id) } } -void assign_material(Object *ob, Material *ma, int act) +void assign_material(Object *ob, Material *ma, short act) { Material *mao, **matar, ***matarar; char *matbits; @@ -784,9 +794,10 @@ void assign_material(Object *ob, Material *ma, int act) } /* XXX - this calls many more update calls per object then are needed, could be optimized */ -void assign_matarar(struct Object *ob, struct Material ***matar, int totcol) +void assign_matarar(struct Object *ob, struct Material ***matar, short totcol) { - int i, actcol_orig= ob->actcol; + int actcol_orig= ob->actcol; + short i; while(object_remove_material_slot(ob)) {}; @@ -801,7 +812,7 @@ void assign_matarar(struct Object *ob, struct Material ***matar, int totcol) } -int find_material_index(Object *ob, Material *ma) +short find_material_index(Object *ob, Material *ma) { Material ***matarar; short a, *totcolp; @@ -1053,7 +1064,7 @@ int object_remove_material_slot(Object *ob) Material *mao, ***matarar; Object *obt; short *totcolp; - int a, actcol; + short a, actcol; if(ob==NULL || ob->totcol==0) return FALSE; @@ -1468,3 +1479,482 @@ void paste_matcopybuf(Material *ma) ma->nodetree= ntreeCopyTree(matcopybuf.nodetree); } + + +/*********************** texface to material convert functions **********************/ +/* encode all the TF information into a single int */ +static int encode_tfaceflag(MTFace *tf, int convertall) +{ + /* calculate the flag */ + int flag = tf->mode; + + /* options that change the material offline render */ + if (!convertall) { + flag &= ~TF_OBCOL; + } + + /* clean flags that are not being converted */ + flag &= ~TF_TEX; + flag &= ~TF_SHAREDVERT; + flag &= ~TF_SHAREDCOL; + flag &= ~TF_CONVERTED; + + /* light tface flag is ignored in GLSL mode */ + flag &= ~TF_LIGHT; + + /* 15 is how big the flag can be - hardcoded here and in decode_tfaceflag() */ + flag |= tf->transp << 15; + + /* increase 1 so flag 0 is different than no flag yet */ + return flag + 1; +} + +/* set the material options based in the tface flag */ +static void decode_tfaceflag(Material *ma, int flag, int convertall) +{ + int alphablend; + GameSettings *game= &ma->game; + + /* flag is shifted in 1 to make 0 != no flag yet (see encode_tfaceflag) */ + flag -= 1; + + alphablend = flag >> 15; //encoded in the encode_tfaceflag function + (*game).flag = 0; + + /* General Material Options */ + if ((flag & TF_DYNAMIC)==0) (*game).flag |= GEMAT_NOPHYSICS; + + /* Material Offline Rendering Properties */ + if (convertall) { + if (flag & TF_OBCOL) ma->shade_flag |= MA_OBCOLOR; + } + + /* Special Face Properties */ + if ((flag & TF_TWOSIDE)==0) (*game).flag |= GEMAT_BACKCULL; + if (flag & TF_INVISIBLE)(*game).flag |= GEMAT_INVISIBLE; + if (flag & TF_BMFONT) (*game).flag |= GEMAT_TEXT; + + /* Face Orientation */ + if (flag & TF_BILLBOARD) (*game).face_orientation |= GEMAT_HALO; + else if (flag & TF_BILLBOARD2) (*game).face_orientation |= GEMAT_BILLBOARD; + else if (flag & TF_SHADOW) (*game).face_orientation |= GEMAT_SHADOW; + + /* Alpha Blend */ + if (flag & TF_ALPHASORT && ELEM(alphablend, TF_ALPHA, TF_ADD)) (*game).alpha_blend = GEMAT_ALPHA_SORT; + else if (alphablend & TF_ALPHA) (*game).alpha_blend = GEMAT_ALPHA; + else if (alphablend & TF_ADD) (*game).alpha_blend = GEMAT_ADD; + else if (alphablend & TF_CLIP) (*game).alpha_blend = GEMAT_CLIP; +} + +/* boolean check to see if the mesh needs a material */ +static int check_tfaceneedmaterial(int flag) +{ + // check if the flags we have are not deprecated != than default material options + // also if only flags are visible and collision see if all objects using this mesh have this option in physics + + /* flag is shifted in 1 to make 0 != no flag yet (see encode_tfaceflag) */ + flag -=1; + + // deprecated flags + flag &= ~TF_OBCOL; + flag &= ~TF_SHAREDVERT; + flag &= ~TF_SHAREDCOL; + + /* light tface flag is ignored in GLSL mode */ + flag &= ~TF_LIGHT; + + // automatic detected if tex image has alpha + flag &= ~(TF_ALPHA << 15); + // automatic detected if using texture + flag &= ~TF_TEX; + + // settings for the default NoMaterial + if (flag == TF_DYNAMIC) + return 0; + + else + return 1; +} + +/* return number of digits of an integer */ +// XXX to be optmized or replaced by an equivalent blender internal function +static int integer_getdigits(int number) +{ + int i=0; + if (number == 0) return 1; + + while (number != 0){ + number = (int)(number/10); + i++; + } + return i; +} + +static void calculate_tface_materialname(char *matname, char *newname, int flag) +{ + // if flag has only light and collision and material matches those values + // you can do strcpy(name, mat_name); + // otherwise do: + int digits = integer_getdigits(flag); + /* clamp the old name, remove the MA prefix and add the .TF.flag suffix + e.g. matname = "MALoooooooooooooongName"; newname = "Loooooooooooooon.TF.2" */ + sprintf(newname, "%.*s.TF.%0*d", MAX_ID_NAME-(digits+5), matname, digits, flag); +} + +/* returns -1 if no match */ +static short mesh_getmaterialnumber(Mesh *me, Material *ma) +{ + short a; + + for (a=0; a<me->totcol; a++) { + if (me->mat[a] == ma) { + return a; + } + } + + return -1; +} + +/* append material */ +static short mesh_addmaterial(Mesh *me, Material *ma) +{ + material_append_id(&me->id, NULL); + me->mat[me->totcol-1]= ma; + + id_us_plus(&ma->id); + + return me->totcol-1; +} + +static void set_facetexture_flags(Material *ma, Image *image) +{ + if(image) { + ma->mode |= MA_FACETEXTURE; + /* we could check if the texture has alpha, but then more meshes sharing the same + * material may need it. Let's make it simple. */ + if(BKE_image_has_alpha(image)) + ma->mode |= MA_FACETEXTURE_ALPHA; + } +} + +/* returns material number */ +static short convert_tfacenomaterial(Main *main, Mesh *me, MTFace *tf, int flag) +{ + Material *ma; + char idname[MAX_ID_NAME]; + short mat_nr= -1; + + /* new material, the name uses the flag*/ + sprintf(idname, "MAMaterial.TF.%0*d", integer_getdigits(flag), flag); + + if ((ma= BLI_findstring(&main->mat, idname+2, offsetof(ID, name)+2))) { + mat_nr= mesh_getmaterialnumber(me, ma); + /* assign the material to the mesh */ + if(mat_nr == -1) mat_nr= mesh_addmaterial(me, ma); + + /* if needed set "Face Textures [Alpha]" Material options */ + set_facetexture_flags(ma, tf->tpage); + } + /* create a new material */ + else { + ma= add_material(idname+2); + + if(ma){ + printf("TexFace Convert: Material \"%s\" created.\n", idname+2); + mat_nr= mesh_addmaterial(me, ma); + + /* if needed set "Face Textures [Alpha]" Material options */ + set_facetexture_flags(ma, tf->tpage); + + decode_tfaceflag(ma, flag, 1); + // the final decoding will happen after, outside the main loop + // for now store the flag into the material and change light/tex/collision + // store the flag as a negative number + ma->game.flag = -flag; + id_us_min((ID *)ma); + } + else printf("Error: Unable to create Material \"%s\" for Mesh \"%s\".", idname+2, me->id.name+2); + } + + /* set as converted, no need to go bad to this face */ + tf->mode |= TF_CONVERTED; + return mat_nr; +} + +/* Function to fully convert materials */ +static void convert_tfacematerial(Main *main, Material *ma) +{ + Mesh *me; + Material *mat_new; + MFace *mf; + MTFace *tf; + int flag, index; + int a; + short mat_nr; + CustomDataLayer *cdl; + char idname[MAX_ID_NAME]; + + for(me=main->mesh.first; me; me=me->id.next){ + /* check if this mesh uses this material */ + for(a=0;a<me->totcol;a++) + if(me->mat[a] == ma) break; + + /* no material found */ + if (a == me->totcol) continue; + + /* get the active tface layer */ + index= CustomData_get_active_layer_index(&me->fdata, CD_MTFACE); + cdl= (index == -1)? NULL: &me->fdata.layers[index]; + if (!cdl) continue; + + /* loop over all the faces and stop at the ones that use the material*/ + for(a=0, mf=me->mface; a<me->totface; a++, mf++) { + if(me->mat[mf->mat_nr] != ma) continue; + + /* texface data for this face */ + tf = ((MTFace*)cdl->data) + a; + flag = encode_tfaceflag(tf, 1); + + /* the name of the new material */ + calculate_tface_materialname(ma->id.name, (char *)&idname, flag); + + if ((mat_new= BLI_findstring(&main->mat, idname+2, offsetof(ID, name)+2))) { + /* material already existent, see if the mesh has it */ + mat_nr = mesh_getmaterialnumber(me, mat_new); + /* material is not in the mesh, add it */ + if(mat_nr == -1) mat_nr= mesh_addmaterial(me, mat_new); + } + /* create a new material */ + else { + mat_new=copy_material(ma); + if(mat_new){ + /* rename the material*/ + strcpy(mat_new->id.name, idname); + id_us_min((ID *)mat_new); + + mat_nr= mesh_addmaterial(me, mat_new); + decode_tfaceflag(mat_new, flag, 1); + } + else { + printf("Error: Unable to create Material \"%s\" for Mesh \"%s.", idname+2, me->id.name+2); + mat_nr = mf->mat_nr; + continue; + } + } + + /* if the material has a texture but no texture channel + * set "Face Textures [Alpha]" Material options + * actually we need to run it always, because of old behavior + * of using face texture if any texture channel was present (multitex) */ + //if((!mat_new->mtex[0]) && (!mat_new->mtex[0]->tex)) + set_facetexture_flags(mat_new, tf->tpage); + + /* set the material number to the face*/ + mf->mat_nr = mat_nr; + } + /* remove material from mesh */ + for(a=0;a<me->totcol;) + if(me->mat[a] == ma) material_pop_id(&me->id, a, 1);else a++; + } +} + + +#define MAT_BGE_DISPUTED -99999 + +int do_version_tface(Main *main, int fileload) +{ + Mesh *me; + Material *ma; + MFace *mf; + MTFace *tf; + CustomDataLayer *cdl; + int a; + int flag; + int index; + + /* sometimes mesh has no materials but will need a new one. In those + * cases we need to ignore the mf->mat_nr and only look at the face + * mode because it can be zero as uninitialized or the 1st created material + */ + int nomaterialslots; + + /* alert to user to check the console */ + int nowarning = 1; + + /* mark all the materials to conversion with a flag + * if there is tface create a complete flag for that storing in flag + * if there is tface and flag > 0: creates a new flag based on this face + * if flags are different set flag to -1 + */ + + /* 1st part: marking mesh materials to update */ + for(me=main->mesh.first; me; me=me->id.next){ + if (me->id.lib) continue; + + /* get the active tface layer */ + index= CustomData_get_active_layer_index(&me->fdata, CD_MTFACE); + cdl= (index == -1)? NULL: &me->fdata.layers[index]; + if (!cdl) continue; + + nomaterialslots = (me->totcol==0?1:0); + + /* loop over all the faces*/ + for(a=0, mf=me->mface; a<me->totface; a++, mf++) { + /* texface data for this face */ + tf = ((MTFace*)cdl->data) + a; + + /* conversion should happen only once */ + if (fileload) + tf->mode &= ~TF_CONVERTED; + else { + if((tf->mode & TF_CONVERTED)) continue; + else tf->mode |= TF_CONVERTED; + } + + /* no material slots */ + if(nomaterialslots) { + flag = encode_tfaceflag(tf, 1); + + /* create/find a new material and assign to the face */ + if (check_tfaceneedmaterial(flag)) { + mf->mat_nr= convert_tfacenomaterial(main, me, tf, flag); + } + /* else mark them as no-material to be reverted to 0 later */ + else { + mf->mat_nr = -1; + } + } + else if(mf->mat_nr < me->totcol) { + ma= me->mat[mf->mat_nr]; + + /* no material create one if necessary */ + if(!ma) { + /* find a new material and assign to the face */ + flag = encode_tfaceflag(tf, 1); + + /* create/find a new material and assign to the face */ + if (check_tfaceneedmaterial(flag)) + mf->mat_nr= convert_tfacenomaterial(main, me, tf, flag); + + continue; + } + + /* we can't read from this if it comes from a library, + * at doversion time: direct_link might not have happened on it, + * so ma->mtex is not pointing to valid memory yet. + * later we could, but it's better not */ + else if(ma->id.lib) + continue; + + /* material already marked as disputed */ + else if(ma->game.flag == MAT_BGE_DISPUTED) + continue; + + /* found a material */ + else { + flag = encode_tfaceflag(tf, ((fileload)?0:1)); + + /* first time changing this material */ + if (ma->game.flag == 0) + ma->game.flag= -flag; + + /* mark material as disputed */ + else if (ma->game.flag != -flag) { + ma->game.flag = MAT_BGE_DISPUTED; + continue; + } + + /* material ok so far */ + else { + ma->game.flag = -flag; + + /* some people uses multitexture with TexFace by creating a texture + * channel which not neccessarly the tf->tpage image. But the game engine + * was enabling it. Now it's required to set "Face Texture [Alpha] in the + * material settings. */ + if(!fileload) + set_facetexture_flags(ma, tf->tpage); + } + } + } + else + continue; + } + + /* if we didn't have material slot and now we do, we need to + * make sure the materials are correct */ + if(nomaterialslots) { + if (me->totcol>0) { + for(a=0, mf=me->mface; a<me->totface; a++, mf++) { + if (mf->mat_nr == -1) { + /* texface data for this face */ + tf = ((MTFace*)cdl->data) + a; + mf->mat_nr= convert_tfacenomaterial(main, me, tf, encode_tfaceflag(tf, 1)); + } + } + } + else { + for(a=0, mf=me->mface; a<me->totface; a++, mf++) { + mf->mat_nr=0; + } + } + } + + } + + /* 2nd part - conversion */ + /* skip library files */ + + /* we shouldn't loop through the materials created in the loop. make the loop stop at its original length) */ + for (ma= main->mat.first, a=0; ma; ma= ma->id.next, a++) { + if (ma->id.lib) continue; + + /* disputed material */ + if (ma->game.flag == MAT_BGE_DISPUTED) { + ma->game.flag = 0; + if (fileload) { + printf("Warning: material \"%s\" skipped - to convert old game texface to material go to the Help menu.\n", ma->id.name+2); + nowarning = 0; + } + else + convert_tfacematerial(main, ma); + continue; + } + + /* no conflicts in this material - 90% of cases + * convert from tface system to material */ + else if (ma->game.flag < 0) { + decode_tfaceflag(ma, -(ma->game.flag), 1); + + /* material is good make sure all faces using + * this material are set to converted */ + if (fileload) { + for(me=main->mesh.first; me; me=me->id.next){ + /* check if this mesh uses this material */ + for(a=0;a<me->totcol;a++) + if(me->mat[a] == ma) break; + + /* no material found */ + if (a == me->totcol) continue; + + /* get the active tface layer */ + index= CustomData_get_active_layer_index(&me->fdata, CD_MTFACE); + cdl= (index == -1)? NULL: &me->fdata.layers[index]; + if (!cdl) continue; + + /* loop over all the faces and stop at the ones that use the material*/ + for (a=0, mf=me->mface; a<me->totface; a++, mf++) { + if (me->mat[mf->mat_nr] == ma) { + /* texface data for this face */ + tf = ((MTFace*)cdl->data) + a; + tf->mode |= TF_CONVERTED; + } + } + } + } + } + } + + return nowarning; +} + diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 32819226361..810e7c285e8 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -917,7 +917,7 @@ int nurbs_to_mdata_customdb(Object *ob, ListBase *dispbase, MVert **allvert, int mface->v2= startvert+index[2]; mface->v3= startvert+index[1]; mface->v4= 0; - mface->mat_nr= (unsigned char)dl->col; + mface->mat_nr= dl->col; test_index_face(mface, NULL, 0, 3); if(smooth) mface->flag |= ME_SMOOTH; @@ -966,7 +966,7 @@ int nurbs_to_mdata_customdb(Object *ob, ListBase *dispbase, MVert **allvert, int mface->v2= p3; mface->v3= p4; mface->v4= p2; - mface->mat_nr= (unsigned char)dl->col; + mface->mat_nr= dl->col; test_index_face(mface, NULL, 0, 4); if(smooth) mface->flag |= ME_SMOOTH; @@ -1252,7 +1252,7 @@ void mesh_to_curve(Scene *scene, Object *ob) } } -void mesh_delete_material_index(Mesh *me, int index) +void mesh_delete_material_index(Mesh *me, short index) { MFace *mf; int i; diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 89fd3ff9c13..524a63a8a95 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -295,12 +295,12 @@ int nodeFindNode(bNodeTree *ntree, bNodeSocket *sock, bNode **nodep, int *sockin static void node_add_sockets_from_type(bNodeTree *ntree, bNode *node, bNodeType *ntype) { bNodeSocketTemplate *sockdef; - bNodeSocket *sock; + /* bNodeSocket *sock; */ /* UNUSED */ if(ntype->inputs) { sockdef= ntype->inputs; while(sockdef->type != -1) { - sock = node_add_input_from_template(ntree, node, sockdef); + /* sock = */ node_add_input_from_template(ntree, node, sockdef); sockdef++; } @@ -308,7 +308,7 @@ static void node_add_sockets_from_type(bNodeTree *ntree, bNode *node, bNodeType if(ntype->outputs) { sockdef= ntype->outputs; while(sockdef->type != -1) { - sock = node_add_output_from_template(ntree, node, sockdef); + /* sock = */ node_add_output_from_template(ntree, node, sockdef); sockdef++; } @@ -620,7 +620,7 @@ bNodeTree *ntreeAddTree(const char *name, int type, int nodetype) bNodeTree *ntreeCopyTree(bNodeTree *ntree) { bNodeTree *newtree; - bNode *node, *nnode, *last; + bNode *node /*, *nnode */ /* UNUSED */, *last; bNodeLink *link; bNodeSocket *gsock, *oldgsock; @@ -647,7 +647,7 @@ bNodeTree *ntreeCopyTree(bNodeTree *ntree) last = ntree->nodes.last; for(node= ntree->nodes.first; node; node= node->next) { node->new_node= NULL; - nnode= nodeCopyNode(newtree, node); /* sets node->new */ + /* nnode= */ nodeCopyNode(newtree, node); /* sets node->new */ /* make sure we don't copy new nodes again! */ if (node==last) diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c index d00eb6192da..ddeb42d608e 100644 --- a/source/blender/blenkernel/intern/paint.c +++ b/source/blender/blenkernel/intern/paint.c @@ -97,6 +97,10 @@ int paint_facesel_test(Object *ob) return (ob && ob->type==OB_MESH && ob->data && (((Mesh *)ob->data)->editflag & ME_EDIT_PAINT_MASK) && (ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT))); } +int paint_vertsel_test(Object *ob) +{ + return (ob && ob->type==OB_MESH && ob->data && (((Mesh *)ob->data)->editflag & ME_EDIT_VERT_SEL) && (ob->mode & OB_MODE_WEIGHT_PAINT)); +} void paint_init(Paint *p, const char col[3]) { Brush *brush; diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c index d17b769888b..73d0d70778f 100644 --- a/source/blender/blenkernel/intern/sound.c +++ b/source/blender/blenkernel/intern/sound.c @@ -1,5 +1,5 @@ /* - * $Id: + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 2ff555b5b22..36263746228 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -968,8 +968,9 @@ static void ccgDM_copyFinalFaceArray(DerivedMesh *dm, MFace *mface) for(index = 0; index < totface; index++) { CCGFace *f = ccgdm->faceMap[index].face; int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f); - int flag = (faceFlags)? faceFlags[index*2]: ME_SMOOTH; - int mat_nr = (faceFlags)? faceFlags[index*2+1]: 0; + /* keep types in sync with MFace, avoid many conversions */ + char flag = (faceFlags)? faceFlags[index*2]: ME_SMOOTH; + short mat_nr = (faceFlags)? faceFlags[index*2+1]: 0; for(S = 0; S < numVerts; S++) { for(y = 0; y < gridSize - 1; y++) { @@ -1374,11 +1375,10 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, v CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss); GPUVertexAttribs gattribs; DMVertexAttribs attribs= {{{NULL}}}; - MTFace *tf = dm->getFaceDataArray(dm, CD_MTFACE); + /* MTFace *tf = dm->getFaceDataArray(dm, CD_MTFACE); */ /* UNUSED */ int gridSize = ccgSubSurf_getGridSize(ss); int gridFaces = gridSize - 1; int edgeSize = ccgSubSurf_getEdgeSize(ss); - int transp, orig_transp, new_transp; char *faceFlags = ccgdm->faceFlags; int a, b, i, doDraw, numVerts, matnr, new_matnr, totface; @@ -1386,8 +1386,6 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, v doDraw = 0; matnr = -1; - transp = GPU_get_material_blend_mode(); - orig_transp = transp; #define PASSATTRIB(dx, dy, vert) { \ if(attribs.totorco) { \ @@ -1439,18 +1437,6 @@ static void ccgDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, v continue; } - if(tf) { - new_transp = tf[i].transp; - - if(new_transp != transp) { - if(new_transp == GPU_BLEND_SOLID && orig_transp != GPU_BLEND_SOLID) - GPU_set_material_blend_mode(orig_transp); - else - GPU_set_material_blend_mode(new_transp); - transp = new_transp; - } - } - glShadeModel(drawSmooth? GL_SMOOTH: GL_FLAT); for (S=0; S<numVerts; S++) { DMGridData *faceGridData = ccgSubSurf_getFaceGridDataArray(ss, f, S); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 38454547f48..497ac415ebb 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -238,6 +238,7 @@ typedef struct OldNewMap { /* local prototypes */ static void *read_struct(FileData *fd, BHead *bh, const char *blockname); static void direct_link_modifiers(FileData *fd, ListBase *lb); +static void convert_tface_mt(FileData *fd, Main *main); static OldNewMap *oldnewmap_new(void) { @@ -3478,6 +3479,9 @@ static void lib_link_mesh(FileData *fd, Main *main) } me= me->id.next; } + + /* convert texface options to material */ + convert_tface_mt(fd, main); } static void direct_link_dverts(FileData *fd, int count, MDeformVert *mdverts) @@ -6358,7 +6362,7 @@ static void alphasort_version_246(FileData *fd, Library *lib, Mesh *me) /* if we do, set alpha sort if the game engine did it before */ for(a=0, mf=me->mface; a<me->totface; a++, mf++) { if(mf->mat_nr < me->totcol) { - ma= newlibadr(fd, lib, me->mat[(int)mf->mat_nr]); + ma= newlibadr(fd, lib, me->mat[mf->mat_nr]); texalpha = 0; /* we can't read from this if it comes from a library, @@ -7038,6 +7042,27 @@ static void do_versions_nodetree_dynamic_sockets(bNodeTree *ntree) sock->flag |= SOCK_DYNAMIC; } +void convert_tface_mt(FileData *fd, Main *main) +{ + Main *gmain; + + /* this is a delayed do_version (so it can create new materials) */ + if (main->versionfile < 259 || (main->versionfile == 259 && main->subversionfile < 3)) { + + //XXX hack, material.c uses G.main all over the place, instead of main + // temporarily set G.main to the current main + gmain = G.main; + G.main = main; + + if(!(do_version_tface(main, 1))) { + BKE_report(fd->reports, RPT_ERROR, "Texface conversion problem. Error in console"); + } + + //XXX hack, material.c uses G.main allover the place, instead of main + G.main = gmain; + } +} + static void do_versions(FileData *fd, Library *lib, Main *main) { /* WATCH IT!!!: pointers from libdata have not been converted */ diff --git a/source/blender/collada/GeometryExporter.cpp b/source/blender/collada/GeometryExporter.cpp index 4da0a4c6e1f..4892955fd3c 100644 --- a/source/blender/collada/GeometryExporter.cpp +++ b/source/blender/collada/GeometryExporter.cpp @@ -129,7 +129,7 @@ void GeometryExporter::operator()(Object *ob) } // powerful because it handles both cases when there is material and when there's not -void GeometryExporter::createPolylist(int material_index, +void GeometryExporter::createPolylist(short material_index, bool has_uvs, bool has_color, Object *ob, diff --git a/source/blender/collada/GeometryExporter.h b/source/blender/collada/GeometryExporter.h index 64c51b6324e..532a439eba7 100644 --- a/source/blender/collada/GeometryExporter.h +++ b/source/blender/collada/GeometryExporter.h @@ -67,7 +67,7 @@ public: void operator()(Object *ob); // powerful because it handles both cases when there is material and when there's not - void createPolylist(int material_index, + void createPolylist(short material_index, bool has_uvs, bool has_color, Object *ob, diff --git a/source/blender/collada/MeshImporter.cpp b/source/blender/collada/MeshImporter.cpp index 15bd9c48f12..2f5d9e54e50 100644 --- a/source/blender/collada/MeshImporter.cpp +++ b/source/blender/collada/MeshImporter.cpp @@ -778,7 +778,7 @@ MTFace *MeshImporter::assign_material_to_geom(COLLADAFW::MaterialBinding cmateri std::map<COLLADAFW::UniqueId, Material*>& uid_material_map, Object *ob, const COLLADAFW::UniqueId *geom_uid, MTex **color_texture, char *layername, MTFace *texture_face, - std::map<Material*, TexIndexTextureArrayMap>& material_texture_mapping_map, int mat_index) + std::map<Material*, TexIndexTextureArrayMap>& material_texture_mapping_map, short mat_index) { Mesh *me = (Mesh*)ob->data; const COLLADAFW::UniqueId& ma_uid = cmaterial.getReferencedMaterial(); diff --git a/source/blender/collada/MeshImporter.h b/source/blender/collada/MeshImporter.h index 88ee0e46c33..208ba4d65c0 100644 --- a/source/blender/collada/MeshImporter.h +++ b/source/blender/collada/MeshImporter.h @@ -141,7 +141,7 @@ public: std::map<COLLADAFW::UniqueId, Material*>& uid_material_map, Object *ob, const COLLADAFW::UniqueId *geom_uid, MTex **color_texture, char *layername, MTFace *texture_face, - std::map<Material*, TexIndexTextureArrayMap>& material_texture_mapping_map, int mat_index); + std::map<Material*, TexIndexTextureArrayMap>& material_texture_mapping_map, short mat_index); Object *create_mesh_object(COLLADAFW::Node *node, COLLADAFW::InstanceGeometry *geom, diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index 53e0fd92eeb..566ff09c366 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -4290,10 +4290,15 @@ int ED_do_pose_selectbuffer(Scene *scene, Base *base, unsigned int *buffer, shor /* if the bone cannot be affected, don't do anything */ if ((nearBone) && !(nearBone->flag & BONE_UNSELECTABLE)) { + Object *ob_act= OBACT; bArmature *arm= ob->data; - /* since we do unified select, we don't shift+select a bone if the armature object was not active yet */ - if (!(extend) || (base != scene->basact)) { + /* since we do unified select, we don't shift+select a bone if the + * armature object was not active yet. + * note, special exception for armature mode so we can do multi-select + * we could check for multi-select explicitly but think its fine to + * always give pradictable behavior in weight paint mode - campbell */ + if (!(extend) || ((ob_act && ob_act->mode & OB_MODE_WEIGHT_PAINT) == 0)) { ED_pose_deselectall(ob, 0); nearBone->flag |= (BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL); arm->act_bone= nearBone; @@ -4324,7 +4329,7 @@ int ED_do_pose_selectbuffer(Scene *scene, Base *base, unsigned int *buffer, shor } /* in weightpaint we select the associated vertex group too */ - if (OBACT && OBACT->mode & OB_MODE_WEIGHT_PAINT) { + if (ob_act && ob_act->mode & OB_MODE_WEIGHT_PAINT) { if (nearBone == arm->act_bone) { ED_vgroup_select_by_name(OBACT, nearBone->name); DAG_id_tag_update(&OBACT->id, OB_RECALC_DATA); @@ -5061,6 +5066,10 @@ void POSE_OT_select_inverse(wmOperatorType *ot) static int pose_de_select_all_exec(bContext *C, wmOperator *op) { int action = RNA_enum_get(op->ptr, "action"); + + Object *ob = NULL; + Scene *scene= CTX_data_scene(C); + int multipaint = scene->toolsettings->multipaint; if (action == SEL_TOGGLE) { action= CTX_DATA_COUNT(C, selected_pose_bones) ? SEL_DESELECT : SEL_SELECT; @@ -5091,6 +5100,11 @@ static int pose_de_select_all_exec(bContext *C, wmOperator *op) WM_event_add_notifier(C, NC_OBJECT|ND_BONE_SELECT, NULL); + if(multipaint) { + ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + } + return OPERATOR_FINISHED; } diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c index 806e288798f..6c721660e9c 100644 --- a/source/blender/editors/armature/meshlaplacian.c +++ b/source/blender/editors/armature/meshlaplacian.c @@ -657,22 +657,41 @@ void heat_bone_weighting(Object *ob, Mesh *me, float (*verts)[3], int numsource, int *vertsflipped = NULL, *mask= NULL; int a, totface, j, bbone, firstsegment, lastsegment; + MVert *mvert = me->mvert; + int use_vert_sel= FALSE; + int use_face_sel= FALSE; + *err_str= NULL; /* count triangles and create mask */ - if(me->editflag & ME_EDIT_PAINT_MASK) + if( (use_face_sel= (me->editflag & ME_EDIT_PAINT_MASK) != 0) || + (use_vert_sel= ((me->editflag & ME_EDIT_VERT_SEL) != 0))) + { mask= MEM_callocN(sizeof(int)*me->totvert, "heat_bone_weighting mask"); + } for(totface=0, a=0, mface=me->mface; a<me->totface; a++, mface++) { totface++; if(mface->v4) totface++; - if(mask && (mface->flag & ME_FACE_SEL)) { - mask[mface->v1]= 1; - mask[mface->v2]= 1; - mask[mface->v3]= 1; - if(mface->v4) - mask[mface->v4]= 1; + /* (added selectedVerts content for vertex mask, they used to just equal 1) */ + if(use_vert_sel) { + mask[mface->v1]= (mvert[mface->v1].flag & SELECT) != 0; + mask[mface->v2]= (mvert[mface->v2].flag & SELECT) != 0; + mask[mface->v3]= (mvert[mface->v3].flag & SELECT) != 0; + if(mface->v4) { + mask[mface->v4]= (mvert[mface->v4].flag & SELECT) != 0; + } + } + else { + if(use_face_sel) { + mask[mface->v1]= 1; + mask[mface->v2]= 1; + mask[mface->v3]= 1; + if(mface->v4) { + mask[mface->v4]= 1; + } + } } } diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index 8bb77ad43a0..9709979ff6a 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -123,6 +123,8 @@ int EM_vertColorCheck(struct EditMesh *em); void undo_push_mesh(struct bContext *C, const char *name); +void paintvert_flush_flags(struct Object *ob); +void paintvert_deselect_all_visible(struct Object *ob, int action, short flush_flags); /* editmesh_lib.c */ diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index f8682d3935b..d574ddd3030 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -53,6 +53,7 @@ struct Scene; struct View3D; struct ViewContext; struct wmWindow; +struct MVert; /* for derivedmesh drawing callbacks, for view3d_select, .... */ diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index 095c90797f1..af515bf8061 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -2138,6 +2138,18 @@ static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, Pointe //uiItemR(row, itemptr, "mute", 0, "", ICON_MUTE_IPO_OFF); uiBlockSetEmboss(block, UI_EMBOSS); } + else if(itemptr->type == &RNA_VertexGroup) { + bDeformGroup *dg= (bDeformGroup *)itemptr->data; + uiItemL(sub, name, icon); + /* RNA does not allow nice lock icons, use lower level buttons */ +#if 0 + uiDefButR(block, OPTION, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y, itemptr, "lock_weight", 0, 0, 0, 0, 0, NULL); +#else + uiBlockSetEmboss(block, UI_EMBOSSN); + uiDefIconButBitC(block, TOG, DG_LOCK_WEIGHT, 0, (dg->flag & DG_LOCK_WEIGHT) ? ICON_LOCKED : ICON_UNLOCKED, 0, 0, UI_UNIT_X, UI_UNIT_Y, &dg->flag, 0, 0, 0, 0, "Maintain relative weights while painting"); + uiBlockSetEmboss(block, UI_EMBOSS); +#endif + } else if(itemptr->type == &RNA_KeyingSetPath) { KS_Path *ksp = (KS_Path*)itemptr->data; diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c index 3f5bc21814d..18db1c8c894 100644 --- a/source/blender/editors/interface/view2d.c +++ b/source/blender/editors/interface/view2d.c @@ -420,8 +420,8 @@ void UI_view2d_curRect_validate_resize(View2D *v2d, int resize) /* check if we should restore aspect ratio (if view size changed) */ if (v2d->keepzoom & V2D_KEEPASPECT) { - short do_x=0, do_y=0, do_cur, do_win; - float curRatio, winRatio; + short do_x=0, do_y=0, do_cur /* , do_win */ /* UNUSED */; + float /* curRatio, */ /* UNUSED */ winRatio; /* when a window edge changes, the aspect ratio can't be used to * find which is the best new 'cur' rect. thats why it stores 'old' @@ -429,7 +429,7 @@ void UI_view2d_curRect_validate_resize(View2D *v2d, int resize) if (winx != v2d->oldwinx) do_x= 1; if (winy != v2d->oldwiny) do_y= 1; - curRatio= height / width; + /* curRatio= height / width; */ /* UNUSED */ winRatio= winy / winx; /* both sizes change (area/region maximised) */ @@ -443,7 +443,7 @@ void UI_view2d_curRect_validate_resize(View2D *v2d, int resize) else do_x= 1; } do_cur= do_x; - do_win= do_y; + /* do_win= do_y; */ /* UNUSED */ if (do_cur) { if ((v2d->keeptot == V2D_KEEPTOT_STRICT) && (winx != v2d->oldwinx)) { diff --git a/source/blender/editors/mesh/editmesh.c b/source/blender/editors/mesh/editmesh.c index c56a4238239..6a263fca915 100644 --- a/source/blender/editors/mesh/editmesh.c +++ b/source/blender/editors/mesh/editmesh.c @@ -1958,3 +1958,101 @@ void em_setup_viewcontext(bContext *C, ViewContext *vc) vc->em= me->edit_mesh; } } + + +/* (similar to void paintface_flush_flags(Object *ob)) + * copy the vertex flags, most importantly selection from the mesh to the final derived mesh, + * use in object mode when selecting vertices (while painting) */ +void paintvert_flush_flags(Object *ob) +{ + Mesh *me= get_mesh(ob); + DerivedMesh *dm= ob->derivedFinal; + MVert *dm_mvert, *dm_mv; + int *index_array = NULL; + int totvert; + int i; + + if(me==NULL || dm==NULL) + return; + + index_array = dm->getVertDataArray(dm, CD_ORIGINDEX); + + dm_mvert = dm->getVertArray(dm); + totvert = dm->getNumVerts(dm); + + dm_mv= dm_mvert; + + if(index_array) { + int orig_index; + for (i= 0; i<totvert; i++, dm_mv++) { + orig_index= index_array[i]; + if(orig_index != ORIGINDEX_NONE) { + dm_mv->flag= me->mvert[index_array[i]].flag; + } + } + } + else { + for (i= 0; i<totvert; i++, dm_mv++) { + dm_mv->flag= me->mvert[i].flag; + } + } +} +/* note: if the caller passes FALSE to flush_flags, then they will need to run paintvert_flush_flags(ob) themselves */ +void paintvert_deselect_all_visible(Object *ob, int action, short flush_flags) +{ + Mesh *me; + MVert *mvert; + int a; + + me= get_mesh(ob); + if(me==NULL) return; + + if(action == SEL_INVERT) { + mvert= me->mvert; + a= me->totvert; + while(a--) { + if((mvert->flag & ME_HIDE) == 0) { + mvert->flag ^= SELECT; + } + mvert++; + } + } + else { + if (action == SEL_TOGGLE) { + action = SEL_SELECT; + + mvert= me->mvert; + a= me->totvert; + while(a--) { + if((mvert->flag & ME_HIDE) == 0 && mvert->flag & SELECT) { + action = SEL_DESELECT; + break; + } + mvert++; + } + } + + mvert= me->mvert; + a= me->totvert; + while(a--) { + if((mvert->flag & ME_HIDE) == 0) { + switch (action) { + case SEL_SELECT: + mvert->flag |= SELECT; + break; + case SEL_DESELECT: + mvert->flag &= ~SELECT; + break; + case SEL_INVERT: + mvert->flag ^= SELECT; + break; + } + } + mvert++; + } + } + + if(flush_flags) { + paintvert_flush_flags(ob); + } +} diff --git a/source/blender/editors/mesh/editmesh_mods.c b/source/blender/editors/mesh/editmesh_mods.c index 9783f25466e..8c035ca46fd 100644 --- a/source/blender/editors/mesh/editmesh_mods.c +++ b/source/blender/editors/mesh/editmesh_mods.c @@ -266,6 +266,7 @@ int EM_mask_init_backbuf_border(ViewContext *vc, int mcords[][2], short tot, sho /* method in use for face selecting too */ if(vc->obedit==NULL) { if(paint_facesel_test(vc->obact)); + else if(paint_vertsel_test(vc->obact)); else return 0; } else if(vc->v3d->drawtype<OB_SOLID || (vc->v3d->flag & V3D_ZBUF_SELECT)==0) return 0; @@ -328,6 +329,7 @@ int EM_init_backbuf_circle(ViewContext *vc, short xs, short ys, short rads) /* method in use for face selecting too */ if(vc->obedit==NULL) { if(paint_facesel_test(vc->obact)); + else if (paint_vertsel_test(vc->obact)); else return 0; } else if(vc->v3d->drawtype<OB_SOLID || (vc->v3d->flag & V3D_ZBUF_SELECT)==0) return 0; @@ -1471,10 +1473,8 @@ static void EM_mesh_copy_face(EditMesh *em, wmOperator *op, short type) tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); if (tf_act->tpage) { tf->tpage = tf_act->tpage; - tf->mode |= TF_TEX; } else { tf->tpage = NULL; - tf->mode &= ~TF_TEX; } tf->tile= tf_act->tile; change = 1; @@ -1654,10 +1654,8 @@ void EM_mesh_copy_face_layer(EditMesh *em, wmOperator *op, short type) tf = CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); if (tf_from->tpage) { tf->tpage = tf_from->tpage; - tf->mode |= TF_TEX; } else { tf->tpage = NULL; - tf->mode &= ~TF_TEX; } tf->tile= tf_from->tile; change = 1; diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c index 5411f01bee4..ef52d9be0c3 100644 --- a/source/blender/editors/mesh/mesh_data.c +++ b/source/blender/editors/mesh/mesh_data.c @@ -238,7 +238,6 @@ int ED_mesh_uv_texture_remove(bContext *C, Object *ob, Mesh *me) int ED_mesh_color_add(bContext *C, Scene *UNUSED(scene), Object *UNUSED(ob), Mesh *me, const char *name, int active_set) { EditMesh *em; - MCol *mcol; int layernum; if(me->edit_mesh) { @@ -261,8 +260,6 @@ int ED_mesh_color_add(bContext *C, Scene *UNUSED(scene), Object *UNUSED(ob), Mes if(layernum >= MAX_MCOL) return 0; - mcol= me->mcol; - if(me->mcol) CustomData_add_layer_named(&me->fdata, CD_MCOL, CD_DUPLICATE, me->mcol, me->totface, name); else diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index 32e52916b77..526bf177ab7 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -217,7 +217,7 @@ int join_mesh_exec(bContext *C, wmOperator *op) if(me->totvert) { /* Add this object's materials to the base one's if they don't exist already (but only if limits not exceeded yet) */ - if(totcol < MAXMAT-1) { + if(totcol < MAXMAT) { for(a=1; a<=base->object->totcol; a++) { ma= give_current_material(base->object, a); @@ -231,7 +231,7 @@ int join_mesh_exec(bContext *C, wmOperator *op) } totcol++; } - if(totcol>=MAXMAT-1) + if(totcol >= MAXMAT) break; } } diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index 3da0723ec18..434111c1227 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -200,6 +200,8 @@ void OBJECT_OT_vertex_group_copy(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_normalize(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_normalize_all(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_levels(struct wmOperatorType *ot); +void OBJECT_OT_vertex_group_lock(struct wmOperatorType *ot); +void OBJECT_OT_vertex_group_fix(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_invert(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_blend(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_clean(struct wmOperatorType *ot); diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index 57efc8c7dc9..452d1aded51 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -174,6 +174,8 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_vertex_group_copy); WM_operatortype_append(OBJECT_OT_vertex_group_normalize); WM_operatortype_append(OBJECT_OT_vertex_group_normalize_all); + WM_operatortype_append(OBJECT_OT_vertex_group_lock); + WM_operatortype_append(OBJECT_OT_vertex_group_fix); WM_operatortype_append(OBJECT_OT_vertex_group_invert); WM_operatortype_append(OBJECT_OT_vertex_group_levels); WM_operatortype_append(OBJECT_OT_vertex_group_blend); diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 592205d2a31..797cf428969 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -49,6 +49,7 @@ #include "DNA_scene_types.h" #include "DNA_particle_types.h" +#include "BLI_math.h" #include "BLI_blenlib.h" #include "BLI_editVert.h" #include "BLI_utildefines.h" @@ -60,6 +61,7 @@ #include "BKE_global.h" #include "BKE_mesh.h" #include "BKE_report.h" +#include "BKE_DerivedMesh.h" #include "RNA_access.h" #include "RNA_define.h" @@ -701,6 +703,10 @@ static void vgroup_normalize(Object *ob) MDeformWeight *dw; MDeformVert *dvert, **dvert_array=NULL; int i, def_nr, dvert_tot=0; + + Mesh *me = ob->data; + MVert *mvert = me->mvert; + const int use_vert_sel= (me->editflag & ME_EDIT_VERT_SEL) != 0; ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot); @@ -712,6 +718,11 @@ static void vgroup_normalize(Object *ob) def_nr= ob->actdef-1; for(i = 0; i < dvert_tot; i++) { + + if(use_vert_sel && !(mvert[i].flag & SELECT)) { + continue; + } + dvert = dvert_array[i]; dw = defvert_find_index(dvert, def_nr); if(dw) { @@ -721,6 +732,11 @@ static void vgroup_normalize(Object *ob) if(weight_max > 0.0f) { for(i = 0; i < dvert_tot; i++) { + + if(use_vert_sel && !(mvert[i].flag & SELECT)) { + continue; + } + dvert = dvert_array[i]; dw = defvert_find_index(dvert, def_nr); if(dw) { @@ -736,6 +752,401 @@ static void vgroup_normalize(Object *ob) if (dvert_array) MEM_freeN(dvert_array); } +/* This adds the indices of vertices to a list if they are not already present +It returns the number that it added (0-2) +It relies on verts having -1 for unassigned indices +*/ +static int tryToAddVerts(int *verts, int length, int a, int b) { + char containsA = FALSE; + char containsB = FALSE; + int added = 0; + int i; + for(i = 0; i < length && (!containsA || !containsB); i++) { + if(verts[i] == a) { + containsA = TRUE; + } else if(verts[i] == b) { + containsB = TRUE; + } else if(verts[i] == -1) { + if(!containsA) { + verts[i] = a; + containsA = TRUE; + added++; + } else if(!containsB){ + verts[i] = b; + containsB = TRUE; + added++; + } + } + } + return added; +} + +/* This finds all of the vertices connected to vert by an edge +and returns an array of indices of size count + +count is an int passed by reference so it can be assigned the value of the length here. +*/ +static int* getSurroundingVerts(Mesh *me, int vert, int *count) { + int length = 0; + int *tverts; + int *verts = NULL; + MFace *mf = me->mface; + int totface = me->totface; + int found = 0; + int i; + for(i = 0; i < totface; i++, mf++) { + if(vert == mf->v1 || vert == mf->v2 || vert == mf->v3 || (mf->v4 &&vert == mf->v4)) { + length+=2; + } + } + if(!length) { + return 0; + } + tverts = MEM_mallocN(sizeof(int)*length, "tempSurroundingVerts"); + mf = me->mface; + for(i = 0; i < length; i++) { + tverts[i] = -1; + } + for(i = 0; i < totface; i++, mf++) { + int a=-1, b=-1; + if(mf->v1 == vert) { + a = mf->v2; + if(mf->v4) { + b = mf->v4; + } else { + b = mf->v3; + } + } else if(mf->v2 == vert) { + a = mf->v1; + b = mf->v3; + } else if(mf->v3 == vert) { + a = mf->v2; + if(mf->v4) { + b = mf->v4; + } else { + b = mf->v1; + } + } else if (mf->v4 && mf->v4 == vert){ + a = mf->v1; + b = mf->v3; + } else { + continue; + } + found += tryToAddVerts(tverts, length, a, b); + } + if(found) { + verts = MEM_mallocN(sizeof(int)* found, "surroundingVerts"); + for(i = 0; i < found; i++) { + verts[i] = tverts[i]; + } + *count = found; + } + MEM_freeN(tverts); + return verts; +} + +/* get a single point in space by averaging a point cloud (vectors of size 3) +coord is the place the average is stored, points is the point cloud, count is the number of points in the cloud +*/ +static void getSingleCoordinate(MVert *points, int count, float coord[3]) { + int i; + zero_v3(coord); + for(i = 0; i < count; i++) { + add_v3_v3(coord, points[i].co); + } + mul_v3_fl(coord, 1.0f/count); +} + +/* find the closest point on a plane to another point and store it in dst */ +/* coord is a point on the plane */ +/* point is the point that you want the nearest of */ +/* norm is the plane's normal, and d is the last number in the plane equation 0 = ax + by + cz + d */ +static void getNearestPointOnPlane(const float norm[3], const float coord[3], const float point[3], float dst_r[3]) +{ + float temp[3]; + float dotprod; + + sub_v3_v3v3(temp, point, coord); + dotprod= dot_v3v3(temp, norm); + + dst_r[0] = point[0] - (norm[0] * dotprod); + dst_r[1] = point[1] - (norm[1] * dotprod); + dst_r[2] = point[2] - (norm[2] * dotprod); +} + +/* distance of two vectors a and b of size length */ +static float distance(float* a, float *b, int length) { + int i; + float sum = 0; + for(i = 0; i < length; i++) { + sum += (b[i]-a[i])*(b[i]-a[i]); + } + return sqrt(sum); +} + +/* given a plane and a start and end position, +compute the amount of vertical distance relative to the plane and store it in dists, +then get the horizontal and vertical change and store them in changes +*/ +static void getVerticalAndHorizontalChange(float *norm, float d, float *coord, float *start, float distToStart, float *end, float (*changes)[2], float *dists, int index) { + // A=Q-((Q-P).N)N + // D = (a*x0 + b*y0 +c*z0 +d) + float projA[3] = {0}, projB[3] = {0}; + + getNearestPointOnPlane(norm, coord, start, projA); + getNearestPointOnPlane(norm, coord, end, projB); + // (vertical and horizontal refer to the plane's y and xz respectively) + // vertical distance + dists[index] = norm[0]*end[0] + norm[1]*end[1] + norm[2]*end[2] + d; + // vertical change + changes[index][0] = dists[index] - distToStart; + //printf("vc %f %f\n", distance(end, projB, 3)-distance(start, projA, 3), changes[index][0]); + // horizontal change + changes[index][1] = distance(projA, projB, 3); +} + +// I need the derived mesh to be forgotten so the positions are recalculated with weight changes (see dm_deform_recalc) +static void dm_deform_clear(DerivedMesh *dm, Object *ob) { + if(ob->derivedDeform && (ob->derivedDeform)==dm) { + ob->derivedDeform->needsFree = 1; + ob->derivedDeform->release(ob->derivedDeform); + ob->derivedDeform = NULL; + } + else if(dm) { + dm->needsFree = 1; + dm->release(dm); + } +} + +// recalculate the deformation +static DerivedMesh* dm_deform_recalc(Scene *scene, Object *ob) { + return mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH); +} + +/* by changing nonzero weights, try to move a vertex in me->mverts with index 'index' to distToBe distance away from the provided plane +strength can change distToBe so that it moves towards distToBe by that percentage +cp changes how much the weights are adjusted to check the distance + +index is the index of the vertex being moved +norm and d are the plane's properties for the equation: ax + by + cz + d = 0 +coord is a point on the plane +*/ +static void moveCloserToDistanceFromPlane(Scene *scene, Object *ob, Mesh *me, int index, float norm[3], float coord[3], float d, float distToBe, float strength, float cp) { + DerivedMesh *dm; + MDeformWeight *dw; + MVert m; + MDeformVert *dvert = me->dvert+index; + int totweight = dvert->totweight; + float oldw = 0; + float oldPos[3] = {0}; + float vc, hc, dist; + int i, k; + float (*changes)[2] = MEM_mallocN(sizeof(float *)*totweight*2, "vertHorzChange"); + float *dists = MEM_mallocN(sizeof(float)*totweight, "distance"); + int *upDown = MEM_callocN(sizeof(int)*totweight, "upDownTracker");// track if up or down moved it closer for each bone + int *dwIndices = MEM_callocN(sizeof(int)*totweight, "dwIndexTracker"); + float distToStart; + int bestIndex = 0; + char wasChange; + char wasUp; + int lastIndex = -1; + float originalDistToBe = distToBe; + do { + wasChange = FALSE; + dm = dm_deform_recalc(scene, ob); + dm->getVert(dm, index, &m); + oldPos[0] = m.co[0]; + oldPos[1] = m.co[1]; + oldPos[2] = m.co[2]; + distToStart = norm[0]*oldPos[0] + norm[1]*oldPos[1] + norm[2]*oldPos[2] + d; + + if(distToBe == originalDistToBe) { + distToBe += distToStart - distToStart*strength; + } + for(i = 0; i < totweight; i++) { + dwIndices[i] = i; + dw = (dvert->dw+i); + vc = hc = 0; + if(!dw->weight) { + changes[i][0] = 0; + changes[i][1] = 0; + dists[i] = distToStart; + continue; + } + for(k = 0; k < 2; k++) { + if(dm) { + dm_deform_clear(dm, ob); dm = NULL; + } + oldw = dw->weight; + if(k) { + dw->weight *= 1+cp; + } else { + dw->weight /= 1+cp; + } + if(dw->weight == oldw) { + changes[i][0] = 0; + changes[i][1] = 0; + dists[i] = distToStart; + break; + } + if(dw->weight > 1) { + dw->weight = 1; + } + dm = dm_deform_recalc(scene, ob); + dm->getVert(dm, index, &m); + getVerticalAndHorizontalChange(norm, d, coord, oldPos, distToStart, m.co, changes, dists, i); + dw->weight = oldw; + if(!k) { + vc = changes[i][0]; + hc = changes[i][1]; + dist = dists[i]; + } else { + if(fabs(dist - distToBe) < fabs(dists[i] - distToBe)) { + upDown[i] = 0; + changes[i][0] = vc; + changes[i][1] = hc; + dists[i] = dist; + } else { + upDown[i] = 1; + } + if(fabs(dists[i] - distToBe) > fabs(distToStart - distToBe)) { + changes[i][0] = 0; + changes[i][1] = 0; + dists[i] = distToStart; + } + } + } + } + // sort the changes by the vertical change + for(k = 0; k < totweight; k++) { + float tf; + int ti; + bestIndex = k; + for(i = k+1; i < totweight; i++) { + dist = dists[i]; + + if(fabs(dist) > fabs(dists[i])) { + bestIndex = i; + } + } + // switch with k + if(bestIndex != k) { + ti = upDown[k]; + upDown[k] = upDown[bestIndex]; + upDown[bestIndex] = ti; + + ti = dwIndices[k]; + dwIndices[k] = dwIndices[bestIndex]; + dwIndices[bestIndex] = ti; + + tf = changes[k][0]; + changes[k][0] = changes[bestIndex][0]; + changes[bestIndex][0] = tf; + + tf = changes[k][1]; + changes[k][1] = changes[bestIndex][1]; + changes[bestIndex][1] = tf; + + tf = dists[k]; + dists[k] = dists[bestIndex]; + dists[bestIndex] = tf; + } + } + bestIndex = -1; + // find the best change with an acceptable horizontal change + for(i = 0; i < totweight; i++) { + if(fabs(changes[i][0]) > fabs(changes[i][1]*2.0f)) { + bestIndex = i; + break; + } + } + if(bestIndex != -1) { + wasChange = TRUE; + // it is a good place to stop if it tries to move the opposite direction + // (relative to the plane) of last time + if(lastIndex != -1) { + if(wasUp != upDown[bestIndex]) { + wasChange = FALSE; + } + } + lastIndex = bestIndex; + wasUp = upDown[bestIndex]; + dw = (dvert->dw+dwIndices[bestIndex]); + oldw = dw->weight; + if(upDown[bestIndex]) { + dw->weight *= 1+cp; + } else { + dw->weight /= 1+cp; + } + if(dw->weight > 1) { + dw->weight = 1; + } + if(oldw == dw->weight) { + wasChange = FALSE; + } + if(dm) { + dm_deform_clear(dm, ob); dm = NULL; + } + } + }while(wasChange && (distToStart-distToBe)/fabs(distToStart-distToBe) == (dists[bestIndex]-distToBe)/fabs(dists[bestIndex]-distToBe)); + MEM_freeN(upDown); + MEM_freeN(changes); + MEM_freeN(dists); + MEM_freeN(dwIndices); +} + +/* this is used to try to smooth a surface by only adjusting the nonzero weights of a vertex +but it could be used to raise or lower an existing 'bump.' */ +static void vgroup_fix(Scene *scene, Object *ob, float distToBe, float strength, float cp) +{ + int i; + + Mesh *me = ob->data; + MVert *mvert = me->mvert; + const int use_vert_sel= (me->editflag & ME_EDIT_VERT_SEL) != 0; + int *verts = NULL; + for(i = 0; i < me->totvert && mvert; i++, mvert++) { + + if(use_vert_sel && (mvert->flag & SELECT)) { + + int count=0; + if((verts = getSurroundingVerts(me, i, &count))) { + MVert m; + MVert *p = MEM_callocN(sizeof(MVert)*(count), "deformedPoints"); + int k; + + DerivedMesh *dm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH); + for(k = 0; k < count; k++) { + dm->getVert(dm, verts[k], &m); + p[k] = m; + } + + if(count >= 3) { + float d /*, dist */ /* UNUSED */, mag; + float coord[3] = {0}; + float norm[3] = {0}; + getSingleCoordinate(p, count, coord); + dm->getVert(dm, i, &m); + norm[0] = m.co[0]-coord[0]; + norm[1] = m.co[1]-coord[1]; + norm[2] = m.co[2]-coord[2]; + mag = sqrt(norm[0]*norm[0] + norm[1]*norm[1] + norm[2]*norm[2]); + if(mag) {// zeros fix + mul_v3_fl(norm, 1.0f/mag); + + d = -norm[0]*coord[0] -norm[1]*coord[1] -norm[2]*coord[2]; + /* dist = (norm[0]*m.co[0] + norm[1]*m.co[1] + norm[2]*m.co[2] + d); */ /* UNUSED */ + moveCloserToDistanceFromPlane(scene, ob, me, i, norm, coord, d, distToBe, strength, cp); + } + } + + MEM_freeN(verts); + MEM_freeN(p); + } + } + } +} + static void vgroup_levels(Object *ob, float offset, float gain) { bDeformGroup *dg; @@ -743,6 +1154,10 @@ static void vgroup_levels(Object *ob, float offset, float gain) MDeformVert *dvert, **dvert_array=NULL; int i, def_nr, dvert_tot=0; + Mesh *me = ob->data; + MVert *mvert = me->mvert; + const int use_vert_sel= (me->editflag & ME_EDIT_VERT_SEL) != 0; + ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot); dg = BLI_findlink(&ob->defbase, (ob->actdef-1)); @@ -751,6 +1166,11 @@ static void vgroup_levels(Object *ob, float offset, float gain) def_nr= ob->actdef-1; for(i = 0; i < dvert_tot; i++) { + + if(use_vert_sel && !(mvert[i].flag & SELECT)) { + continue; + } + dvert = dvert_array[i]; dw = defvert_find_index(dvert, def_nr); if(dw) { @@ -772,6 +1192,11 @@ static void vgroup_normalize_all(Object *ob, int lock_active) int i, dvert_tot=0; float tot_weight; + + Mesh *me = ob->data; + MVert *mvert = me->mvert; + const int use_vert_sel= (me->editflag & ME_EDIT_VERT_SEL) != 0; + ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot); if(dvert_array) { @@ -781,6 +1206,10 @@ static void vgroup_normalize_all(Object *ob, int lock_active) for(i = 0; i < dvert_tot; i++) { float lock_iweight= 1.0f; int j; + + if(use_vert_sel && !(mvert[i].flag & SELECT)) { + continue; + } tot_weight= 0.0f; dw_act= NULL; @@ -821,6 +1250,11 @@ static void vgroup_normalize_all(Object *ob, int lock_active) else { for(i = 0; i < dvert_tot; i++) { int j; + + if(use_vert_sel && !(mvert[i].flag & SELECT)) { + continue; + } + tot_weight= 0.0f; dvert = dvert_array[i]; @@ -848,12 +1282,45 @@ static void vgroup_normalize_all(Object *ob, int lock_active) } +static void vgroup_lock_all(Object *ob, int action) +{ + bDeformGroup *dg; + + if(action == SEL_TOGGLE) { + action= SEL_SELECT; + for(dg= ob->defbase.first; dg; dg= dg->next) { + if(dg->flag & DG_LOCK_WEIGHT) { + action= SEL_DESELECT; + break; + } + } + } + + for(dg= ob->defbase.first; dg; dg= dg->next) { + switch(action) { + case SEL_SELECT: + dg->flag |= DG_LOCK_WEIGHT; + break; + case SEL_DESELECT: + dg->flag &= ~DG_LOCK_WEIGHT; + break; + case SEL_INVERT: + dg->flag ^= DG_LOCK_WEIGHT; + break; + } + } +} + static void vgroup_invert(Object *ob, int auto_assign, int auto_remove) { bDeformGroup *dg; MDeformWeight *dw; MDeformVert *dvert, **dvert_array=NULL; int i, def_nr, dvert_tot=0; + + Mesh *me = ob->data; + MVert *mvert = me->mvert; + const int use_vert_sel= (me->editflag & ME_EDIT_VERT_SEL) != 0; ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot); @@ -864,6 +1331,10 @@ static void vgroup_invert(Object *ob, int auto_assign, int auto_remove) for(i = 0; i < dvert_tot; i++) { + + if(use_vert_sel && !(mvert[i].flag & SELECT)) { + continue; + } dvert = dvert_array[i]; if(auto_assign) { @@ -976,6 +1447,10 @@ static void vgroup_clean(Object *ob, float eul, int keep_single) MDeformWeight *dw; MDeformVert *dvert, **dvert_array=NULL; int i, def_nr, dvert_tot=0; + + Mesh *me = ob->data; + MVert *mvert = me->mvert; + const int use_vert_sel= (me->editflag & ME_EDIT_VERT_SEL) != 0; ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot); @@ -985,6 +1460,10 @@ static void vgroup_clean(Object *ob, float eul, int keep_single) def_nr= ob->actdef-1; for(i = 0; i < dvert_tot; i++) { + + if(use_vert_sel && !(mvert[i].flag & SELECT)) { + continue; + } dvert = dvert_array[i]; dw= defvert_find_index(dvert, def_nr); @@ -1006,12 +1485,21 @@ static void vgroup_clean_all(Object *ob, float eul, int keep_single) MDeformWeight *dw; MDeformVert *dvert, **dvert_array=NULL; int i, dvert_tot=0; + + Mesh *me = ob->data; + MVert *mvert = me->mvert; + const int use_vert_sel= (me->editflag & ME_EDIT_VERT_SEL) != 0; ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot); if(dvert_array) { for(i = 0; i < dvert_tot; i++) { int j; + + if(use_vert_sel && !(mvert[i].flag & SELECT)) { + continue; + } + dvert = dvert_array[i]; j= dvert->totweight; @@ -1832,6 +2320,82 @@ void OBJECT_OT_vertex_group_normalize_all(wmOperatorType *ot) RNA_def_boolean(ot->srna, "lock_active", TRUE, "Lock Active", "Keep the values of the active group while normalizing others"); } +static int vertex_group_fix_exec(bContext *C, wmOperator *op) +{ + Object *ob= CTX_data_active_object(C); + Scene *scene= CTX_data_scene(C); + + float distToBe= RNA_float_get(op->ptr, "dist"); + float strength= RNA_float_get(op->ptr, "strength"); + float cp= RNA_float_get(op->ptr, "accuracy"); + ModifierData *md= ob->modifiers.first; + + while(md) { + if(md->type == eModifierType_Mirror && (md->mode&eModifierMode_Realtime)) { + break; + } + md = md->next; + } + + if(md && md->type == eModifierType_Mirror) { + BKE_report(op->reports, RPT_ERROR_INVALID_CONTEXT, "This operator does not support an active mirror modifier"); + return OPERATOR_CANCELLED; + } + vgroup_fix(scene, ob, distToBe, strength, cp); + + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_vertex_group_fix(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Fix Vertex Group Deform"; + ot->idname= "OBJECT_OT_vertex_group_fix"; + ot->description= "Modify the position of selected vertices by changing only their respective groups' weights (this tool may be slow for many vertices)."; + + /* api callbacks */ + ot->poll= vertex_group_poll; + ot->exec= vertex_group_fix_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + RNA_def_float(ot->srna, "dist", 0.0f, -FLT_MAX, FLT_MAX, "Distance", "The distance to move to.", -10.0f, 10.0f); + RNA_def_float(ot->srna, "strength", 1.f, -2.0f, FLT_MAX, "Strength", "The distance moved can be changed by this multiplier.", -2.0f, 2.0f); + RNA_def_float(ot->srna, "accuracy", 1.0f, 0.05f, FLT_MAX, "Change Sensitivity", "Changes the amount weights are altered with each iteration: lower values are slower.", 0.05f, 1.f); +} + + +static int vertex_group_lock_exec(bContext *C, wmOperator *op) +{ + Object *ob= CTX_data_active_object(C); + + int action = RNA_enum_get(op->ptr, "action"); + + vgroup_lock_all(ob, action); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_vertex_group_lock(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Change the Lock On Vertex Groups"; + ot->idname= "OBJECT_OT_vertex_group_lock"; + + /* api callbacks */ + ot->poll= vertex_group_poll; + ot->exec= vertex_group_lock_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + WM_operator_properties_select_all(ot); +} + static int vertex_group_invert_exec(bContext *C, wmOperator *op) { Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index 37c720ea43b..eb919261127 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -5409,6 +5409,15 @@ int facemask_paint_poll(bContext *C) return paint_facesel_test(CTX_data_active_object(C)); } +int vert_paint_poll(bContext *C) +{ + return paint_vertsel_test(CTX_data_active_object(C)); +} + +int mask_paint_poll(bContext *C) +{ + return paint_facesel_test(CTX_data_active_object(C)) || paint_vertsel_test(CTX_data_active_object(C)); +} /* use project paint to re-apply an image */ static int texture_paint_camera_project_exec(bContext *C, wmOperator *op) { diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h index 5a0ee19d6c9..f671b7b1713 100644 --- a/source/blender/editors/sculpt_paint/paint_intern.h +++ b/source/blender/editors/sculpt_paint/paint_intern.h @@ -122,6 +122,11 @@ void PAINT_OT_face_select_inverse(struct wmOperatorType *ot); void PAINT_OT_face_select_hide(struct wmOperatorType *ot); void PAINT_OT_face_select_reveal(struct wmOperatorType *ot); +void PAINT_OT_vert_select_all(struct wmOperatorType *ot); +void PAINT_OT_vert_select_inverse(struct wmOperatorType *ot); +int vert_paint_poll(struct bContext *C); +int mask_paint_poll(struct bContext *C); + int facemask_paint_poll(struct bContext *C); /* stroke operator */ diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c index 69af50415cc..287d204115c 100644 --- a/source/blender/editors/sculpt_paint/paint_ops.c +++ b/source/blender/editors/sculpt_paint/paint_ops.c @@ -373,6 +373,10 @@ void ED_operatortypes_paint(void) WM_operatortype_append(PAINT_OT_weight_sample); WM_operatortype_append(PAINT_OT_weight_sample_group); + /* vertex selection */ + WM_operatortype_append(PAINT_OT_vert_select_all); + WM_operatortype_append(PAINT_OT_vert_select_inverse); + /* vertex */ WM_operatortype_append(PAINT_OT_vertex_paint_toggle); WM_operatortype_append(PAINT_OT_vertex_paint); @@ -607,6 +611,17 @@ void ED_keymap_paint(wmKeyConfig *keyconf) WM_keymap_verify_item(keymap, "PAINT_OT_weight_from_bones", WKEY, KM_PRESS, 0, 0); + + /*Weight paint's Vertex Selection Mode */ + keymap= WM_keymap_find(keyconf, "Weight Paint Vertex Selection", 0, 0); + keymap->poll= vert_paint_poll; + WM_keymap_add_item(keymap, "PAINT_OT_vert_select_all", AKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "PAINT_OT_vert_select_inverse", IKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "VIEW3D_OT_select_border", BKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "VIEW3D_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL, 0); + RNA_boolean_set(WM_keymap_add_item(keymap, "VIEW3D_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_SHIFT|KM_CTRL, 0)->ptr, "deselect", 1); + WM_keymap_add_item(keymap, "VIEW3D_OT_select_circle", CKEY, KM_PRESS, 0, 0); + /* Image/Texture Paint mode */ keymap= WM_keymap_find(keyconf, "Image Paint", 0, 0); keymap->poll= image_texture_paint_poll; diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c index 33b8a7ca686..d332dc6ec0d 100644 --- a/source/blender/editors/sculpt_paint/paint_utils.c +++ b/source/blender/editors/sculpt_paint/paint_utils.c @@ -1,5 +1,5 @@ /* - * $Id: + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -387,6 +387,49 @@ void PAINT_OT_face_select_all(wmOperatorType *ot) WM_operator_properties_select_all(ot); } + +static int vert_select_all_exec(bContext *C, wmOperator *op) +{ + Object *ob= CTX_data_active_object(C); + paintvert_deselect_all_visible(ob, RNA_enum_get(op->ptr, "action"), TRUE); + ED_region_tag_redraw(CTX_wm_region(C)); + return OPERATOR_FINISHED; +} + + +void PAINT_OT_vert_select_all(wmOperatorType *ot) +{ + ot->name= "Vertex Selection"; + ot->description= "Change selection for all vertices"; + ot->idname= "PAINT_OT_vert_select_all"; + + ot->exec= vert_select_all_exec; + ot->poll= vert_paint_poll; + + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; + + WM_operator_properties_select_all(ot); +} + +static int vert_select_inverse_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Object *ob= CTX_data_active_object(C); + paintvert_deselect_all_visible(ob, SEL_INVERT, TRUE); + ED_region_tag_redraw(CTX_wm_region(C)); + return OPERATOR_FINISHED; +} + +void PAINT_OT_vert_select_inverse(wmOperatorType *ot) +{ + ot->name= "Vertex Select Invert"; + ot->description= "Invert selection of vertices"; + ot->idname= "PAINT_OT_vert_select_inverse"; + + ot->exec= vert_select_inverse_exec; + ot->poll= vert_paint_poll; + + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} static int face_select_inverse_exec(bContext *C, wmOperator *UNUSED(op)) { Object *ob= CTX_data_active_object(C); diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index b2aa1be3b9f..11a46bb373b 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -64,6 +64,7 @@ #include "RNA_enum_types.h" #include "BKE_DerivedMesh.h" +#include "BKE_armature.h" #include "BKE_action.h" #include "BKE_brush.h" #include "BKE_context.h" @@ -390,25 +391,27 @@ void vpaint_fill(Object *ob, unsigned int paintcol) void wpaint_fill(VPaint *wp, Object *ob, float paintweight) { Mesh *me; - MFace *mface; MDeformWeight *dw, *uw; int *indexar; - int index, vgroup; - unsigned int faceverts[5]={0,0,0,0,0}; - unsigned char i; - int vgroup_mirror= -1; + unsigned int index; + int vgroup, vgroup_mirror= -1; int selected; + int use_vert_sel; + me= ob->data; if(me==NULL || me->totface==0 || me->dvert==NULL || !me->mface) return; selected= (me->editflag & ME_EDIT_PAINT_MASK); + + use_vert_sel= (me->editflag & ME_EDIT_VERT_SEL) != 0; indexar= get_indexarray(me); if(selected) { - for(index=0, mface=me->mface; index<me->totface; index++, mface++) { - if((mface->flag & ME_FACE_SEL)==0) + MFace *mf; + for(index=0, mf= me->mface; index<me->totface; index++, mf++) { + if((mf->flag & ME_FACE_SEL)==0) indexar[index]= 0; else indexar[index]= index+1; @@ -430,22 +433,25 @@ void wpaint_fill(VPaint *wp, Object *ob, float paintweight) for(index=0; index<me->totface; index++) { if(indexar[index] && indexar[index]<=me->totface) { - mface= me->mface + (indexar[index]-1); - /* just so we can loop through the verts */ - faceverts[0]= mface->v1; - faceverts[1]= mface->v2; - faceverts[2]= mface->v3; - faceverts[3]= mface->v4; - for (i=0; i<3 || faceverts[i]; i++) { - if(!((me->dvert+faceverts[i])->flag)) { - dw= defvert_verify_index(me->dvert+faceverts[i], vgroup); + MFace *mf= &me->mface[indexar[index]-1]; + unsigned int fidx= mf->v4 ? 3:2; + + do { + unsigned int vidx= *(&mf->v1 + fidx); + + if(!me->dvert[vidx].flag) { + if(use_vert_sel && !(me->mvert[vidx].flag & SELECT)) { + continue; + } + + dw= defvert_verify_index(&me->dvert[vidx], vgroup); if(dw) { - uw= defvert_verify_index(wp->wpaint_prev+faceverts[i], vgroup); + uw= defvert_verify_index(wp->wpaint_prev+vidx, vgroup); uw->weight= dw->weight; /* set the undo weight */ dw->weight= paintweight; - + if(me->editflag & ME_EDIT_MIRROR_X) { /* x mirror painting */ - int j= mesh_get_x_mirror_vert(ob, faceverts[i]); + int j= mesh_get_x_mirror_vert(ob, vidx); if(j>=0) { /* copy, not paint again */ if(vgroup_mirror != -1) { @@ -460,16 +466,19 @@ void wpaint_fill(VPaint *wp, Object *ob, float paintweight) } } } - (me->dvert+faceverts[i])->flag= 1; + me->dvert[vidx].flag= 1; } - } + + + } while (fidx--); } } - - index=0; - while (index<me->totvert) { - (me->dvert+index)->flag= 0; - index++; + + { + MDeformVert *dv= me->dvert; + for(index= me->totvert; index != 0; index--, dv++) { + dv->flag= 0; + } } MEM_freeN(indexar); @@ -792,7 +801,7 @@ static float calc_vp_alpha_dl(VPaint *vp, ViewContext *vc, float vpimat[][3], fl return alpha; } -static void wpaint_blend(VPaint *wp, MDeformWeight *dw, MDeformWeight *uw, float alpha, float paintval, int flip) +static void wpaint_blend(VPaint *wp, MDeformWeight *dw, MDeformWeight *uw, float alpha, float paintval, int flip, int multipaint) { Brush *brush = paint_brush(&wp->paint); int tool = brush->vertexpaint_tool; @@ -830,7 +839,10 @@ static void wpaint_blend(VPaint *wp, MDeformWeight *dw, MDeformWeight *uw, float if (dw->weight > paintval) dw->weight = paintval*alpha + dw->weight*(1.0f-alpha); } - CLAMP(dw->weight, 0.0f, 1.0f); + /* delay clamping until the end so multi-paint can function when the active group is at the limits */ + if(multipaint == FALSE) { + CLAMP(dw->weight, 0.0f, 1.0f); + } /* if no spray, clip result with orig weight & orig alpha */ if((wp->flag & VP_SPRAY)==0) { @@ -857,15 +869,17 @@ static void wpaint_blend(VPaint *wp, MDeformWeight *dw, MDeformWeight *uw, float else testw = uw->weight; } - CLAMP(testw, 0.0f, 1.0f); - - if( testw<uw->weight ) { - if(dw->weight < testw) dw->weight= testw; - else if(dw->weight > uw->weight) dw->weight= uw->weight; - } - else { - if(dw->weight > testw) dw->weight= testw; - else if(dw->weight < uw->weight) dw->weight= uw->weight; + + if(multipaint == FALSE) { + CLAMP(testw, 0.0f, 1.0f); + if( testw<uw->weight ) { + if(dw->weight < testw) dw->weight= testw; + else if(dw->weight > uw->weight) dw->weight= uw->weight; + } + else { + if(dw->weight > testw) dw->weight= testw; + else if(dw->weight < uw->weight) dw->weight= uw->weight; + } } } @@ -980,7 +994,7 @@ static EnumPropertyItem *weight_paint_sample_enum_itemf(bContext *C, PointerRNA const int totgroup= BLI_countlist(&vc.obact->defbase); if(totgroup) { MFace *mf= ((MFace *)me->mface) + index-1; - int fidx= mf->v4 ? 3:2; + unsigned int fidx= mf->v4 ? 3:2; int *groups= MEM_callocN(totgroup*sizeof(int), "groups"); int found= FALSE; @@ -1062,6 +1076,7 @@ void PAINT_OT_weight_sample_group(wmOperatorType *ot) } +#if 0 /* UNUSED */ static void do_weight_paint_auto_normalize(MDeformVert *dvert, int paint_nr, char *map) { @@ -1096,41 +1111,600 @@ 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) +{ +// MDeformWeight *dw = dvert->dw; + float sum=0.0f, fac=0.0f; + int i, tot=0; + + if (do_auto_normalize == FALSE) + return; + + for (i=0; i<dvert->totweight; i++) { + if (map[dvert->dw[i].def_nr]) { + tot += 1; + sum += dvert->dw[i].weight; + } + } + + if (!tot || sum == 1.0f) + return; + + fac = sum; + fac = fac==0.0f ? 1.0f : 1.0f / fac; + + for (i=0; i<dvert->totweight; i++) { + if (map[dvert->dw[i].def_nr]) { + dvert->dw[i].weight *= fac; + } + } +} + +/* +See if the current deform vertex has a locked group +*/ +static char has_locked_group(MDeformVert *dvert, const char *lock_flags) +{ + int i; + for(i = 0; i < dvert->totweight; i++) { + if(lock_flags[dvert->dw[i].def_nr] && dvert->dw[i].weight > 0.0f) { + return TRUE; + } + } + return FALSE; +} +/* + * gen_lck_flags gets the status of "flag" for each bDeformGroup + *in ob->defbase and returns an array containing them + */ +static char *gen_lock_flags(Object* ob, int defbase_tot) +{ + char is_locked = FALSE; + int i; + //int defbase_tot = BLI_countlist(&ob->defbase); + char *lock_flags = MEM_mallocN(defbase_tot*sizeof(char), "defflags"); + bDeformGroup *defgroup; + + for(i = 0, defgroup = ob->defbase.first; i < defbase_tot && defgroup; defgroup = defgroup->next, i++) { + lock_flags[i] = ((defgroup->flag & DG_LOCK_WEIGHT) != 0); + is_locked |= lock_flags[i]; + } + if(is_locked){ + return lock_flags; + } + + MEM_freeN(lock_flags); + return NULL; +} + +static int has_locked_group_selected(int defbase_tot, char *defbase_sel, char *lock_flags) +{ + int i; + for(i = 0; i < defbase_tot; i++) { + if(defbase_sel[i] && lock_flags[i]) { + return TRUE; + } + } + return FALSE; +} + + +#if 0 /* UNUSED */ +static int has_unselected_unlocked_bone_group(int defbase_tot, char *defbase_sel, int selected, char *lock_flags, char *vgroup_validmap) +{ + int i; + if(defbase_tot == selected) { + return FALSE; + } + for(i = 0; i < defbase_tot; i++) { + if(vgroup_validmap[i] && !defbase_sel[i] && !lock_flags[i]) { + return TRUE; + } + } + return FALSE; +} +#endif + + +static void multipaint_selection(MDeformVert *dvert, float change, char *defbase_sel, int defbase_tot) +{ + int i; + MDeformWeight *dw; + float val; + /* make sure they are all at most 1 after the change */ + for(i = 0; i < defbase_tot; i++) { + if(defbase_sel[i]) { + dw = defvert_find_index(dvert, i); + if(dw && dw->weight) { + val = dw->weight * change; + if(val > 1) { + /* TODO: when the change is reduced, you need to recheck + * the earlier values to make sure they are not 0 + * (precision error) */ + change = 1.0f/dw->weight; + } + /* the value should never reach zero while multi-painting if it + * was nonzero beforehand */ + if(val <= 0) { + return; + } + } + } + } + /* apply the valid change */ + for(i = 0; i < defbase_tot; i++) { + if(defbase_sel[i]) { + dw = defvert_find_index(dvert, i); + if(dw && dw->weight) { + dw->weight = dw->weight * change; + } + } + } +} + +/* move all change onto valid, unchanged groups. If there is change left over, + * then return it. + * assumes there are valid groups to shift weight onto */ +static float redistribute_change(MDeformVert *ndv, char *change_status, int changeme, int changeto, float totchange, float total_valid, char do_auto_normalize) +{ + float was_change; + float change; + float oldval; + MDeformWeight *ndw; + int i; + do { + /* assume there is no change until you see one */ + was_change = FALSE; + /* change each group by the same amount each time */ + change = totchange/total_valid; + for(i = 0; i < ndv->totweight && total_valid && totchange; i++) { + ndw = (ndv->dw+i); + /* change only the groups with a valid status */ + if(change_status[ndw->def_nr] == changeme) { + oldval = ndw->weight; + /* if auto normalize is active, don't worry about upper bounds */ + if(do_auto_normalize == FALSE && ndw->weight + change > 1) { + totchange -= 1-ndw->weight; + ndw->weight = 1; + /* stop the changes to this group */ + change_status[ndw->def_nr] = changeto; + total_valid--; + } + else if(ndw->weight + change < 0) { /* check the lower bound */ + totchange -= ndw->weight; + ndw->weight = 0; + change_status[ndw->def_nr] = changeto; + total_valid--; + } + else {/* a perfectly valid change occurred to ndw->weight */ + totchange -= change; + ndw->weight += change; + } + /* see if there was a change */ + if(oldval != ndw->weight) { + was_change = TRUE; + } + } + } + /* don't go again if there was no change, if there is no valid group, + * or there is no change left */ + } while(was_change && total_valid && totchange); + /* left overs */ + return totchange; +} + +/* observe the changes made to the weights of groups. + * make sure all locked groups on the vertex have the same deformation + * by moving the changes made to groups onto other unlocked groups */ +static void enforce_locks(MDeformVert *odv, MDeformVert *ndv, int defbase_tot, + const char *lock_flags, const char *vgroup_validmap, char do_auto_normalize) +{ + float totchange = 0.0f; + float totchange_allowed = 0.0f; + float left_over; + + int total_valid = 0; + int total_changed = 0; + unsigned int i; + MDeformWeight *ndw; + MDeformWeight *odw; + MDeformWeight *ndw2; + MDeformWeight *odw2; + int designatedw = -1; + int designatedw_changed = FALSE; + float storedw; + char *change_status; + char new_weight_has_zero = FALSE; + + if(!lock_flags || !has_locked_group(ndv, lock_flags)) { + return; + } + /* record if a group was changed, unlocked and not changed, or locked */ + change_status = MEM_callocN(sizeof(char)*defbase_tot, "unlocked_unchanged"); + + for(i = 0; i < defbase_tot; i++) { + ndw = defvert_find_index(ndv, i); + odw = defvert_find_index(odv, i); + /* the weights are zero, so we can assume a lot */ + if(!ndw || !odw) { + if (!lock_flags[i] && vgroup_validmap[i]){ + defvert_verify_index(odv, i); + defvert_verify_index(ndv, i); + total_valid++; + change_status[i] = 1; /* can be altered while redistributing */ + } + continue; + } + /* locked groups should not be changed */ + if(lock_flags[i]) { + ndw->weight = odw->weight; + } + else if(ndw->weight != odw->weight) { /* changed groups are handled here */ + totchange += ndw->weight - odw->weight; + change_status[i] = 2; /* was altered already */ + total_changed++; + if(ndw->weight == 0) { + new_weight_has_zero = TRUE; + } + else if(designatedw == -1){ + designatedw = i; + } + } /* unchanged, unlocked bone groups are handled here */ + else if (vgroup_validmap[i]){ + totchange_allowed += ndw->weight; + total_valid++; + change_status[i] = 1; /* can be altered while redistributing */ + } + } + /* if there was any change, redistribute it */ + if(total_changed) { + /* auto normalize will allow weights to temporarily go above 1 in redistribution */ + if(vgroup_validmap && total_changed < 0 && total_valid) { + totchange_allowed = total_valid; + } + /* there needs to be change allowed, or you should not bother */ + if(totchange_allowed) { + /* the way you modify the unlocked+unchanged groups is different depending + * on whether or not you are painting the weight(s) up or down */ + if(totchange < 0) { + totchange_allowed = total_valid - totchange_allowed; + } + else { + totchange_allowed *= -1; + } + left_over = 0; + if(fabsf(totchange_allowed) < fabsf(totchange)) { + /* this amount goes back onto the changed, unlocked weights */ + left_over = fabsf(fabsf(totchange) - fabsf(totchange_allowed)); + if(totchange > 0) { + left_over *= -1; + } + } + else { + /* all of the change will be permitted */ + totchange_allowed = -totchange; + } + /* move the weight evenly between the allowed groups, move excess back onto the used groups based on the change */ + totchange_allowed = redistribute_change(ndv, change_status, 1, -1, totchange_allowed, total_valid, do_auto_normalize); + left_over += totchange_allowed; + if(left_over) { + /* more than one nonzero weights were changed with the same ratio, so keep them changed that way! */ + if(total_changed > 1 && !new_weight_has_zero && designatedw >= 0) { + /* this dw is special, it is used as a base to determine how to change the others */ + ndw = defvert_find_index(ndv, designatedw); + odw = defvert_find_index(odv, designatedw); + storedw = ndw->weight; + for(i = 0; i < ndv->totweight; i++) { + if(change_status[ndw->def_nr] == 2) { + odw2 = &odv->dw[i]; + ndw2 = &ndv->dw[i]; + if(!designatedw_changed) { + ndw->weight = (totchange_allowed + odw->weight + odw2->weight)/(1.0f + ndw2->weight/ndw->weight); + designatedw_changed = TRUE; + } + ndw2->weight = ndw->weight * ndw2->weight / storedw; + } + } + } + /* a weight was changed to zero, only one weight was changed, + * or designatedw is still -1 put weight back as evenly as possible */ + else { + redistribute_change(ndv, change_status, 2, -2, left_over, total_changed, do_auto_normalize); + } + } + } + else { + /* reset the weights */ + unsigned int i; + MDeformWeight *dw_old= odv->dw; + MDeformWeight *dw_new= ndv->dw; + + for (i= odv->totweight; i != 0; i--, dw_old++, dw_new++) { + dw_new->weight= dw_old->weight; + } + } + } + + MEM_freeN(change_status); +} -static void do_weight_paint_vertex(VPaint *wp, Object *ob, int index, - float alpha, float paintweight, int flip, - int vgroup_mirror, char *validmap) +/* multi-paint's initial, potential change is computed here based on the user's stroke */ +static float get_mp_change(MDeformVert *odv, char *defbase_sel, float brush_change) +{ + float selwsum = 0.0f; + unsigned int i; + MDeformWeight *dw= odv->dw; + + for (i= odv->totweight; i != 0; i--, dw++) { + if(defbase_sel[dw->def_nr]) { + selwsum += dw->weight; + } + } + if(selwsum && selwsum+brush_change > 0) { + return (selwsum+brush_change)/selwsum; + } + return 0.0f; +} + +/* 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) +{ + MDeformWeight *dw= dvert->dw; + MDeformWeight *w; + unsigned int i; + for (i= dvert->totweight; i != 0; i--, dw++) { + w= defvert_find_index(wv, 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; + } +} + +static void clamp_weights(MDeformVert *dvert) +{ + MDeformWeight *dw= dvert->dw; + unsigned int i; + for (i= dvert->totweight; i != 0; i--, dw++) { + CLAMP(dw->weight, 0.0f, 1.0f); + } +} + +/* struct to avoid passing many args each call to do_weight_paint_vertex() + * this _could_ be made a part of the operators 'WPaintData' struct, or at + * least a member, but for now keep its own struct, initialized on every + * paint stroke update - campbell */ +typedef struct WeightPaintInfo { + + int defbase_tot; + + /* both must add up to 'defbase_tot' */ + int defbase_tot_sel; + int defbase_tot_unsel; + + int vgroup_mirror; /* mirror group or -1 */ + + char *lock_flags; /* boolean array for locked bones, + * length of defbase_tot */ + char *defbase_sel; /* boolean array for selected bones, + * length of defbase_tot */ + + char *vgroup_validmap; /* same as WeightPaintData.vgroup_validmap, + * only added here for convenience */ + + char do_flip; + char do_multipaint; + char do_auto_normalize; +} WeightPaintInfo; + +/* fresh start to make multi-paint and locking modular */ +/* returns TRUE if it thinks you need to reset the weights due to + * normalizing while multi-painting */ +static int apply_mp_locks_normalize(Mesh *me, const WeightPaintInfo *wpi, + const unsigned int index, + MDeformWeight *dw, MDeformWeight *tdw, + float change, float oldChange, + float oldw, float neww) +{ + MDeformVert *dv= &me->dvert[index]; + MDeformVert dv_test= {NULL}; + + dv_test.dw= MEM_dupallocN(dv->dw); + dv_test.flag = dv->flag; + dv_test.totweight = dv->totweight; + /* do not multi-paint if a locked group is selected or the active group is locked + * !lock_flags[dw->def_nr] helps if nothing is selected, but active group is locked */ + if( (wpi->lock_flags == NULL) || + ((wpi->lock_flags[dw->def_nr] == FALSE) && + has_locked_group_selected(wpi->defbase_tot, wpi->defbase_sel, wpi->lock_flags) == FALSE)) + { + if(wpi->do_multipaint && wpi->defbase_tot_sel > 1) { + if(change && change!=1) { + multipaint_selection(dv, change, wpi->defbase_sel, wpi->defbase_tot); + } + } + else { /* this lets users paint normally, but don't let them paint locked groups */ + dw->weight = neww; + } + } + clamp_weights(dv); + + enforce_locks(&dv_test, dv, wpi->defbase_tot, wpi->lock_flags, wpi->vgroup_validmap, wpi->do_auto_normalize); + + do_weight_paint_auto_normalize_all_groups(dv, wpi->vgroup_validmap, wpi->do_auto_normalize); + + if(oldChange && wpi->do_multipaint && wpi->defbase_tot_sel > 1) { + if(tdw->weight != oldw) { + if(neww > oldw) { + if(tdw->weight <= oldw) { + MEM_freeN(dv_test.dw); + return TRUE; + } + } + else { + if(tdw->weight >= oldw) { + MEM_freeN(dv_test.dw); + return TRUE; + } + } + } + } + MEM_freeN(dv_test.dw); + return FALSE; +} + +/* within the current dvert index, get the dw that is selected and has a weight + * above 0, this helps multi-paint */ +static int get_first_selected_nonzero_weight(MDeformVert *dvert, char *defbase_sel) +{ + int i; + MDeformWeight *dw= dvert->dw; + for(i=0; i< dvert->totweight; i++, dw++) { + if(defbase_sel[dw->def_nr] && dw->weight > 0.0f) { + return i; + } + } + return -1; +} + + +static char *wpaint_make_validmap(Object *ob); + + +static void do_weight_paint_vertex( /* vars which remain the same for every vert */ + VPaint *wp, Object *ob, const WeightPaintInfo *wpi, + /* vars which change on each stroke */ + const unsigned int index, float alpha, float paintweight + ) { Mesh *me= ob->data; + 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(&me->dvert[index], vgroup); uw= defvert_find_index(wp->wpaint_prev+index, vgroup); } else { - dw= defvert_verify_index(me->dvert+index, vgroup); + dw= defvert_verify_index(&me->dvert[index], vgroup); uw= defvert_verify_index(wp->wpaint_prev+index, vgroup); } if(dw==NULL || uw==NULL) return; - - wpaint_blend(wp, dw, uw, alpha, paintweight, flip); - do_weight_paint_auto_normalize(me->dvert+index, vgroup, validmap); - if(me->editflag & ME_EDIT_MIRROR_X) { /* x mirror painting */ - int j= mesh_get_x_mirror_vert(ob, index); - if(j>=0) { - /* copy, not paint again */ - if(vgroup_mirror != -1) - uw= defvert_verify_index(me->dvert+j, vgroup_mirror); - else - uw= defvert_verify_index(me->dvert+j, vgroup); - - uw->weight= dw->weight; + /* 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)) + { + 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) { + /* copy, not paint again */ + uw= defvert_verify_index(me->dvert+j, (wpi->vgroup_mirror != -1) ? wpi->vgroup_mirror : vgroup); + + uw->weight= dw->weight; - do_weight_paint_auto_normalize(me->dvert+j, vgroup, validmap); + do_weight_paint_auto_normalize_all_groups(me->dvert+j, wpi->vgroup_validmap, wpi->do_auto_normalize); + } + } + } + else { + /* use locks and/or multipaint */ + float oldw; + float neww; + float testw=0; + float change = 0; + float oldChange = 0; + int i; + MDeformWeight *tdw = NULL, *tuw; + MDeformVert dv= {NULL}; + + oldw = dw->weight; + wpaint_blend(wp, dw, uw, alpha, paintweight, wpi->do_flip, wpi->do_multipaint && wpi->defbase_tot_sel >1); + neww = dw->weight; + dw->weight = oldw; + + /* 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; + 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); + if(i>=0) { + tdw = &(me->dvert[index].dw[i]); + tuw = defvert_verify_index(wp->wpaint_prev+index, tdw->def_nr); + } + else { + change = 0; + } + } + if(change && tuw->weight && tuw->weight * change) { + if(tdw->weight != tuw->weight) { + oldChange = tdw->weight/tuw->weight; + testw = tuw->weight*change; + 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]); + } + else { + /* the old change was more significant, so set + * the change to 0 so that it will not do another multi-paint */ + change = 0; + } + } + else { + if(change < oldChange) { + reset_to_prev(wp->wpaint_prev+index, &me->dvert[index]); + } + else { + change = 0; + } + } + } + } + else { + change = 0; + } + } + } + + if(apply_mp_locks_normalize(me, wpi, index, dw, tdw, change, oldChange, oldw, neww)) { + reset_to_prev(&dv, &me->dvert[index]); + change = 0; + oldChange = 0; + } + if(dv.dw) { + MEM_freeN(dv.dw); + } + /* dvert may have been altered greatly */ + dw = defvert_find_index(&me->dvert[index], vgroup); + + if(me->editflag & ME_EDIT_MIRROR_X) { /* x mirror painting */ + int j= mesh_get_x_mirror_vert(ob, index); + if(j>=0) { + /* copy, not paint again */ + uw= defvert_verify_index(me->dvert+j, (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); + } } } } @@ -1227,16 +1801,15 @@ struct WPaintData { /*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; }; static char *wpaint_make_validmap(Object *ob) { bDeformGroup *dg; ModifierData *md; - char *validmap; - bPose *pose; - bPoseChannel *chan; - ArmatureModifierData *amd; + char *vgroup_validmap; GHash *gh = BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "wpaint_make_validmap gh"); int i = 0, step1=1; @@ -1248,7 +1821,7 @@ static char *wpaint_make_validmap(Object *ob) if (!i) return NULL; - validmap = MEM_callocN(i, "wpaint valid map"); + vgroup_validmap= MEM_callocN(i, "wpaint valid map"); /*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) { @@ -1257,10 +1830,11 @@ static char *wpaint_make_validmap(Object *ob) if (md->type == eModifierType_Armature) { - amd = (ArmatureModifierData*) md; + ArmatureModifierData *amd= (ArmatureModifierData*) md; if(amd->object && amd->object->pose) { - pose = amd->object->pose; + bPose *pose= amd->object->pose; + bPoseChannel *chan; for (chan=pose->chanbase.first; chan; chan=chan->next) { if (chan->bone->flag & BONE_NO_DEFORM) @@ -1278,13 +1852,13 @@ static char *wpaint_make_validmap(Object *ob) /*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) { - validmap[i] = 1; + vgroup_validmap[i] = TRUE; } } BLI_ghash_free(gh, NULL, NULL); - return validmap; + return vgroup_validmap; } static int wpaint_stroke_test_start(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) @@ -1318,7 +1892,9 @@ 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; - if (wpd->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) wpd->vgroup_validmap = wpaint_make_validmap(ob); // if(qual & LR_CTRLKEY) { @@ -1385,14 +1961,19 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P float mat[4][4]; float paintweight; int *indexar; - int totindex, index, totw, flip; + int totw; + unsigned int index, totindex; float alpha; float mval[2], pressure; - + int use_vert_sel; + + /* intentionally dont initialize as NULL, make sure we initialize all members below */ + WeightPaintInfo wpi; + /* cannot paint if there is no stroke data */ if (wpd == NULL) { - // XXX: force a redraw here, since even though we can't paint, - // at least view won't freeze until stroke ends + /* XXX: force a redraw here, since even though we can't paint, + * at least view won't freeze until stroke ends */ ED_region_tag_redraw(CTX_wm_region(C)); return; } @@ -1407,17 +1988,39 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P /* load projection matrix */ mul_m4_m4m4(mat, ob->obmat, vc->rv3d->persmat); - flip = RNA_boolean_get(itemptr, "pen_flip"); pressure = RNA_float_get(itemptr, "pressure"); RNA_float_get_array(itemptr, "mouse", mval); mval[0]-= vc->ar->winrct.xmin; mval[1]-= vc->ar->winrct.ymin; - + + + + /* *** setup WeightPaintInfo - pass onto do_weight_paint_vertex *** */ + wpi.defbase_tot= wpd->defbase_tot; + wpi.defbase_sel= MEM_mallocN(wpi.defbase_tot*sizeof(char), "wpi.defbase_sel"); + wpi.defbase_tot_sel= get_selected_defgroups(ob, wpi.defbase_sel, wpi.defbase_tot); + if(wpi.defbase_tot_sel == 0 && ob->actdef) wpi.defbase_tot_sel = 1; + wpi.defbase_tot_unsel= wpi.defbase_tot - wpi.defbase_tot_sel; + wpi.vgroup_mirror= wpd->vgroup_mirror; + wpi.lock_flags= wpd->lock_flags; + 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); + /* *** done setting up WeightPaintInfo *** */ + + + swap_m4m4(wpd->vc.rv3d->persmat, mat); - + + use_vert_sel= (me->editflag & ME_EDIT_VERT_SEL) != 0; + /* which faces are involved */ if(wp->flag & VP_AREA) { + /* Ugly hack, to avoid drawing vertex index when getting the face index buffer - campbell */ + me->editflag &= ~ME_EDIT_VERT_SEL; totindex= sample_backbuf_area(vc, indexar, me->totface, mval[0], mval[1], brush_size(brush)); + me->editflag |= use_vert_sel ? ME_EDIT_VERT_SEL : 0; } else { indexar[0]= view3d_sample_backbuf(vc, mval[0], mval[1]); @@ -1460,30 +2063,40 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P for(index=0; index<totindex; index++) { if(indexar[index] && indexar[index]<=me->totface) { MFace *mface= me->mface + (indexar[index]-1); - - (me->dvert+mface->v1)->flag= 1; - (me->dvert+mface->v2)->flag= 1; - (me->dvert+mface->v3)->flag= 1; - if(mface->v4) (me->dvert+mface->v4)->flag= 1; + + if(use_vert_sel) { + me->dvert[mface->v1].flag = (me->mvert[mface->v1].flag & SELECT); + me->dvert[mface->v2].flag = (me->mvert[mface->v2].flag & SELECT); + me->dvert[mface->v3].flag = (me->mvert[mface->v3].flag & SELECT); + if(mface->v4) me->dvert[mface->v4].flag = (me->mvert[mface->v4].flag & SELECT); + } + else { + me->dvert[mface->v1].flag= 1; + me->dvert[mface->v2].flag= 1; + me->dvert[mface->v3].flag= 1; + if(mface->v4) me->dvert[mface->v4].flag= 1; + } if(brush->vertexpaint_tool==VP_BLUR) { MDeformWeight *dw, *(*dw_func)(MDeformVert *, const int); + unsigned int fidx= mface->v4 ? 3:2; if(wp->flag & VP_ONLYVGROUP) dw_func= (MDeformWeight *(*)(MDeformVert *, const int))defvert_find_index; else dw_func= defvert_verify_index; - - dw= dw_func(me->dvert+mface->v1, ob->actdef-1); - if(dw) {paintweight+= dw->weight; totw++;} - dw= dw_func(me->dvert+mface->v2, ob->actdef-1); - if(dw) {paintweight+= dw->weight; totw++;} - dw= dw_func(me->dvert+mface->v3, ob->actdef-1); - if(dw) {paintweight+= dw->weight; totw++;} - if(mface->v4) { - dw= dw_func(me->dvert+mface->v4, ob->actdef-1); - if(dw) {paintweight+= dw->weight; totw++;} - } + + do { + unsigned int vidx= *(&mface->v1 + fidx); + + dw= dw_func(me->dvert+vidx, ob->actdef-1); + if(dw) { + paintweight+= dw->weight; + totw++; + } + + } while (fidx--); + } } } @@ -1494,52 +2107,28 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P for(index=0; index<totindex; index++) { if(indexar[index] && indexar[index]<=me->totface) { - MFace *mface= me->mface + (indexar[index]-1); - - if((me->dvert+mface->v1)->flag) { - alpha= calc_vp_alpha_dl(wp, vc, wpd->wpimat, wpd->vertexcosnos+6*mface->v1, mval, pressure); - if(alpha) { - do_weight_paint_vertex(wp, ob, mface->v1, - alpha, paintweight, flip, wpd->vgroup_mirror, - wpd->vgroup_validmap); - } - (me->dvert+mface->v1)->flag= 0; - } - - if((me->dvert+mface->v2)->flag) { - alpha= calc_vp_alpha_dl(wp, vc, wpd->wpimat, wpd->vertexcosnos+6*mface->v2, mval, pressure); - if(alpha) { - do_weight_paint_vertex(wp, ob, mface->v2, - alpha, paintweight, flip, wpd->vgroup_mirror, - wpd->vgroup_validmap); - } - (me->dvert+mface->v2)->flag= 0; - } - - if((me->dvert+mface->v3)->flag) { - alpha= calc_vp_alpha_dl(wp, vc, wpd->wpimat, wpd->vertexcosnos+6*mface->v3, mval, pressure); - if(alpha) { - do_weight_paint_vertex(wp, ob, mface->v3, - alpha, paintweight, flip, wpd->vgroup_mirror, - wpd->vgroup_validmap); - } - (me->dvert+mface->v3)->flag= 0; - } - - if((me->dvert+mface->v4)->flag) { - if(mface->v4) { - alpha= calc_vp_alpha_dl(wp, vc, wpd->wpimat, wpd->vertexcosnos+6*mface->v4, mval, pressure); + MFace *mf= me->mface + (indexar[index]-1); + unsigned int fidx= mf->v4 ? 3:2;; + do { + unsigned int vidx= *(&mf->v1 + fidx); + + if(me->dvert[vidx].flag) { + alpha= calc_vp_alpha_dl(wp, vc, wpd->wpimat, wpd->vertexcosnos+6*vidx, mval, pressure); if(alpha) { - do_weight_paint_vertex(wp, ob, mface->v4, - alpha, paintweight, flip, wpd->vgroup_mirror, - wpd->vgroup_validmap); + do_weight_paint_vertex(wp, ob, &wpi, vidx, alpha, paintweight); } - (me->dvert+mface->v4)->flag= 0; + me->dvert[vidx].flag= 0; } - } + } while (fidx--); } } - + + + /* *** free wpi members */ + MEM_freeN(wpi.defbase_sel); + /* *** dont freeing wpi members */ + + swap_m4m4(vc->rv3d->persmat, mat); DAG_id_tag_update(ob->data, 0); @@ -1559,7 +2148,9 @@ static void wpaint_stroke_done(bContext *C, struct PaintStroke *stroke) if (wpd->vgroup_validmap) MEM_freeN(wpd->vgroup_validmap); - + if(wpd->lock_flags) + MEM_freeN(wpd->lock_flags); + MEM_freeN(wpd); } @@ -1633,7 +2224,7 @@ static int weight_paint_set_exec(bContext *C, wmOperator *UNUSED(op)) Object *obact = CTX_data_active_object(C); wpaint_fill(scene->toolsettings->wpaint, obact, scene->toolsettings->vgroup_weight); - ED_region_tag_redraw(CTX_wm_region(C)); // XXX - should redraw all 3D views + ED_region_tag_redraw(CTX_wm_region(C)); /* XXX - should redraw all 3D views */ return OPERATOR_FINISHED; } @@ -1645,7 +2236,7 @@ void PAINT_OT_weight_set(wmOperatorType *ot) /* api callbacks */ ot->exec= weight_paint_set_exec; - ot->poll= facemask_paint_poll; + ot->poll= mask_paint_poll; /* it was facemask_paint_poll */ /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -1781,12 +2372,12 @@ static int vpaint_stroke_test_start(bContext *C, struct wmOperator *op, wmEvent return 1; } -static void vpaint_paint_face(VPaint *vp, VPaintData *vpd, Object *ob, int index, const float mval[2], float pressure, int UNUSED(flip)) +static void vpaint_paint_face(VPaint *vp, VPaintData *vpd, Object *ob, const unsigned int index, const float mval[2], float pressure, int UNUSED(flip)) { ViewContext *vc = &vpd->vc; Brush *brush = paint_brush(&vp->paint); Mesh *me = get_mesh(ob); - MFace *mface= ((MFace*)me->mface) + index; + MFace *mface= &me->mface[index]; unsigned int *mcol= ((unsigned int*)me->mcol) + 4*index; unsigned int *mcolorig= ((unsigned int*)vp->vpaint_prev) + 4*index; float alpha; diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c index 539e975095e..5b72e87f95a 100644 --- a/source/blender/editors/sound/sound_ops.c +++ b/source/blender/editors/sound/sound_ops.c @@ -436,7 +436,7 @@ static void mixdown_draw(bContext *C, wmOperator *op) } #endif // WITH_AUDASPACE -void SOUND_OT_mixdown(wmOperatorType *ot) +static void SOUND_OT_mixdown(wmOperatorType *ot) { #ifdef WITH_AUDASPACE static EnumPropertyItem format_items[] = { diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c index 32594e710a4..dc81fb1e8bc 100644 --- a/source/blender/editors/space_action/action_select.c +++ b/source/blender/editors/space_action/action_select.c @@ -1139,7 +1139,7 @@ static void mouse_action_keys (bAnimContext *ac, const int mval[2], short select static int actkeys_clickselect_invoke(bContext *C, wmOperator *op, wmEvent *event) { bAnimContext ac; - ARegion *ar; + /* ARegion *ar; */ /* UNUSED */ short selectmode, column; /* get editor data */ @@ -1147,7 +1147,7 @@ static int actkeys_clickselect_invoke(bContext *C, wmOperator *op, wmEvent *even return OPERATOR_CANCELLED; /* get useful pointers from animation context data */ - ar= ac.ar; + /* ar= ac.ar; */ /* UNUSED */ /* select mode is either replace (deselect all, then add) or add/extend */ if (RNA_boolean_get(op->ptr, "extend")) diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index afab4ede229..e345caf1359 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -595,7 +595,7 @@ static void image_refresh(const bContext *C, ScrArea *UNUSED(sa)) tf = EM_get_active_mtface(em, NULL, NULL, 1); /* partially selected face is ok */ - if(tf && (tf->mode & TF_TEX)) { + if(tf) { /* don't need to check for pin here, see above */ sima->image= tf->tpage; diff --git a/source/blender/editors/space_logic/logic_ops.c b/source/blender/editors/space_logic/logic_ops.c index 60e9595b77a..b7f9af09348 100644 --- a/source/blender/editors/space_logic/logic_ops.c +++ b/source/blender/editors/space_logic/logic_ops.c @@ -43,6 +43,7 @@ #include "BKE_context.h" #include "BKE_main.h" #include "BKE_sca.h" +#include "BKE_material.h" //for texface convert #include "ED_logic.h" #include "ED_object.h" @@ -57,6 +58,11 @@ #include "logic_intern.h" +// temporary new includes for texface functions +#include "DNA_mesh_types.h" +#include "DNA_material_types.h" +#include "DNA_meshdata_types.h" + /* ************* Generic Operator Helpers ************* */ static int edit_sensor_poll(bContext *C) { @@ -687,6 +693,36 @@ static void LOGIC_OT_actuator_move(wmOperatorType *ot) RNA_def_enum(ot->srna, "direction", logicbricks_move_direction, 1, "Direction", "Move Up or Down"); } +/* ************* TexFace Converter Operator ************* */ +static int texface_convert_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Main *bmain= CTX_data_main(C); + do_version_tface(bmain, 0); + + return OPERATOR_FINISHED; +} + +static int texface_convert_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) +{ + return texface_convert_exec(C, op); +} + + static void LOGIC_OT_texface_convert(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "TexFace to Material Converter"; + ot->description = "Convert old texface settings into material. It may create new materials if needed"; + ot->idname= "LOGIC_OT_texface_convert"; + + /* api callbacks */ + ot->invoke= texface_convert_invoke; + ot->exec= texface_convert_exec; +// ot->poll= texface_convert_poll; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + void ED_operatortypes_logic(void) { @@ -699,4 +735,5 @@ void ED_operatortypes_logic(void) WM_operatortype_append(LOGIC_OT_actuator_remove); WM_operatortype_append(LOGIC_OT_actuator_add); WM_operatortype_append(LOGIC_OT_actuator_move); + WM_operatortype_append(LOGIC_OT_texface_convert); } diff --git a/source/blender/editors/space_nla/nla_select.c b/source/blender/editors/space_nla/nla_select.c index 5ea7f357ecf..05d38a63109 100644 --- a/source/blender/editors/space_nla/nla_select.c +++ b/source/blender/editors/space_nla/nla_select.c @@ -606,8 +606,8 @@ static void mouse_nla_strips (bContext *C, bAnimContext *ac, const int mval[2], static int nlaedit_clickselect_invoke(bContext *C, wmOperator *op, wmEvent *event) { bAnimContext ac; - Scene *scene; - ARegion *ar; + /* Scene *scene; */ /* UNUSED */ + /* ARegion *ar; */ /* UNUSED */ // View2D *v2d; /*UNUSED*/ short selectmode; @@ -616,8 +616,8 @@ static int nlaedit_clickselect_invoke(bContext *C, wmOperator *op, wmEvent *even return OPERATOR_CANCELLED; /* get useful pointers from animation context data */ - scene= ac.scene; - ar= ac.ar; + /* scene= ac.scene; */ /* UNUSED */ + /* ar= ac.ar; */ /* UNUSED */ // v2d= &ar->v2d; /* select mode is either replace (deselect all, then add) or add/extend */ diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index cd521f7e8c7..f34cef4d2aa 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -179,6 +179,7 @@ static void node_socket_button_color(const bContext *C, uiBlock *block, /* ****************** BASE DRAW FUNCTIONS FOR NEW OPERATOR NODES ***************** */ +#if 0 /* UNUSED */ static void node_draw_socket_new(bNodeSocket *sock, float size) { float x=sock->locx, y=sock->locy; @@ -216,6 +217,7 @@ static void node_draw_socket_new(bNodeSocket *sock, float size) glDisable( GL_LINE_SMOOTH ); glDisable(GL_BLEND); } +#endif /* ****************** BUTTON CALLBACKS FOR ALL TREES ***************** */ @@ -894,14 +896,14 @@ static void node_browse_text_cb(bContext *C, void *ntree_v, void *node_v) Main *bmain= CTX_data_main(C); bNodeTree *ntree= ntree_v; bNode *node= node_v; - ID *oldid; + /* ID *oldid; */ /* UNUSED */ if(node->menunr<1) return; if(node->id) { node->id->us--; } - oldid= node->id; + /* oldid= node->id; */ /* UNUSED */ node->id= BLI_findlink(&bmain->text, node->menunr-1); id_us_plus(node->id); BLI_strncpy(node->name, node->id->name+2, sizeof(node->name)); diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index a966caa4d70..7cb8351cd12 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -757,6 +757,8 @@ void ED_node_update_hierarchy(bContext *UNUSED(C), bNodeTree *ntree) /* ***************** generic operator functions for nodes ***************** */ +#if 0 /* UNUSED */ + static int edit_node_poll(bContext *C) { return ED_operator_node_active(C); @@ -815,6 +817,7 @@ static void edit_node_properties_get(wmOperator *op, bNodeTree *ntree, bNode **r if (rin_out) *rin_out = in_out; } +#endif /* ***************** Edit Group operator ************* */ @@ -902,7 +905,7 @@ static int node_group_socket_add_exec(bContext *C, wmOperator *op) char name[32]= ""; int type= SOCK_FLOAT; bNodeTree *ngroup= snode->edittree; - bNodeSocket *sock; + /* bNodeSocket *sock; */ /* UNUSED */ ED_preview_kill_jobs(C); @@ -918,7 +921,7 @@ static int node_group_socket_add_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; /* using placeholder subtype first */ - sock = node_group_add_socket(ngroup, name, type, in_out); + /* sock = */ /* UNUSED */ node_group_add_socket(ngroup, name, type, in_out); ntreeUpdateTree(ngroup); diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c index ca9ecf2c328..e2b0b9c65d0 100644 --- a/source/blender/editors/space_node/node_select.c +++ b/source/blender/editors/space_node/node_select.c @@ -109,7 +109,7 @@ static int node_select_exec(bContext *C, wmOperator *op) ARegion *ar= CTX_wm_region(C); int mval[2]; short extend; - bNode *node= NULL; + /* bNode *node= NULL; */ /* UNUSED */ /* get settings from RNA properties for operator */ mval[0] = RNA_int_get(op->ptr, "mouse_x"); @@ -118,7 +118,7 @@ static int node_select_exec(bContext *C, wmOperator *op) extend = RNA_boolean_get(op->ptr, "extend"); /* perform the select */ - node= node_mouse_select(bmain, snode, ar, mval, extend); + /* node= */ /* UNUSED*/ node_mouse_select(bmain, snode, ar, mval, extend); /* send notifiers */ WM_event_add_notifier(C, NC_NODE|NA_SELECTED, NULL); diff --git a/source/blender/editors/space_node/node_state.c b/source/blender/editors/space_node/node_state.c index c4567bea648..13a5f3cb3dc 100644 --- a/source/blender/editors/space_node/node_state.c +++ b/source/blender/editors/space_node/node_state.c @@ -214,12 +214,11 @@ void NODE_OT_visibility_toggle(wmOperatorType *ot) static void snode_home(ScrArea *UNUSED(sa), ARegion *ar, SpaceNode* snode) { bNode *node; - rctf *cur, *tot; + rctf *cur; float oldwidth, oldheight, width, height; int first= 1; cur= &ar->v2d.cur; - tot= &ar->v2d.tot; oldwidth= cur->xmax - cur->xmin; oldheight= cur->ymax - cur->ymin; diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c index 68b2d3d586f..6bfe370d105 100644 --- a/source/blender/editors/space_outliner/outliner_edit.c +++ b/source/blender/editors/space_outliner/outliner_edit.c @@ -969,7 +969,7 @@ static void tree_element_to_path(SpaceOops *soops, TreeElement *te, TreeStoreEle ListBase hierarchy = {NULL, NULL}; LinkData *ld; TreeElement *tem, *temnext, *temsub; - TreeStoreElem *tse, *tsenext; + TreeStoreElem *tse /* , *tsenext */ /* UNUSED */; PointerRNA *ptr, *nextptr; PropertyRNA *prop; char *newpath=NULL; @@ -1018,7 +1018,7 @@ static void tree_element_to_path(SpaceOops *soops, TreeElement *te, TreeStoreEle char buf[128], *name; temnext= (TreeElement*)(ld->next->data); - tsenext= TREESTORE(temnext); + /* tsenext= TREESTORE(temnext); */ /* UNUSED */ nextptr= &temnext->rnaptr; name= RNA_struct_name_get_alloc(nextptr, buf, sizeof(buf)); diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c index 0a1f7a3599d..9fe0ed0543f 100644 --- a/source/blender/editors/space_outliner/outliner_tree.c +++ b/source/blender/editors/space_outliner/outliner_tree.c @@ -1151,7 +1151,7 @@ static int need_add_seq_dup(Sequence *seq) static void outliner_add_seq_dup(SpaceOops *soops, Sequence *seq, TreeElement *te, short index) { - TreeElement *ch; + /* TreeElement *ch; */ /* UNUSED */ Sequence *p; p= seq; @@ -1162,7 +1162,7 @@ static void outliner_add_seq_dup(SpaceOops *soops, Sequence *seq, TreeElement *t } if(!strcmp(p->strip->stripdata->name, seq->strip->stripdata->name)) - ch= outliner_add_element(soops, &te->subtree, (void*)p, te, TSE_SEQUENCE, index); + /* ch= */ /* UNUSED */ outliner_add_element(soops, &te->subtree, (void*)p, te, TSE_SEQUENCE, index); p= p->next; } } diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index da769184669..bd93a1270f6 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -1483,9 +1483,13 @@ static int sequencer_cut_exec(bContext *C, wmOperator *op) sort_seq(scene); } - WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER, scene); - - return OPERATOR_FINISHED; + if(changed) { + WM_event_add_notifier(C, NC_SCENE|ND_SEQUENCER, scene); + return OPERATOR_FINISHED; + } + else { + return OPERATOR_CANCELLED; + } } diff --git a/source/blender/editors/space_text/text_draw.c b/source/blender/editors/space_text/text_draw.c index 3d49bc7ffa0..685b15aed50 100644 --- a/source/blender/editors/space_text/text_draw.c +++ b/source/blender/editors/space_text/text_draw.c @@ -1291,7 +1291,7 @@ static void draw_documentation(SpaceText *st, ARegion *ar) TextLine *tmp; char *docs, buf[DOC_WIDTH+1], *p; int i, br, lines; - int boxw, boxh, l, x, y, top; + int boxw, boxh, l, x, y /* , top */ /* UNUSED */; if(!st || !st->text) return; if(!texttool_text_is_active(st->text)) return; @@ -1314,7 +1314,7 @@ static void draw_documentation(SpaceText *st, ARegion *ar) x += SUGG_LIST_WIDTH*st->cwidth + 50; } - top= y= ar->winy - st->lheight*l - 2; + /* top= */ /* UNUSED */ y= ar->winy - st->lheight*l - 2; boxw= DOC_WIDTH*st->cwidth + 20; boxh= (DOC_HEIGHT+1)*st->lheight; diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c index 6e02ecbd5a8..b6e76885719 100644 --- a/source/blender/editors/space_view3d/drawmesh.c +++ b/source/blender/editors/space_view3d/drawmesh.c @@ -64,6 +64,7 @@ #include "GPU_buffers.h" #include "GPU_extensions.h" #include "GPU_draw.h" +#include "GPU_material.h" #include "ED_mesh.h" @@ -207,44 +208,71 @@ static Material *give_current_material_or_def(Object *ob, int matnr) return ma?ma:&defmaterial; } -static int set_draw_settings_cached(int clearcache, int textured, MTFace *texface, int lit, Object *litob, int litmatnr, int doublesided) +/* Icky globals, fix with userdata parameter */ + +static struct TextureDrawState { + Object *ob; + int islit, istex; + int color_profile; + unsigned char obcol[4]; +} Gtexdraw = {NULL, 0, 0, 0, {0, 0, 0, 0}}; + +static int set_draw_settings_cached(int clearcache, MTFace *texface, Material *ma, struct TextureDrawState gtexdraw) { + static Material *c_ma; static int c_textured; - static int c_lit; - static int c_doublesided; static MTFace *c_texface; - static Object *c_litob; - static int c_litmatnr; + static int c_backculled; static int c_badtex; + static int c_lit; + Object *litob = NULL; //to get mode to turn off mipmap in painting mode + int backculled = 0; + int alphablend = 0; + int textured = 0; + int lit = 0; + if (clearcache) { - c_textured= c_lit= c_doublesided= -1; + c_textured= c_lit= c_backculled= -1; c_texface= (MTFace*) -1; - c_litob= (Object*) -1; - c_litmatnr= -1; c_badtex= 0; + } else { + textured = gtexdraw.istex; + litob = gtexdraw.ob; + } + + /* convert number of lights into boolean */ + if (gtexdraw.islit) lit = 1; + + if (ma) { + alphablend = ma->game.alpha_blend; + if (ma->mode & MA_SHLESS) lit = 0; + backculled = ma->game.flag & GEMAT_BACKCULL; } if (texface) { - lit = lit && (lit==-1 || texface->mode&TF_LIGHT); - textured = textured && (texface->mode&TF_TEX); - doublesided = texface->mode&TF_TWOSIDE; - } else { - textured = 0; + textured = textured && (texface->tpage); + + /* no material, render alpha if texture has depth=32 */ + if (!ma && BKE_image_has_alpha(texface->tpage)) + alphablend = GPU_BLEND_ALPHA; } - if (doublesided!=c_doublesided) { - if (doublesided) glDisable(GL_CULL_FACE); - else glEnable(GL_CULL_FACE); + else + textured = 0; + + if (backculled!=c_backculled) { + if (backculled) glEnable(GL_CULL_FACE); + else glDisable(GL_CULL_FACE); - c_doublesided= doublesided; + c_backculled= backculled; } if (textured!=c_textured || texface!=c_texface) { if (textured ) { - c_badtex= !GPU_set_tpage(texface, !(litob->mode & OB_MODE_TEXTURE_PAINT)); + c_badtex= !GPU_set_tpage(texface, !(litob->mode & OB_MODE_TEXTURE_PAINT), alphablend); } else { - GPU_set_tpage(NULL, 0); + GPU_set_tpage(NULL, 0, 0); c_badtex= 0; } c_textured= textured; @@ -252,10 +280,10 @@ static int set_draw_settings_cached(int clearcache, int textured, MTFace *texfac } if (c_badtex) lit= 0; - if (lit!=c_lit || litob!=c_litob || litmatnr!=c_litmatnr) { + if (lit!=c_lit || ma!=c_ma) { if (lit) { - Material *ma= give_current_material_or_def(litob, litmatnr+1); float spec[4]; + if (!ma)ma= give_current_material_or_def(NULL, 0); //default material spec[0]= ma->spec*ma->specr; spec[1]= ma->spec*ma->specg; @@ -273,22 +301,11 @@ static int set_draw_settings_cached(int clearcache, int textured, MTFace *texfac glDisable(GL_COLOR_MATERIAL); } c_lit= lit; - c_litob= litob; - c_litmatnr= litmatnr; } return c_badtex; } -/* Icky globals, fix with userdata parameter */ - -static struct TextureDrawState { - Object *ob; - int islit, istex; - int color_profile; - unsigned char obcol[4]; -} Gtexdraw = {NULL, 0, 0, 0, {0, 0, 0, 0}}; - static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob) { unsigned char obcol[4]; @@ -318,14 +335,14 @@ static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, O Gtexdraw.istex = istex; Gtexdraw.color_profile = scene->r.color_mgt_flag & R_COLOR_MANAGEMENT; memcpy(Gtexdraw.obcol, obcol, sizeof(obcol)); - set_draw_settings_cached(1, 0, NULL, Gtexdraw.islit, NULL, 0, 0); + set_draw_settings_cached(1, NULL, NULL, Gtexdraw); glShadeModel(GL_SMOOTH); } static void draw_textured_end(void) { /* switch off textures */ - GPU_set_tpage(NULL, 0); + GPU_set_tpage(NULL, 0, 0); glShadeModel(GL_FLAT); glDisable(GL_CULL_FACE); @@ -347,18 +364,22 @@ static void draw_textured_end(void) static int draw_tface__set_draw_legacy(MTFace *tface, MCol *mcol, int matnr) { - if (tface && (tface->mode&TF_INVISIBLE)) return 0; + Material *ma= give_current_material(Gtexdraw.ob, matnr+1); + int validtexture=0; + + if (ma && (ma->game.flag & GEMAT_INVISIBLE)) return 0; + + validtexture = set_draw_settings_cached(0, tface, ma, Gtexdraw); - if (tface && set_draw_settings_cached(0, Gtexdraw.istex, tface, Gtexdraw.islit, Gtexdraw.ob, matnr, TF_TWOSIDE)) { + if (tface && validtexture) { glColor3ub(0xFF, 0x00, 0xFF); return 2; /* Don't set color */ - } else if (tface && tface->mode&TF_OBCOL) { + } else if (ma && ma->shade_flag&MA_OBCOLOR) { glColor3ubv(Gtexdraw.obcol); return 2; /* Don't set color */ } else if (!mcol) { if (tface) glColor3f(1.0, 1.0, 1.0); else { - Material *ma= give_current_material(Gtexdraw.ob, matnr+1); if(ma) { float col[3]; if(Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r); @@ -375,9 +396,11 @@ static int draw_tface__set_draw_legacy(MTFace *tface, MCol *mcol, int matnr) } static int draw_tface__set_draw(MTFace *tface, MCol *mcol, int matnr) { - if (tface && (tface->mode&TF_INVISIBLE)) return 0; + Material *ma= give_current_material(Gtexdraw.ob, matnr+1); + + if (ma && (ma->game.flag & GEMAT_INVISIBLE)) return 0; - if (tface && set_draw_settings_cached(0, Gtexdraw.istex, tface, Gtexdraw.islit, Gtexdraw.ob, matnr, TF_TWOSIDE)) { + if (tface && set_draw_settings_cached(0, tface, ma, Gtexdraw)) { return 2; /* Don't set color */ } else if (tface && tface->mode&TF_OBCOL) { return 2; /* Don't set color */ @@ -399,7 +422,9 @@ static void add_tface_color_layer(DerivedMesh *dm) finalCol = MEM_mallocN(sizeof(MCol)*4*dm->getNumFaces(dm),"add_tface_color_layer"); for(i=0;i<dm->getNumFaces(dm);i++) { - if (tface && (tface->mode&TF_INVISIBLE)) { + Material *ma= give_current_material(Gtexdraw.ob, mface[i].mat_nr+1); + + if (ma && (ma->game.flag&GEMAT_INVISIBLE)) { if( mcol ) memcpy(&finalCol[i*4],&mcol[i*4],sizeof(MCol)*4); else @@ -409,7 +434,7 @@ static void add_tface_color_layer(DerivedMesh *dm) finalCol[i*4+j].r = 255; } } - else if (tface && mface && set_draw_settings_cached(0, Gtexdraw.istex, tface, Gtexdraw.islit, Gtexdraw.ob, mface[i].mat_nr, TF_TWOSIDE)) { + else if (tface && mface && set_draw_settings_cached(0, tface, ma, Gtexdraw)) { for(j=0;j<4;j++) { finalCol[i*4+j].b = 255; finalCol[i*4+j].g = 0; @@ -494,10 +519,13 @@ static int wpaint__setSolidDrawOptions(void *userData, int index, int *drawSmoot { Mesh *me = (Mesh*)userData; - if ( (me->mface && me->mface[index].flag & ME_HIDE) || - (me->mtface && (me->mtface[index].mode & TF_INVISIBLE)) - ) { - return 0; + if (me->mface) { + short matnr= me->mface[index].mat_nr; + Material *ma= me->mat[matnr]; + + if (ma && (ma->game.flag & GEMAT_INVISIBLE)) { + return 0; + } } *drawSmooth_r = 1; @@ -523,17 +551,18 @@ static void draw_mesh_text(Scene *scene, Object *ob, int glsl) if(ob->mode & OB_MODE_EDIT) return; else if(ob==OBACT) - if(paint_facesel_test(ob)) + if(paint_facesel_test(ob) || paint_vertsel_test(ob)) return; ddm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH); for(a=0, mf=mface; a<totface; a++, tface++, mf++) { - int mode= tface->mode; - int matnr= mf->mat_nr; + short matnr= mf->mat_nr; int mf_smooth= mf->flag & ME_SMOOTH; + Material *mat = me->mat[matnr]; + int mode= mat->game.flag; - if (!(mf->flag&ME_HIDE) && !(mode&TF_INVISIBLE) && (mode&TF_BMFONT)) { + if (!(mode&GEMAT_INVISIBLE) && (mode&GEMAT_TEXT)) { float v1[3], v2[3], v3[3], v4[3]; char string[MAX_PROPSTRING]; int characters, i, glattrib= -1, badtex= 0; @@ -549,7 +578,7 @@ static void draw_mesh_text(Scene *scene, Object *ob, int glsl) } } else { - badtex = set_draw_settings_cached(0, Gtexdraw.istex, tface, Gtexdraw.islit, Gtexdraw.ob, matnr, TF_TWOSIDE); + badtex = set_draw_settings_cached(0, tface, mat, Gtexdraw); if (badtex) { if (mcol) mcol+=4; continue; @@ -578,7 +607,7 @@ static void draw_mesh_text(Scene *scene, Object *ob, int glsl) glNormal3fv(nor); } - GPU_render_text(tface, tface->mode, string, characters, + GPU_render_text(tface, mode, string, characters, (unsigned int*)mcol, v1, v2, v3, (mf->v4? v4: NULL), glattrib); } if (mcol) { diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 0e8e6cdfee1..44d68ded679 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -220,16 +220,13 @@ int draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, int dt) return (scene->gm.matmode == GAME_MAT_GLSL) && (dt > OB_SOLID); } -static int check_material_alpha(Base *base, Mesh *me, int glsl) +static int check_material_alpha(Base *base, int glsl) { if(base->flag & OB_FROMDUPLI) return 0; if(G.f & G_PICKSEL) return 0; - - if(me->edit_mesh) - return 0; return (glsl || (base->object->dtx & OB_DRAWTRANSP)); } @@ -1740,6 +1737,31 @@ void mesh_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, EditVe dm->release(dm); } +/* draw callback */ +static void drawSelectedVertices__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s)) +{ + MVert *mv = &((MVert *)userData)[index]; + + if(!(mv->flag & ME_HIDE)) { + const char sel= mv->flag & SELECT; + + // TODO define selected color + if(sel) { + glColor3f(1.0f, 1.0f, 0.0f); + } + else { + glColor3f(0.0f, 0.0f, 0.0f); + } + + glVertex3fv(co); + } +} + +static void drawSelectedVertices(DerivedMesh *dm, Mesh *me) { + glBegin(GL_POINTS); + dm->foreachMappedVert(dm, drawSelectedVertices__mapFunc, me->mvert); + glEnd(); +} static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, float *v0co, float *v1co) { struct { void (*func)(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int index); void *userData; ViewContext vc; int clipVerts; } *data = userData; @@ -2924,7 +2946,16 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D bglPolygonOffset(rv3d->dist, 0.0); } } - + + if(paint_vertsel_test(ob)) { + + glColor3f(0.0f, 0.0f, 0.0f); + glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE)); + + drawSelectedVertices(dm, ob->data); + + glPointSize(1.0f); + } dm->release(dm); } @@ -2964,12 +2995,16 @@ static int draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D scene->customdata_mask); if(dt>OB_WIRE) { - // no transp in editmode, the fancy draw over goes bad then glsl = draw_glsl_material(scene, ob, v3d, dt); - GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, NULL); + check_alpha = check_material_alpha(base, glsl); + + GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, + (check_alpha)? &do_alpha_pass: NULL); } - draw_em_fancy(scene, v3d, rv3d, ob, em, cageDM, finalDM, dt); + // transp in editmode makes the fancy draw over go bad + if (!do_alpha_pass) + draw_em_fancy(scene, v3d, rv3d, ob, em, cageDM, finalDM, dt); GPU_end_object_materials(); @@ -2980,7 +3015,7 @@ static int draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D /* don't create boundbox here with mesh_get_bb(), the derived system will make it, puts deformed bb's OK */ if(me->totface<=4 || ED_view3d_boundbox_clip(rv3d, ob->obmat, (ob->bb)? ob->bb: me->bb)) { glsl = draw_glsl_material(scene, ob, v3d, dt); - check_alpha = check_material_alpha(base, me, glsl); + check_alpha = check_material_alpha(base, glsl); if(dt==OB_SOLID || glsl) { GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, @@ -4022,7 +4057,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv if(draw_as==PART_DRAW_PATH){ ParticleCacheKey **cache, *path; - float *cd2=NULL,*cdata2=NULL; + float /* *cd2=NULL, */ /* UNUSED */ *cdata2=NULL; /* setup gl flags */ if (1) { //ob_dt > OB_WIRE) { @@ -4090,7 +4125,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv if(cdata2) MEM_freeN(cdata2); - cd2=cdata2=NULL; + /* cd2= */ /* UNUSED */ cdata2=NULL; glLineWidth(1.0f); @@ -6516,6 +6551,32 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) /* ***************** BACKBUF SEL (BBS) ********* */ +static void bbs_obmode_mesh_verts__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s)) +{ + struct {void* offset; MVert *mvert;} *data = userData; + MVert *mv = &data->mvert[index]; + int offset = (intptr_t) data->offset; + + if (!(mv->flag & ME_HIDE)) { + WM_set_framebuffer_index_color(offset+index); + bglVertex3fv(co); + } +} + +static void bbs_obmode_mesh_verts(Object *ob, DerivedMesh *dm, int offset) +{ + struct {void* offset; struct MVert *mvert;} data; + Mesh *me = ob->data; + MVert *mvert = me->mvert; + data.mvert = mvert; + data.offset = (void*)(intptr_t) offset; + glPointSize( UI_GetThemeValuef(TH_VERTEX_SIZE) ); + bglBegin(GL_POINTS); + dm->foreachMappedVert(dm, bbs_obmode_mesh_verts__mapFunc, &data); + bglEnd(); + glPointSize(1.0); +} + static void bbs_mesh_verts__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s)) { int offset = (intptr_t) userData; @@ -6614,6 +6675,17 @@ static int bbs_mesh_solid_hide__setDrawOpts(void *userData, int index, int *UNUS } } +// must have called WM_set_framebuffer_index_color beforehand +static int bbs_mesh_solid_hide2__setDrawOpts(void *userData, int index, int *UNUSED(drawSmooth_r)) +{ + Mesh *me = userData; + + if (!(me->mface[index].flag & ME_HIDE)) { + return 1; + } else { + return 0; + } +} static void bbs_mesh_solid(Scene *scene, Object *ob) { DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_mask); @@ -6672,7 +6744,21 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec EM_free_index_arrays(); } else { - bbs_mesh_solid(scene, ob); + Mesh *me= ob->data; + if(me->editflag & ME_EDIT_VERT_SEL) { + DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_mask); + glColor3ub(0, 0, 0); + + dm->drawMappedFaces(dm, bbs_mesh_solid_hide2__setDrawOpts, me, 0, GPU_enable_material, NULL); + + + bbs_obmode_mesh_verts(ob, dm, 1); + em_vertoffs = me->totvert+1; + dm->release(dm); + } + else { + bbs_mesh_solid(scene, ob); + } } break; case OB_CURVE: diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c index 8da6f49e089..e87ace19edb 100644 --- a/source/blender/editors/space_view3d/drawvolume.c +++ b/source/blender/editors/space_view3d/drawvolume.c @@ -183,7 +183,7 @@ void draw_volume(ARegion *ar, GPUTexture *tex, float *min, float *max, int res[3 float viewnormal[3]; int i, j, n, good_index; - float d, d0, dd, ds; + float d /*, d0 */ /* UNUSED */, dd, ds; float *points = NULL; int numpoints = 0; float cor[3] = {1.,1.,1.}; @@ -390,7 +390,8 @@ void draw_volume(ARegion *ar, GPUTexture *tex, float *min, float *max, int res[3 // (a,b,c), the plane normal, are given by viewdir // d is the parameter along the view direction. the first d is given by // inserting previously found vertex into the plane equation - d0 = (viewnormal[0]*cv[i][0] + viewnormal[1]*cv[i][1] + viewnormal[2]*cv[i][2]); + + /* d0 = (viewnormal[0]*cv[i][0] + viewnormal[1]*cv[i][1] + viewnormal[2]*cv[i][2]); */ /* UNUSED */ ds = (ABS(viewnormal[0])*size[0] + ABS(viewnormal[1])*size[1] + ABS(viewnormal[2])*size[2]); dd = 0.05; // ds/512.0f; n = 0; diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index 6833dec2e43..c46b6b6d70b 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -371,6 +371,10 @@ static void view3d_main_area_init(wmWindowManager *wm, ARegion *ar) keymap= WM_keymap_find(wm->defaultconf, "Face Mask", 0, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); + + keymap= WM_keymap_find(wm->defaultconf, "Weight Paint Vertex Selection", 0, 0); + WM_event_add_keymap_handler(&ar->handlers, keymap); + /* pose is not modal, operator poll checks for this */ keymap= WM_keymap_find(wm->defaultconf, "Pose", 0, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 2f2e2c5c282..0854f9f3685 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -2786,7 +2786,7 @@ void VIEW3D_OT_viewnumpad(wmOperatorType *ot) ot->flag= 0; RNA_def_enum(ot->srna, "type", prop_view_items, 0, "View", "The Type of view"); - RNA_def_boolean(ot->srna, "align_active", 0, "Align Active", "Align to the active objects axis"); + RNA_def_boolean(ot->srna, "align_active", 0, "Align Active", "Align to the active object's axis"); } static EnumPropertyItem prop_view_orbit_items[] = { diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c index 55b30aec804..0776ca752a9 100644 --- a/source/blender/editors/space_view3d/view3d_header.c +++ b/source/blender/editors/space_view3d/view3d_header.c @@ -516,7 +516,15 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C) PointerRNA meshptr; RNA_pointer_create(&ob->id, &RNA_Mesh, ob->data, &meshptr); - uiItemR(layout, &meshptr, "use_paint_mask", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); + if(ob->mode & (OB_MODE_TEXTURE_PAINT|OB_MODE_VERTEX_PAINT)) { + uiItemR(layout, &meshptr, "use_paint_mask", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); + } + else { + + row= uiLayoutRow(layout, 1); + uiItemR(row, &meshptr, "use_paint_mask", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); + uiItemR(row, &meshptr, "use_paint_mask_vertex", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); + } } else { const char *str_menu; diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 36ae6b65038..1c98397c7f6 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -54,6 +54,11 @@ #include "BLI_linklist.h" #include "BLI_utildefines.h" +/* vertex box select */ +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" +#include "BKE_global.h" + #include "BKE_context.h" #include "BKE_paint.h" #include "BKE_armature.h" @@ -198,6 +203,24 @@ static void EM_backbuf_checkAndSelectFaces(EditMesh *em, int select) } } + +/* object mode, EM_ prefix is confusing here, rename? */ +static void EM_backbuf_checkAndSelectVerts_obmode(Mesh *me, int select) +{ + MVert *mv = me->mvert; + int a; + + if (mv) { + for(a=1; a<=me->totvert; a++, mv++) { + if(EM_check_backbuf(a)) { + if(!(mv->flag & ME_HIDE)) { + mv->flag = select?(mv->flag|SELECT):(mv->flag&~SELECT); + } + } + } + } +} +/* object mode, EM_ prefix is confusing here, rename? */ static void EM_backbuf_checkAndSelectTFaces(Mesh *me, int select) { MFace *mface = me->mface; @@ -231,7 +254,7 @@ static int view3d_selectable_data(bContext *C) if (ob->mode & OB_MODE_SCULPT) { return 0; } - if (ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT) && !paint_facesel_test(ob)) { + if (ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT) && !paint_facesel_test(ob) && !paint_vertsel_test(ob)) { return 0; } } @@ -727,6 +750,88 @@ static void do_lasso_select_meta(ViewContext *vc, int mcords[][2], short moves, } } +int do_paintvert_box_select(ViewContext *vc, rcti *rect, int select, int extend) +{ + Mesh *me; + MVert *mvert; + struct ImBuf *ibuf; + unsigned int *rt; + int a, index; + char *selar; + int sx= rect->xmax-rect->xmin+1; + int sy= rect->ymax-rect->ymin+1; + + me= vc->obact->data; + + if(me==NULL || me->totvert==0 || sx*sy <= 0) + return OPERATOR_CANCELLED; + + selar= MEM_callocN(me->totvert+1, "selar"); + + if (extend == 0 && select) + paintvert_deselect_all_visible(vc->obact, SEL_DESELECT, FALSE); + + view3d_validate_backbuf(vc); + + ibuf = IMB_allocImBuf(sx,sy,32,IB_rect); + rt = ibuf->rect; + glReadPixels(rect->xmin+vc->ar->winrct.xmin, rect->ymin+vc->ar->winrct.ymin, sx, sy, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect); + if(ENDIAN_ORDER==B_ENDIAN) IMB_convert_rgba_to_abgr(ibuf); + + a= sx*sy; + while(a--) { + if(*rt) { + index= WM_framebuffer_to_index(*rt); + if(index<=me->totvert) selar[index]= 1; + } + rt++; + } + + mvert= me->mvert; + for(a=1; a<=me->totvert; a++, mvert++) { + if(selar[a]) { + if(mvert->flag & ME_HIDE); + else { + if(select) mvert->flag |= SELECT; + else mvert->flag &= ~SELECT; + } + } + } + + IMB_freeImBuf(ibuf); + MEM_freeN(selar); + +#ifdef __APPLE__ + glReadBuffer(GL_BACK); +#endif + + paintvert_flush_flags(vc->obact); + + return OPERATOR_FINISHED; +} + +static void do_lasso_select_paintvert(ViewContext *vc, int mcords[][2], short moves, short extend, short select) +{ + Object *ob= vc->obact; + Mesh *me= ob?ob->data:NULL; + rcti rect; + + if(me==NULL || me->totvert==0) + return; + + if(extend==0 && select) + paintvert_deselect_all_visible(ob, SEL_DESELECT, FALSE); /* flush selection at the end */ + em_vertoffs= me->totvert+1; /* max index array */ + + lasso_select_boundbox(&rect, mcords, moves); + EM_mask_init_backbuf_border(vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax); + + EM_backbuf_checkAndSelectVerts_obmode(me, select); + + EM_free_backbuf(); + + paintvert_flush_flags(ob); +} static void do_lasso_select_paintface(ViewContext *vc, int mcords[][2], short moves, short extend, short select) { Object *ob= vc->obact; @@ -789,6 +894,8 @@ static void view3d_lasso_select(bContext *C, ViewContext *vc, int mcords[][2], s if(vc->obedit==NULL) { /* Object Mode */ if(paint_facesel_test(ob)) do_lasso_select_paintface(vc, mcords, moves, extend, select); + else if(paint_vertsel_test(ob)) + do_lasso_select_paintvert(vc, mcords, moves, extend, select); else if(ob && ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT)) ; else if(ob && ob->mode & OB_MODE_PARTICLE_EDIT) @@ -1798,6 +1905,9 @@ static int view3d_borderselect_exec(bContext *C, wmOperator *op) else if(vc.obact && paint_facesel_test(vc.obact)) { ret= do_paintface_box_select(&vc, &rect, select, extend); } + else if(vc.obact && paint_vertsel_test(vc.obact)) { + ret= do_paintvert_box_select(&vc, &rect, select, extend); + } else if(vc.obact && vc.obact->mode & OB_MODE_PARTICLE_EDIT) { ret= PE_border_select(C, &rect, select, extend); } @@ -1834,6 +1944,58 @@ void VIEW3D_OT_select_border(wmOperatorType *ot) WM_operator_properties_gesture_border(ot, TRUE); } +/* much like facesel_face_pick()*/ +/* returns 0 if not found, otherwise 1 */ +static int vertsel_vert_pick(struct bContext *C, Mesh *me, const int mval[2], unsigned int *index, short rect) +{ + ViewContext vc; + view3d_set_viewcontext(C, &vc); + + if (!me || me->totvert==0) + return 0; + + if (rect) { + /* sample rect to increase changes of selecting, so that when clicking + on an face in the backbuf, we can still select a vert */ + + int dist; + *index = view3d_sample_backbuf_rect(&vc, mval, 3, 1, me->totvert+1, &dist,0,NULL, NULL); + } + else { + /* sample only on the exact position */ + *index = view3d_sample_backbuf(&vc, mval[0], mval[1]); + } + + if ((*index)<=0 || (*index)>(unsigned int)me->totvert) + return 0; + + (*index)--; + + return 1; +} + +/* mouse selection in weight paint */ +/* gets called via generic mouse select operator */ +static int mouse_weight_paint_vertex_select(bContext *C, const int mval[2], short extend, Object *obact) +{ + Mesh* me= obact->data; /* already checked for NULL */ + unsigned int index = 0; + MVert *mv; + if(vertsel_vert_pick(C, me, mval, &index, 1)) { + mv = me->mvert+index; + if(extend) { + mv->flag ^= SELECT; + } else { + paintvert_deselect_all_visible(obact, SEL_DESELECT, FALSE); + mv->flag |= SELECT; + } + paintvert_flush_flags(obact); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obact->data); + return 1; + } + return 0; +} + /* ****** Mouse Select ****** */ @@ -1878,6 +2040,8 @@ static int view3d_select_invoke(bContext *C, wmOperator *op, wmEvent *event) return PE_mouse_particles(C, event->mval, extend); else if(obact && paint_facesel_test(obact)) retval = paintface_mouse_select(C, obact, event->mval, extend); + else if (paint_vertsel_test(obact)) + retval = mouse_weight_paint_vertex_select(C, event->mval, extend, obact); else retval = mouse_select(C, event->mval, extend, center, enumerate); @@ -1992,18 +2156,36 @@ static void paint_facesel_circle_select(ViewContext *vc, int select, const int m { Object *ob= vc->obact; Mesh *me = ob?ob->data:NULL; - int bbsel; + /* int bbsel; */ /* UNUSED */ if (me) { em_vertoffs= me->totface+1; /* max index array */ - bbsel= EM_init_backbuf_circle(vc, mval[0], mval[1], (short)(rad+1.0f)); + /* bbsel= */ /* UNUSED */ EM_init_backbuf_circle(vc, mval[0], mval[1], (short)(rad+1.0f)); EM_backbuf_checkAndSelectTFaces(me, select==LEFTMOUSE); EM_free_backbuf(); } } +static void paint_vertsel_circle_select(ViewContext *vc, int select, const int mval[2], float rad) +{ + Object *ob= vc->obact; + Mesh *me = ob?ob->data:NULL; + /* int bbsel; */ /* UNUSED */ + /* struct {ViewContext *vc; short select; int mval[2]; float radius; } data = {NULL}; */ /* UNUSED */ + if (me) { + em_vertoffs= me->totvert+1; /* max index array */ + + /* bbsel= */ /* UNUSED */ EM_init_backbuf_circle(vc, mval[0], mval[1], (short)(rad+1.0f)); + EM_backbuf_checkAndSelectVerts_obmode(me, select==LEFTMOUSE); + EM_free_backbuf(); + + paintvert_flush_flags(ob); + } +} + + static void nurbscurve_circle_doSelect(void *userData, Nurb *UNUSED(nu), BPoint *bp, BezTriple *bezt, int beztindex, int x, int y) { struct {ViewContext *vc; short select; int mval[2]; float radius; } *data = userData; @@ -2258,7 +2440,7 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op) select= (gesture_mode==GESTURE_MODAL_SELECT); - if( CTX_data_edit_object(C) || paint_facesel_test(obact) || + if( CTX_data_edit_object(C) || paint_facesel_test(obact) || paint_vertsel_test(obact) || (obact && (obact->mode & (OB_MODE_PARTICLE_EDIT|OB_MODE_POSE))) ) { ViewContext vc; @@ -2278,6 +2460,10 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op) paint_facesel_circle_select(&vc, select, mval, (float)radius); WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obact->data); } + else if(paint_vertsel_test(obact)) { + paint_vertsel_circle_select(&vc, select, mval, (float)radius); + WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obact->data); + } else if(obact->mode & OB_MODE_POSE) pose_circle_select(&vc, select, mval, (float)radius); else diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index 45d832d4739..8227ba87021 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -1667,7 +1667,7 @@ static void RestoreState(bContext *C, wmWindow *win) win->queue= queue_back; GPU_state_init(); - GPU_set_tpage(NULL, 0); + GPU_set_tpage(NULL, 0, 0); glPopAttrib(); } diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index c8b95727304..f6b4f32adef 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -4260,7 +4260,6 @@ static int createSlideVerts(TransInfo *t) LinkNode *edgelist = NULL, *vertlist=NULL, *look; GHash *vertgh; TransDataSlideVert *tempsv; - float vertdist; // XXX, projectMat[4][4]; int i, j, numsel, numadded=0, timesthrough = 0, vertsel=0; /* UV correction vars */ GHash **uvarray= NULL; @@ -4525,7 +4524,6 @@ static int createSlideVerts(TransInfo *t) look = vertlist; nearest = NULL; - vertdist = -1; while(look) { tempsv = BLI_ghash_lookup(vertgh,(EditVert*)look->link); @@ -5563,7 +5561,7 @@ static void applyTimeTranslate(TransInfo *t, float UNUSED(sval)) const short autosnap= getAnimEdit_SnapMode(t); - float deltax, val, valprev; + float deltax, val /* , valprev */; /* it doesn't matter whether we apply to t->data or t->data2d, but t->data2d is more convenient */ for (i = 0 ; i < t->total; i++, td++, td2d++) { @@ -5573,7 +5571,7 @@ static void applyTimeTranslate(TransInfo *t, float UNUSED(sval)) */ AnimData *adt= (t->spacetype != SPACE_NLA) ? td->extra : NULL; - valprev = *td->val; + /* valprev = *td->val; */ /* UNUSED */ /* check if any need to apply nla-mapping */ if (adt && t->spacetype != SPACE_SEQ) { diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index d76e5c8a88a..77d2e6e7ff0 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -1983,7 +1983,7 @@ static void createTransEditVerts(bContext *C, TransInfo *t) float *mappedcos = NULL, *quats= NULL; float mtx[3][3], smtx[3][3], (*defmats)[3][3] = NULL, (*defcos)[3] = NULL; int count=0, countsel=0, a, totleft; - int propmode = t->flag & T_PROP_EDIT; + int propmode = (t->flag & T_PROP_EDIT) ? (t->flag & (T_PROP_EDIT | T_PROP_CONNECTED)) : 0; int mirror = 0; short selectmode = ts->selectmode; @@ -2053,7 +2053,9 @@ static void createTransEditVerts(bContext *C, TransInfo *t) copy_m3_m4(mtx, t->obedit->obmat); invert_m3_m3(smtx, mtx); - if(propmode) editmesh_set_connectivity_distance(em, mtx); + if(propmode & T_PROP_CONNECTED) { + editmesh_set_connectivity_distance(em, mtx); + } /* detect CrazySpace [tm] */ if(modifiers_getCageIndex(t->scene, t->obedit, NULL, 1)>=0) { @@ -3406,7 +3408,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t) const char sel3= use_handle ? bezt->f3 & SELECT : 0; TransDataCurveHandleFlags *hdata = NULL; - short h1=1, h2=1; + /* short h1=1, h2=1; */ /* UNUSED */ /* only include handles if selected, irrespective of the interpolation modes. * also, only treat handles specially if the center point isn't selected. @@ -3416,16 +3418,18 @@ static void createTransGraphEditData(bContext *C, TransInfo *t) hdata = initTransDataCurveHandles(td, bezt); bezt_to_transdata(td++, td2d++, adt, bezt, 0, 1, 1, intvals, mtx, smtx); } - else - h1= 0; + else { + /* h1= 0; */ /* UNUSED */ + } if (sel3) { if (hdata==NULL) hdata = initTransDataCurveHandles(td, bezt); bezt_to_transdata(td++, td2d++, adt, bezt, 2, 1, 1, intvals, mtx, smtx); } - else - h2= 0; + else { + /* h2= 0; */ /* UNUSED */ + } } /* only include main vert if selected */ diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c index 3b895f5fbd0..36373562956 100644 --- a/source/blender/editors/transform/transform_manipulator.c +++ b/source/blender/editors/transform/transform_manipulator.c @@ -446,13 +446,13 @@ int calc_manipulator_stats(const bContext *C) } else if(obedit->type==OB_MBALL) { MetaBall *mb = (MetaBall*)obedit->data; - MetaElem *ml, *ml_sel=NULL; + MetaElem *ml /* , *ml_sel=NULL */ /* UNUSED */; ml= mb->editelems->first; while(ml) { if(ml->flag & SELECT) { calc_tw_center(scene, &ml->x); - ml_sel = ml; + /* ml_sel = ml; */ /* UNUSED */ totsel++; } ml= ml->next; diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index 3489bf41143..d6e8e4aa695 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -795,7 +795,7 @@ void TRANSFORM_OT_seq_slide(struct wmOperatorType *ot) ot->cancel = transform_cancel; ot->poll = ED_operator_sequencer_active; - RNA_def_float_vector(ot->srna, "value", 2, VecOne, -FLT_MAX, FLT_MAX, "angle", "", -FLT_MAX, FLT_MAX); + RNA_def_float_vector(ot->srna, "value", 2, VecOne, -FLT_MAX, FLT_MAX, "Angle", "", -FLT_MAX, FLT_MAX); Transform_Properties(ot, P_SNAP); } diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 9a21305457c..61b3a9ca1ca 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -125,14 +125,12 @@ void ED_uvedit_assign_image(Scene *scene, Object *obedit, Image *ima, Image *pre if(uvedit_face_visible(scene, previma, efa, tf)) { if(ima) { tf->tpage= ima; - tf->mode |= TF_TEX; if(ima->id.us==0) id_us_plus(&ima->id); else id_lib_extern(&ima->id); } else { tf->tpage= NULL; - tf->mode &= ~TF_TEX; } update = 1; @@ -2519,7 +2517,7 @@ static void UV_OT_snap_cursor(wmOperatorType *ot) ot->poll= ED_operator_image_active; /* requires space image */; /* properties */ - RNA_def_enum(ot->srna, "target", target_items, 0, "Target", "Target to snap the selected UV's to"); + RNA_def_enum(ot->srna, "target", target_items, 0, "Target", "Target to snap the selected UVs to"); } /* ******************** snap selection operator **************** */ @@ -2761,7 +2759,7 @@ static void UV_OT_snap_selected(wmOperatorType *ot) ot->poll= ED_operator_image_active; /* requires space image */; /* properties */ - RNA_def_enum(ot->srna, "target", target_items, 0, "Target", "Target to snap the selected UV's to"); + RNA_def_enum(ot->srna, "target", target_items, 0, "Target", "Target to snap the selected UVs to"); } /* ******************** pin operator **************** */ diff --git a/source/blender/gpu/GPU_draw.h b/source/blender/gpu/GPU_draw.h index d75b8db2c4e..55c4ff85a57 100644 --- a/source/blender/gpu/GPU_draw.h +++ b/source/blender/gpu/GPU_draw.h @@ -80,15 +80,15 @@ void GPU_end_object_materials(void); int GPU_enable_material(int nr, void *attribs); void GPU_disable_material(void); -void GPU_set_material_blend_mode(int blendmode); -int GPU_get_material_blend_mode(void); +void GPU_set_material_alpha_blend(int alphablend); +int GPU_get_material_alpha_blend(void); /* TexFace drawing * - this is mutually exclusive with material drawing, a mesh should * be drawn using one or the other * - passing NULL clears the state again */ -int GPU_set_tpage(struct MTFace *tface, int mipmap); +int GPU_set_tpage(struct MTFace *tface, int mipmap, int transp); /* Lights * - returns how many lights were enabled diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index 95a08e6d5b3..29ad9c91374 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -94,7 +94,8 @@ typedef enum GPUBlendMode { GPU_BLEND_SOLID = 0, GPU_BLEND_ADD = 1, GPU_BLEND_ALPHA = 2, - GPU_BLEND_CLIP = 4 + GPU_BLEND_CLIP = 4, + GPU_BLEND_ALPHA_SORT = 8 } GPUBlendMode; typedef struct GPUNodeStack { @@ -121,7 +122,7 @@ int GPU_stack_link(GPUMaterial *mat, const char *name, GPUNodeStack *in, GPUNode void GPU_material_output_link(GPUMaterial *material, GPUNodeLink *link); void GPU_material_enable_alpha(GPUMaterial *material); -GPUBlendMode GPU_material_blend_mode(GPUMaterial *material, float obcol[4]); +GPUBlendMode GPU_material_alpha_blend(GPUMaterial *material, float obcol[4]); /* High level functions to create and use GPU materials */ diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index 7af5ef6ea14..4f79d577ae5 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -95,7 +95,7 @@ void GPU_render_text(MTFace *tface, int mode, const char *textstr, int textlen, unsigned int *col, float *v1, float *v2, float *v3, float *v4, int glattrib) { - if ((mode & TF_BMFONT) && (textlen>0) && tface->tpage) { + if ((mode & GEMAT_TEXT) && (textlen>0) && tface->tpage) { Image* ima = (Image*)tface->tpage; int index, character; float centerx, centery, sizex, sizey, transx, transy, movex, movey, advance; @@ -245,7 +245,7 @@ static struct GPUTextureState { int domipmap, linearmipmap; - int alphamode; + int alphablend; float anisotropic; MTFace *lasttface; } GTS = {0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, 1, 0, -1, 1.f, NULL}; @@ -352,7 +352,7 @@ static void gpu_clear_tpage(void) GTS.curtilemode= 0; GTS.curtileXRep=0; GTS.curtileYRep=0; - GTS.alphamode= -1; + GTS.alphablend= -1; glDisable(GL_BLEND); glDisable(GL_TEXTURE_2D); @@ -361,19 +361,19 @@ static void gpu_clear_tpage(void) glDisable(GL_ALPHA_TEST); } -static void gpu_set_blend_mode(GPUBlendMode blendmode) +static void gpu_set_alpha_blend(GPUBlendMode alphablend) { - if(blendmode == GPU_BLEND_SOLID) { + if(alphablend == GPU_BLEND_SOLID) { glDisable(GL_BLEND); glDisable(GL_ALPHA_TEST); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } - else if(blendmode==GPU_BLEND_ADD) { + else if(alphablend==GPU_BLEND_ADD) { glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); glDisable(GL_ALPHA_TEST); } - else if(blendmode==GPU_BLEND_ALPHA) { + else if(ELEM(alphablend, GPU_BLEND_ALPHA, GPU_BLEND_ALPHA_SORT)) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -389,21 +389,21 @@ static void gpu_set_blend_mode(GPUBlendMode blendmode) glAlphaFunc(GL_GREATER, U.glalphaclip); } } - else if(blendmode==GPU_BLEND_CLIP) { + else if(alphablend==GPU_BLEND_CLIP) { glDisable(GL_BLEND); glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GREATER, 0.5f); } } -static void gpu_verify_alpha_mode(MTFace *tface) +static void gpu_verify_alpha_blend(int alphablend) { /* verify alpha blending modes */ - if(GTS.alphamode == tface->transp) + if(GTS.alphablend == alphablend) return; - gpu_set_blend_mode(tface->transp); - GTS.alphamode= tface->transp; + gpu_set_alpha_blend(alphablend); + GTS.alphablend= alphablend; } static void gpu_verify_reflection(Image *ima) @@ -608,7 +608,7 @@ static void gpu_verify_repeat(Image *ima) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); } -int GPU_set_tpage(MTFace *tface, int mipmap) +int GPU_set_tpage(MTFace *tface, int mipmap, int alphablend) { Image *ima; @@ -621,7 +621,7 @@ int GPU_set_tpage(MTFace *tface, int mipmap) ima= tface->tpage; GTS.lasttface= tface; - gpu_verify_alpha_mode(tface); + gpu_verify_alpha_blend(alphablend); gpu_verify_reflection(ima); if(GPU_verify_image(ima, NULL, tface->tile, 1, mipmap)) { @@ -945,12 +945,12 @@ static struct GPUMaterialState { float (*gviewmat)[4]; float (*gviewinv)[4]; - GPUBlendMode *blendmode; - GPUBlendMode blendmode_fixed[FIXEDMAT]; + GPUBlendMode *alphablend; + GPUBlendMode alphablend_fixed[FIXEDMAT]; int alphapass; int lastmatnr, lastretval; - GPUBlendMode lastblendmode; + GPUBlendMode lastalphablend; } GMS = {NULL}; /* fixed function material, alpha handed by caller */ @@ -1000,7 +1000,7 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O { Material *ma; GPUMaterial *gpumat; - GPUBlendMode blendmode; + GPUBlendMode alphablend; int a; int gamma = scene->r.color_mgt_flag & R_COLOR_MANAGEMENT; @@ -1008,7 +1008,7 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O memset(&GMS, 0, sizeof(GMS)); GMS.lastmatnr = -1; GMS.lastretval = -1; - GMS.lastblendmode = GPU_BLEND_SOLID; + GMS.lastalphablend = GPU_BLEND_SOLID; GMS.gob = ob; GMS.gscene = scene; @@ -1024,12 +1024,12 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O if(GMS.totmat > FIXEDMAT) { GMS.matbuf= MEM_callocN(sizeof(GPUMaterialFixed)*GMS.totmat, "GMS.matbuf"); GMS.gmatbuf= MEM_callocN(sizeof(*GMS.gmatbuf)*GMS.totmat, "GMS.matbuf"); - GMS.blendmode= MEM_callocN(sizeof(*GMS.blendmode)*GMS.totmat, "GMS.matbuf"); + GMS.alphablend= MEM_callocN(sizeof(*GMS.alphablend)*GMS.totmat, "GMS.matbuf"); } else { GMS.matbuf= GMS.matbuf_fixed; GMS.gmatbuf= GMS.gmatbuf_fixed; - GMS.blendmode= GMS.blendmode_fixed; + GMS.alphablend= GMS.alphablend_fixed; } /* no materials assigned? */ @@ -1044,7 +1044,7 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O GPU_material_from_blender(GMS.gscene, &defmaterial); } - GMS.blendmode[0]= GPU_BLEND_SOLID; + GMS.alphablend[0]= GPU_BLEND_SOLID; } /* setup materials */ @@ -1060,13 +1060,13 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O if(gpumat) { /* do glsl only if creating it succeed, else fallback */ GMS.gmatbuf[a]= ma; - blendmode = GPU_material_blend_mode(gpumat, ob->col); + alphablend = GPU_material_alpha_blend(gpumat, ob->col); } else { /* fixed function opengl materials */ gpu_material_to_fixed(&GMS.matbuf[a], ma, gamma, ob); - blendmode = (ma->alpha == 1.0f)? GPU_BLEND_SOLID: GPU_BLEND_ALPHA; + alphablend = (ma->alpha == 1.0f)? GPU_BLEND_SOLID: GPU_BLEND_ALPHA; if(do_alpha_pass && GMS.alphapass) GMS.matbuf[a].diff[3]= ma->alpha; else @@ -1076,8 +1076,8 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O /* setting do_alpha_pass = 1 indicates this object needs to be * drawn in a second alpha pass for improved blending */ if(do_alpha_pass) { - GMS.blendmode[a]= blendmode; - if(ELEM(blendmode, GPU_BLEND_ALPHA, GPU_BLEND_ADD) && !GMS.alphapass) + GMS.alphablend[a]= alphablend; + if(ELEM3(alphablend, GPU_BLEND_ALPHA, GPU_BLEND_ADD, GPU_BLEND_ALPHA_SORT) && !GMS.alphapass) *do_alpha_pass= 1; } } @@ -1090,7 +1090,7 @@ int GPU_enable_material(int nr, void *attribs) { GPUVertexAttribs *gattribs = attribs; GPUMaterial *gpumat; - GPUBlendMode blendmode; + GPUBlendMode alphablend; /* no GPU_begin_object_materials, use default material */ if(!GMS.matbuf) { @@ -1131,7 +1131,7 @@ int GPU_enable_material(int nr, void *attribs) /* draw materials with alpha in alpha pass */ GMS.lastmatnr = nr; - GMS.lastretval = ELEM(GMS.blendmode[nr], GPU_BLEND_SOLID, GPU_BLEND_CLIP); + GMS.lastretval = ELEM(GMS.alphablend[nr], GPU_BLEND_SOLID, GPU_BLEND_CLIP); if(GMS.alphapass) GMS.lastretval = !GMS.lastretval; @@ -1145,6 +1145,7 @@ int GPU_enable_material(int nr, void *attribs) GPU_material_bind(gpumat, GMS.gob->lay, GMS.glay, 1.0, !(GMS.gob->mode & OB_MODE_TEXTURE_PAINT)); GPU_material_bind_uniforms(gpumat, GMS.gob->obmat, GMS.gviewmat, GMS.gviewinv, GMS.gob->col); GMS.gboundmat= mat; + alphablend= mat->game.alpha_blend; if(GMS.alphapass) glDepthMask(1); } @@ -1153,28 +1154,29 @@ int GPU_enable_material(int nr, void *attribs) glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, GMS.matbuf[nr].diff); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, GMS.matbuf[nr].spec); glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, GMS.matbuf[nr].hard); + alphablend= GPU_BLEND_SOLID; } /* set (alpha) blending mode */ - blendmode = (GMS.alphapass)? GPU_BLEND_ALPHA: GPU_BLEND_SOLID; - GPU_set_material_blend_mode(blendmode); + if(!GMS.alphapass) alphablend= GPU_BLEND_SOLID; + GPU_set_material_alpha_blend(alphablend); } return GMS.lastretval; } -void GPU_set_material_blend_mode(int blendmode) +void GPU_set_material_alpha_blend(int alphablend) { - if(GMS.lastblendmode == blendmode) + if(GMS.lastalphablend == alphablend) return; - gpu_set_blend_mode(blendmode); - GMS.lastblendmode = blendmode; + gpu_set_alpha_blend(alphablend); + GMS.lastalphablend = alphablend; } -int GPU_get_material_blend_mode(void) +int GPU_get_material_alpha_blend(void) { - return GMS.lastblendmode; + return GMS.lastalphablend; } void GPU_disable_material(void) @@ -1188,7 +1190,7 @@ void GPU_disable_material(void) GMS.gboundmat= NULL; } - GPU_set_material_blend_mode(GPU_BLEND_SOLID); + GPU_set_material_alpha_blend(GPU_BLEND_SOLID); } void GPU_end_object_materials(void) @@ -1198,12 +1200,12 @@ void GPU_end_object_materials(void) if(GMS.matbuf && GMS.matbuf != GMS.matbuf_fixed) { MEM_freeN(GMS.matbuf); MEM_freeN(GMS.gmatbuf); - MEM_freeN(GMS.blendmode); + MEM_freeN(GMS.alphablend); } GMS.matbuf= NULL; GMS.gmatbuf= NULL; - GMS.blendmode= NULL; + GMS.alphablend= NULL; /* resetting the texture matrix after the glScale needed for tiled textures */ if(GTS.tilemode) diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index 9aa453af4d6..40186c5a187 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -358,7 +358,7 @@ void GPU_material_enable_alpha(GPUMaterial *material) material->alpha= 1; } -GPUBlendMode GPU_material_blend_mode(GPUMaterial *material, float obcol[4]) +GPUBlendMode GPU_material_alpha_blend(GPUMaterial *material, float obcol[4]) { if(material->alpha || (material->obcolalpha && obcol[3] < 1.0f)) return GPU_BLEND_ALPHA; diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h index 060b1bf42d1..6719dc8d9af 100644 --- a/source/blender/makesdna/DNA_material_types.h +++ b/source/blender/makesdna/DNA_material_types.h @@ -74,6 +74,14 @@ typedef struct VolumeSettings { float ms_spread; } VolumeSettings; +/* Game Engine Options (old Texface mode, transp and flag) */ +typedef struct GameSettings { + int flag; + int alpha_blend; + int face_orientation; + int pad1; +} GameSettings; + typedef struct Material { ID id; struct AnimData *adt; /* animation data (must be immediately after id for utilities to use it) */ @@ -90,6 +98,7 @@ typedef struct Material { /* end synced with render_types.h */ struct VolumeSettings vol; + struct GameSettings game; float fresnel_mir, fresnel_mir_i; float fresnel_tra, fresnel_tra_i; @@ -166,12 +175,39 @@ typedef struct Material { ListBase gpumaterial; /* runtime */ } Material; + +/* **************** GAME PROPERTIES ********************* */ +// Blend Transparency Options - alpha_blend /* match GPU_material::GPUBlendMode */ +#define GEMAT_SOLID 0 /* GPU_BLEND_SOLID */ +#define GEMAT_ADD 1 /* GPU_BLEND_ADD */ +#define GEMAT_ALPHA 2 /* GPU_BLEND_ALPHA */ +#define GEMAT_CLIP 4 /* GPU_BLEND_CLIP */ +#define GEMAT_ALPHA_SORT 8 /* GPU_BLEND_ALPHA_SORT */ + +// Game Options - flag +#define GEMAT_BACKCULL 16 /* KX_BACKCULL */ +#define GEMAT_SHADED 32 /* KX_LIGHT */ +#define GEMAT_TEXT 64 /* RAS_RENDER_3DPOLYGON_TEXT */ +#define GEMAT_NOPHYSICS 128 +#define GEMAT_INVISIBLE 256 + +// Face Orientation Options - face_orientation +#define GEMAT_NORMAL 0 +#define GEMAT_HALO 512 /* BILLBOARD_SCREENALIGNED */ +#define GEMAT_BILLBOARD 1024 /* BILLBOARD_AXISALIGNED */ +#define GEMAT_SHADOW 2048 /* SHADOW */ + +// Use Textures - not defined directly in the UI +#define GEMAT_TEX 4096 /* KX_TEX */ + + /* **************** MATERIAL ********************* */ /* maximum number of materials per material array. * (on object, mesh, lamp, etc.). limited by - * short mat_nr in verts, faces. */ -#define MAXMAT 32767 + * short mat_nr in verts, faces. + * -1 becayse for active material we store the index + 1 */ +#define MAXMAT (32767-1) /* material_type */ #define MA_TYPE_SURFACE 0 diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h index 6ad60ac2df9..25bb4958c97 100644 --- a/source/blender/makesdna/DNA_mesh_types.h +++ b/source/blender/makesdna/DNA_mesh_types.h @@ -125,7 +125,7 @@ typedef struct TFace { #define ME_EDIT_PAINT_MASK (1 << 3) #define ME_EDIT_MIRROR_TOPO (1 << 4) - +#define ME_EDIT_VERT_SEL (1 << 5) /* me->flag */ /* #define ME_ISDONE 1 */ diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h index 61c4a660992..9d7375b6755 100644 --- a/source/blender/makesdna/DNA_meshdata_types.h +++ b/source/blender/makesdna/DNA_meshdata_types.h @@ -247,6 +247,8 @@ typedef struct MRecast{ #define TF_SHAREDVERT 8 #define TF_LIGHT 16 +#define TF_CONVERTED 32 /* tface converted to material */ + #define TF_SHAREDCOL 64 #define TF_TILES 128 /* deprecated */ #define TF_BILLBOARD 256 diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 8750ee9e906..f32f8d626de 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -62,9 +62,14 @@ struct bGPdata; typedef struct bDeformGroup { struct bDeformGroup *next, *prev; char name[32]; + /* need this flag for locking weights */ + char flag, pad[7]; } bDeformGroup; #define MAX_VGROUP_NAME 32 +/* bDeformGroup->flag */ +#define DG_LOCK_WEIGHT 1 + /** * The following illustrates the orientation of the * bounding box in local space diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 5f20432d6f8..9f176a22848 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -759,9 +759,10 @@ typedef struct ToolSettings { short snap_flag, snap_target; short proportional, prop_mode; char proportional_objects; /* proportional edit, object mode */ - char pad[3]; + char pad[5]; - int auto_normalize; /*auto normalizing mode in wpaint*/ + char auto_normalize; /*auto normalizing mode in wpaint*/ + char multipaint; /* paint multiple bones in wpaint */ short sculpt_paint_settings; /* user preferences for sculpt and paint */ short pad1; diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c index 99473d13daa..5d0c1db572d 100644 --- a/source/blender/makesrna/intern/rna_curve.c +++ b/source/blender/makesrna/intern/rna_curve.c @@ -296,7 +296,8 @@ static EnumPropertyItem *rna_Curve_fill_mode_itemf(bContext *UNUSED(C), PointerR { Curve *cu= (Curve*)ptr->id.data; - return (cu->flag&CU_3D) ? curve3d_fill_mode_items : curve2d_fill_mode_items; + /* cast to quiet warning it IS a const still */ + return (EnumPropertyItem *)((cu->flag & CU_3D) ? curve3d_fill_mode_items : curve2d_fill_mode_items); } static int rna_Nurb_length(PointerRNA *ptr) diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index dcaeb523df5..673e768e71e 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -742,6 +742,61 @@ static void rna_def_material_mtex(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_Material_update"); } +static void rna_def_material_gamesettings(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + static EnumPropertyItem prop_alpha_blend_items[] = { + {GEMAT_SOLID, "OPAQUE", 0, "Opaque", "Render color of textured face as color"}, + {GEMAT_ADD, "ADD", 0, "Add", "Render face transparent and add color of face"}, + {GEMAT_CLIP, "CLIP", 0, "Alpha Clip", "Use the image alpha values clipped with no blending (binary alpha)"}, + {GEMAT_ALPHA, "ALPHA", 0, "Alpha Blend", "Render polygon transparent, depending on alpha channel of the texture"}, + {GEMAT_ALPHA_SORT, "ALPHA_SORT", 0, "Alpha Sort", "Sort faces for correct alpha drawing (slow, use Alpha Clip instead when possible)"}, + {0, NULL, 0, NULL, NULL}}; + + static EnumPropertyItem prop_face_orientation_items[] = { + {GEMAT_NORMAL,"NORMAL",0,"Normal","No tranformation"}, + {GEMAT_HALO, "HALO", 0, "Halo", "Screen aligned billboard"}, + {GEMAT_BILLBOARD, "BILLBOARD", 0, "Billboard", "Billboard with Z-axis constraint"}, + {GEMAT_SHADOW, "SHADOW", 0, "Shadow", "Faces are used for shadow"}, + {0, NULL, 0, NULL, NULL}}; + + srna= RNA_def_struct(brna, "MaterialGameSettings", NULL); + RNA_def_struct_sdna(srna, "GameSettings"); + RNA_def_struct_nested(brna, srna, "Material"); + RNA_def_struct_ui_text(srna, "Material Game Settings", "Game Engine settings for a Material datablock"); + + prop= RNA_def_property(srna, "back_culling", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GEMAT_BACKCULL); /* use bitflags */ + RNA_def_property_ui_text(prop, "Back Culling", "Hide Back of the face in Game Engine "); + RNA_def_property_update(prop, 0, "rna_Material_draw_update"); + + prop= RNA_def_property(srna, "text", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GEMAT_TEXT); /* use bitflags */ + RNA_def_property_ui_text(prop, "Text", "Use material as text in Game Engine "); + RNA_def_property_update(prop, 0, "rna_Material_draw_update"); + + prop= RNA_def_property(srna, "invisible", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GEMAT_INVISIBLE); /* use bitflags */ + RNA_def_property_ui_text(prop, "Invisible", "Make face invisible"); + RNA_def_property_update(prop, 0, "rna_Material_draw_update"); + + prop= RNA_def_property(srna, "alpha_blend", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "alpha_blend"); + RNA_def_property_enum_items(prop, prop_alpha_blend_items); + RNA_def_property_ui_text(prop, "Blend Mode", "Blend Mode for Transparent Faces"); + RNA_def_property_update(prop, 0, "rna_Material_draw_update"); + + prop= RNA_def_property(srna, "face_orientation", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, prop_face_orientation_items); + RNA_def_property_ui_text(prop, "Face Orientations", "Especial face orientation options"); + + prop= RNA_def_property(srna, "physics", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", GEMAT_NOPHYSICS); /* use bitflags */ + RNA_def_property_ui_text(prop, "Physics", "Use physics properties of materials "); +} + static void rna_def_material_colors(StructRNA *srna) { PropertyRNA *prop; @@ -1887,6 +1942,13 @@ void RNA_def_material(BlenderRNA *brna) RNA_def_property_pointer_funcs(prop, "rna_Material_physics_get", NULL, NULL, NULL); RNA_def_property_ui_text(prop, "Physics", "Game physics settings"); + /* game settings */ + prop= RNA_def_property(srna, "game_settings", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_NEVER_NULL); + RNA_def_property_pointer_sdna(prop, NULL, "game"); + RNA_def_property_struct_type(prop, "MaterialGameSettings"); + RNA_def_property_ui_text(prop, "Game Settings", "Game material settings"); + /* nodetree */ prop= RNA_def_property(srna, "node_tree", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "nodetree"); @@ -1932,6 +1994,7 @@ void RNA_def_material(BlenderRNA *brna) rna_def_material_mtex(brna); rna_def_material_strand(brna); rna_def_material_physics(brna); + rna_def_material_gamesettings(brna); RNA_api_material(srna); } diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index a560b54a87a..1bbdc7cc853 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -90,6 +90,24 @@ void rna_Mesh_update_draw(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA } } + +void rna_Mesh_update_vertmask(Main *bmain, Scene *scene, PointerRNA *ptr) +{ + Mesh* me = ptr->data; + if ((me->editflag & ME_EDIT_VERT_SEL) && (me->editflag & ME_EDIT_PAINT_MASK)) { + me->editflag ^= ME_EDIT_PAINT_MASK; + } + rna_Mesh_update_draw(bmain, scene, ptr); +} + +void rna_Mesh_update_facemask(Main *bmain, Scene *scene, PointerRNA *ptr) +{ + Mesh* me = ptr->data; + if ((me->editflag & ME_EDIT_VERT_SEL) && (me->editflag & ME_EDIT_PAINT_MASK)) { + me->editflag ^= ME_EDIT_VERT_SEL; + } + rna_Mesh_update_draw(bmain, scene, ptr); +} static void rna_MeshVertex_normal_get(PointerRNA *ptr, float *value) { MVert *mvert= (MVert*)ptr->data; @@ -1402,6 +1420,9 @@ static void rna_def_mtface(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Image", ""); RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); + //XXX to be deleted soon -- left for now in case we need it for debug + //XXX it should be out before Blender 2.6 (after texface to material patch) + prop= RNA_def_property(srna, "use_image", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", TF_TEX); RNA_def_property_ui_text(prop, "Tex", "Render face with texture"); @@ -1468,6 +1489,9 @@ static void rna_def_mtface(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Transparency", "Transparency blending mode"); RNA_def_property_update(prop, 0, "rna_Mesh_update_data"); + //XXX to be deleted soon -- left for now in case we need it for debug + //XXX it should be out before Blender 2.6 (after texface to material patch) + prop= RNA_def_property(srna, "select_uv", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", TF_SEL1); RNA_def_property_array(prop, 4); @@ -2075,8 +2099,14 @@ static void rna_def_mesh(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "editflag", ME_EDIT_PAINT_MASK); RNA_def_property_ui_text(prop, "Paint Mask", "Face selection masking for painting"); RNA_def_property_ui_icon(prop, ICON_FACESEL_HLT, 0); - RNA_def_property_update(prop, 0, "rna_Mesh_update_draw"); + RNA_def_property_update(prop, 0, "rna_Mesh_update_facemask"); + + prop= RNA_def_property(srna, "use_paint_mask_vertex", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "editflag", ME_EDIT_VERT_SEL); + RNA_def_property_ui_text(prop, "Vertex Selection", "Vertex selection masking for painting (weight paint only)"); + RNA_def_property_ui_icon(prop, ICON_VERTEXSEL, 0); + RNA_def_property_update(prop, 0, "rna_Mesh_update_vertmask"); /* readonly editmesh info - use for extrude menu */ prop= RNA_def_property(srna, "total_vert_sel", PROP_INT, PROP_UNSIGNED); diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 80092b716c2..1b113620663 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -391,6 +391,7 @@ static void rna_NodeGroupSocket_update(Main *bmain, Scene *scene, PointerRNA *pt node_update(bmain, scene, ntree, node); } +#if 0 /* UNUSED */ static void rna_NodeLink_update(Main *bmain, Scene *scene, PointerRNA *ptr) { bNodeTree *ntree= (bNodeTree*)ptr->id.data; @@ -398,6 +399,7 @@ static void rna_NodeLink_update(Main *bmain, Scene *scene, PointerRNA *ptr) ntree->update |= NTREE_UPDATE_LINKS; ntreeUpdateTree(ntree); } +#endif static void rna_NodeSocketInt_range(PointerRNA *ptr, int *min, int *max) { diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index 4f5aa2cc8b0..720fea682ce 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -1265,6 +1265,11 @@ static void rna_def_vertex_group(BlenderRNA *brna) RNA_def_struct_name_property(srna, prop); RNA_def_property_string_funcs(prop, NULL, NULL, "rna_VertexGroup_name_set"); RNA_def_property_update(prop, NC_GEOM|ND_DATA|NA_RENAME, "rna_Object_internal_update_data"); /* update data because modifiers may use [#24761] */ + + prop= RNA_def_property(srna, "lock_weight", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_ui_text(prop, "", "Maintain the relative weights for the group"); + RNA_def_property_boolean_sdna(prop, NULL, "flag", 0); + RNA_def_property_update(prop, NC_GEOM|ND_DATA|NA_RENAME, "rna_Object_internal_update_data"); /* update data because modifiers may use [#24761] */ prop= RNA_def_property(srna, "index", PROP_INT, PROP_UNSIGNED); RNA_def_property_clear_flag(prop, PROP_EDITABLE); diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 49ca8b2c03c..774e21297da 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -1044,6 +1044,22 @@ static KeyingSet *rna_Scene_keying_set_new(Scene *sce, ReportList *reports, cons } } + + +/* note: without this, when Multi-Paint is activated/deactivated, the colors + * will not change right away when multiple bones are selected, this function + * is not for general use and only for the few cases where changing scene + * settings and NOT for general purpose updates, possibly this should be + * given its own notifier. */ +static void rna_Scene_update_active_object_data(Main *bmain, Scene *scene, PointerRNA *ptr) +{ + Object *ob= OBACT; + if(ob) { + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + WM_main_add_notifier(NC_OBJECT|ND_DRAW, &ob->id); + } +} + #else static void rna_def_transform_orientation(BlenderRNA *brna) @@ -1117,9 +1133,17 @@ static void rna_def_tool_settings(BlenderRNA *brna) prop = RNA_def_property(srna, "use_auto_normalize", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "auto_normalize", 1); - RNA_def_property_ui_text(prop, "WPaint Auto-Normalize", - "Ensure all bone-deforming vertex groups add up to 1.0 while " - "weight painting"); + RNA_def_property_ui_text(prop, "WPaint Auto-Normalize", + "Ensure all bone-deforming vertex groups add up " + "to 1.0 while weight painting"); + RNA_def_property_update(prop, 0, "rna_Scene_update_active_object_data"); + + prop = RNA_def_property(srna, "use_multipaint", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "multipaint", 1); + RNA_def_property_ui_text(prop, "WPaint Multi-Paint", + "Paint across all selected bones while " + "weight painting"); + RNA_def_property_update(prop, 0, "rna_Scene_update_active_object_data"); prop= RNA_def_property(srna, "vertex_paint", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "vpaint"); @@ -1804,7 +1828,7 @@ static void rna_def_scene_game_data(BlenderRNA *brna) {0, NULL, 0, NULL, NULL}}; static EnumPropertyItem material_items[] ={ - {GAME_MAT_TEXFACE, "TEXTURE_FACE", 0, "Texture Face", "Single texture face materials"}, + {GAME_MAT_TEXFACE, "SINGLETEXTURE", 0, "Singletexture", "Singletexture face materials"}, {GAME_MAT_MULTITEX, "MULTITEXTURE", 0, "Multitexture", "Multitexture materials"}, {GAME_MAT_GLSL, "GLSL", 0, "GLSL", "OpenGL shading language shaders"}, {0, NULL, 0, NULL, NULL}}; diff --git a/source/blender/modifiers/intern/MOD_uvproject.c b/source/blender/modifiers/intern/MOD_uvproject.c index 912c14adfdd..0c343332736 100644 --- a/source/blender/modifiers/intern/MOD_uvproject.c +++ b/source/blender/modifiers/intern/MOD_uvproject.c @@ -369,7 +369,6 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd, } if(override_image) { - tface->mode = TF_TEX; tface->tpage = image; } } diff --git a/source/blender/nodes/composite/node_composite_util.h b/source/blender/nodes/composite/node_composite_util.h index 57ebe2191dd..f3e0f811f13 100644 --- a/source/blender/nodes/composite/node_composite_util.h +++ b/source/blender/nodes/composite/node_composite_util.h @@ -79,6 +79,10 @@ #include "RE_shader_ext.h" #include "RE_render_ext.h" +/* only for forward declarations */ +#include "NOD_composite.h" + + /* *************************** operations support *************************** */ /* general signal that's in output sockets, and goes over the wires */ diff --git a/source/blender/nodes/composite/nodes/node_composite_colorSpill.c b/source/blender/nodes/composite/nodes/node_composite_colorSpill.c index 418d6802cec..cc55569e566 100644 --- a/source/blender/nodes/composite/nodes/node_composite_colorSpill.c +++ b/source/blender/nodes/composite/nodes/node_composite_colorSpill.c @@ -192,7 +192,7 @@ static void node_composit_exec_color_spill(void *UNUSED(data), bNode *node, bNod /* Originally based on the information from the book "The Art and Science of Digital Composition" and * discussions from vfxtalk.com .*/ CompBuf *cbuf; - CompBuf *mask; + /* CompBuf *mask; */ /* UNUSED */ CompBuf *rgbbuf; CompBuf *spillmap; NodeColorspill *ncs; @@ -204,7 +204,7 @@ static void node_composit_exec_color_spill(void *UNUSED(data), bNode *node, bNod if(in[0]->data==NULL) return; cbuf=typecheck_compbuf(in[0]->data, CB_RGBA); - mask=typecheck_compbuf(in[1]->data, CB_VAL); + /* mask= */ /* UNUSED */ typecheck_compbuf(in[1]->data, CB_VAL); spillmap=alloc_compbuf(cbuf->x, cbuf->y, CB_VAL, 1); rgbbuf=dupalloc_compbuf(cbuf); diff --git a/source/blender/nodes/composite/nodes/node_composite_diffMatte.c b/source/blender/nodes/composite/nodes/node_composite_diffMatte.c index 9f4af0e0d33..f3cb223079f 100644 --- a/source/blender/nodes/composite/nodes/node_composite_diffMatte.c +++ b/source/blender/nodes/composite/nodes/node_composite_diffMatte.c @@ -91,7 +91,7 @@ static void node_composit_exec_diff_matte(void *data, bNode *node, bNodeStack ** CompBuf *outbuf= NULL; CompBuf *imbuf1= NULL; CompBuf *imbuf2= NULL; - NodeChroma *c; + /* NodeChroma *c; */ /* UNUSED */ /*is anything connected?*/ if(out[0]->hasoutput==0 && out[1]->hasoutput==0) return; @@ -107,7 +107,7 @@ static void node_composit_exec_diff_matte(void *data, bNode *node, bNodeStack ** imbuf2=typecheck_compbuf(in[1]->data, CB_RGBA); } - c=node->storage; + /* c=node->storage; */ /* UNUSED */ outbuf=dupalloc_compbuf(imbuf1); /* note, processor gets a keyvals array passed on as buffer constant */ diff --git a/source/blender/nodes/intern/node_common.c b/source/blender/nodes/intern/node_common.c index d7830b6a260..35f2dbf7b32 100644 --- a/source/blender/nodes/intern/node_common.c +++ b/source/blender/nodes/intern/node_common.c @@ -826,11 +826,11 @@ bNodeTemplate node_forloop_template(bNode *node) void node_forloop_init(bNodeTree *ntree, bNode *node, bNodeTemplate *ntemp) { - bNodeSocket *sock; + /* bNodeSocket *sock; */ /* UNUSED */ node->id = (ID*)ntemp->ngroup; - sock = nodeAddInputFloat(ntree, node, "Iterations", PROP_UNSIGNED, 1, 0, 10000); + /* sock = */ nodeAddInputFloat(ntree, node, "Iterations", PROP_UNSIGNED, 1, 0, 10000); /* NB: group socket input/output roles are inverted internally! * Group "inputs" work as outputs in links and vice versa. @@ -932,11 +932,11 @@ void node_loop_update_tree(bNodeTree *ngroup) void node_whileloop_init(bNodeTree *ntree, bNode *node, bNodeTemplate *ntemp) { - bNodeSocket *sock; + /* bNodeSocket *sock; */ /* UNUSED */ node->id = (ID*)ntemp->ngroup; - sock = nodeAddInputFloat(ntree, node, "Condition", PROP_NONE, 1, 0, 1); + /* sock = */ nodeAddInputFloat(ntree, node, "Condition", PROP_NONE, 1, 0, 1); /* max iterations */ node->custom1 = 10000; diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index ba7af235acc..a15662f86f4 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -981,7 +981,7 @@ static void flag_render_node_material(Render *re, bNodeTree *ntree) } } -static Material *give_render_material(Render *re, Object *ob, int nr) +static Material *give_render_material(Render *re, Object *ob, short nr) { extern Material defmaterial; /* material.c */ Material *ma; @@ -2688,7 +2688,8 @@ static void init_render_dm(DerivedMesh *dm, Render *re, ObjectRen *obr, int timeoffset, float *orco, float mat[4][4]) { Object *ob= obr->ob; - int a, a1, end, totvert, vertofs; + int a, end, totvert, vertofs; + short mat_iter; VertRen *ver; VlakRen *vlr; MVert *mvert = NULL; @@ -2718,16 +2719,16 @@ static void init_render_dm(DerivedMesh *dm, Render *re, ObjectRen *obr, /* faces in order of color blocks */ vertofs= obr->totvert - totvert; - for(a1=0; (a1<ob->totcol || (a1==0 && ob->totcol==0)); a1++) { + for(mat_iter= 0; (mat_iter < ob->totcol || (mat_iter==0 && ob->totcol==0)); mat_iter++) { - ma= give_render_material(re, ob, a1+1); + ma= give_render_material(re, ob, mat_iter+1); end= dm->getNumFaces(dm); mface= dm->getFaceArray(dm); for(a=0; a<end; a++, mface++) { int v1, v2, v3, v4, flag; - if( mface->mat_nr==a1 ) { + if(mface->mat_nr == mat_iter) { float len; v1= mface->v1; diff --git a/source/blender/render/intern/source/pixelshading.c b/source/blender/render/intern/source/pixelshading.c index dd5deddece9..5c5162d268b 100644 --- a/source/blender/render/intern/source/pixelshading.c +++ b/source/blender/render/intern/source/pixelshading.c @@ -306,7 +306,7 @@ int shadeHaloFloat(HaloRen *har, float *col, int zz, /* soften the halo if it intersects geometry */ if(har->mat && har->mat->mode & MA_HALO_SOFT) { - float segment_length, halo_depth, distance_from_z, visible_depth, soften; + float segment_length, halo_depth, distance_from_z /* , visible_depth */ /* UNUSED */, soften; /* calculate halo depth */ segment_length= har->hasize*sasqrt(1.0f - dist/(har->rad*har->rad)); @@ -317,7 +317,7 @@ int shadeHaloFloat(HaloRen *har, float *col, int zz, /* calculate how much of this depth is visible */ distance_from_z = haloZtoDist(zz) - haloZtoDist(har->zs); - visible_depth = halo_depth; + /* visible_depth = halo_depth; */ /* UNUSED */ if(distance_from_z < segment_length) { soften= (segment_length + distance_from_z)/halo_depth; diff --git a/source/blender/render/intern/source/pointdensity.c b/source/blender/render/intern/source/pointdensity.c index 980f6b6af1e..36ded5c10d2 100644 --- a/source/blender/render/intern/source/pointdensity.c +++ b/source/blender/render/intern/source/pointdensity.c @@ -107,7 +107,7 @@ static void pointdensity_cache_psys(Render *re, PointDensity *pd, Object *ob, Pa ParticleSimulationData sim= {NULL}; ParticleData *pa=NULL; float cfra = BKE_curframe(re->scene); - int i, childexists; + int i /*, childexists*/ /* UNUSED */; int total_particles, offset=0; int data_used = point_data_used(pd); float partco[3]; @@ -143,9 +143,11 @@ static void pointdensity_cache_psys(Render *re, PointDensity *pd, Object *ob, Pa pd->totpoints = total_particles; if (data_used & POINT_DATA_VEL) offset = pd->totpoints*3; +#if 0 /* UNUSED */ if (psys->totchild > 0 && !(psys->part->draw & PART_DRAW_PARENT)) childexists = 1; - +#endif + for (i=0, pa=psys->particles; i < total_particles; i++, pa++) { state.time = cfra; diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c index ad592609ce6..641fec90cf3 100644 --- a/source/blender/render/intern/source/render_texture.c +++ b/source/blender/render/intern/source/render_texture.c @@ -1994,7 +1994,7 @@ static int ntap_bump_compute(NTapBump *ntap_bump, ShadeInput *shi, MTex *mtex, T else { /* same as above, but doing 5 taps, increasing quality at cost of speed */ float STc[3], STl[3], STr[3], STd[3], STu[3]; - float Hc, Hl, Hr, Hd, Hu; + float /* Hc, */ /* UNUSED */ Hl, Hr, Hd, Hu; texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt); @@ -2017,7 +2017,7 @@ static int ntap_bump_compute(NTapBump *ntap_bump, ShadeInput *shi, MTex *mtex, T // use texres for the center sample, set rgbnor rgbnor = multitex_mtex(shi, mtex, STc, dxt, dyt, texres); - Hc = (fromrgb)? RGBTOBW(texres->tr, texres->tg, texres->tb) : texres->tin; + /* Hc = (fromrgb)? RGBTOBW(texres->tr, texres->tg, texres->tb) : texres->tin; */ /* UNUSED */ // use ttexr for the other taps multitex_mtex(shi, mtex, STl, dxt, dyt, &ttexr); diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index 59a505a3195..bc5e7f23e21 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -992,7 +992,7 @@ static void convert_to_key_alpha(RenderPart *pa, RenderLayer *rl) } /* adds only alpha values */ -void edge_enhance_tile(RenderPart *pa, float *rectf, int *rectz) +static void edge_enhance_tile(RenderPart *pa, float *rectf, int *rectz) { /* use zbuffer to define edges, add it to the image */ int y, x, col, *rz, *rz1, *rz2, *rz3; @@ -1133,7 +1133,7 @@ typedef struct ZbufSolidData { float *edgerect; } ZbufSolidData; -void make_pixelstructs(RenderPart *pa, ZSpan *zspan, int sample, void *data) +static void make_pixelstructs(RenderPart *pa, ZSpan *zspan, int sample, void *data) { ZbufSolidData *sdata= (ZbufSolidData*)data; ListBase *lb= sdata->psmlist; @@ -1515,7 +1515,7 @@ static void shade_sample_sss(ShadeSample *ssamp, Material *mat, ObjectInstanceRe { ShadeInput *shi= ssamp->shi; ShadeResult shr; - float texfac, orthoarea, nor[3], alpha, sx, sy; + float /* texfac,*/ /* UNUSED */ orthoarea, nor[3], alpha, sx, sy; /* cache for shadow */ shi->samplenr= R.shadowsamplenr[shi->thread]++; @@ -1578,7 +1578,7 @@ static void shade_sample_sss(ShadeSample *ssamp, Material *mat, ObjectInstanceRe VECCOPY(color, shr.combined); /* texture blending */ - texfac= shi->mat->sss_texfac; + /* texfac= shi->mat->sss_texfac; */ /* UNUSED */ alpha= shr.combined[3]; *area *= alpha; diff --git a/source/blender/render/intern/source/shadeoutput.c b/source/blender/render/intern/source/shadeoutput.c index 431b2839c25..41d12c6065e 100644 --- a/source/blender/render/intern/source/shadeoutput.c +++ b/source/blender/render/intern/source/shadeoutput.c @@ -1502,12 +1502,12 @@ static void shade_lamp_loop_only_shadow(ShadeInput *shi, ShadeResult *shr) LampRen *lar; GroupObject *go; float inpr, lv[3]; - float *view, shadfac[4]; + float /* *view, */ shadfac[4]; float ir, accum, visifac, lampdist; float shaded = 0.0f, lightness = 0.0f; - view= shi->view; + /* view= shi->view; */ /* UNUSED */ accum= ir= 0.0f; lights= get_lights(shi); diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c index ac56304bdcb..f36994e0969 100644 --- a/source/blender/render/intern/source/zbuf.c +++ b/source/blender/render/intern/source/zbuf.c @@ -2864,7 +2864,7 @@ void RE_zbuf_accumulate_vecblur(NodeBlurData *nbd, int xsize, int ysize, float * float v1[3], v2[3], v3[3], v4[3], fx, fy; float *rectvz, *dvz, *dimg, *dvec1, *dvec2, *dz, *dz1, *dz2, *rectz; float *minvecbufrect= NULL, *rectweight, *rw, *rectmax, *rm, *ro; - float maxspeedsq= (float)nbd->maxspeed*nbd->maxspeed, totfac; + float maxspeedsq= (float)nbd->maxspeed*nbd->maxspeed; int y, x, step, maxspeed=nbd->maxspeed, samples= nbd->samples; int tsktsk= 0; static int firsttime= 1; @@ -3038,7 +3038,6 @@ void RE_zbuf_accumulate_vecblur(NodeBlurData *nbd, int xsize, int ysize, float * } memset(newrect, 0, sizeof(float)*xsize*ysize*4); - totfac= 0.0f; /* accumulate */ samples/= 2; diff --git a/source/blender/windowmanager/intern/wm_gesture.c b/source/blender/windowmanager/intern/wm_gesture.c index de4afa79448..52c0cb902c1 100644 --- a/source/blender/windowmanager/intern/wm_gesture.c +++ b/source/blender/windowmanager/intern/wm_gesture.c @@ -232,7 +232,7 @@ static void wm_gesture_draw_circle(wmGesture *gt) static void draw_filled_lasso(wmGesture *gt) { EditVert *v=NULL, *lastv=NULL, *firstv=NULL; - EditEdge *e; + /* EditEdge *e; */ /* UNUSED */ EditFace *efa; short *lasso= (short *)gt->customdata; int i; @@ -246,7 +246,7 @@ static void draw_filled_lasso(wmGesture *gt) v = BLI_addfillvert(co); if (lastv) - e = BLI_addfilledge(lastv, v); + /* e = */ /* UNUSED */ BLI_addfilledge(lastv, v); lastv = v; if (firstv==NULL) firstv = v; } diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index d4b43cd7ac1..2c2fd052b5d 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -144,6 +144,8 @@ extern "C" { #include "BKE_cdderivedmesh.h" #include "BKE_DerivedMesh.h" #include "BKE_material.h" /* give_current_material */ +#include "BKE_image.h" +#include "IMB_imbuf_types.h" extern Material defmaterial; /* material.c */ } @@ -195,7 +197,7 @@ extern "C" { } #endif -static int default_face_mode = TF_DYNAMIC; +static bool default_light_mode = 0; static unsigned int KX_rgbaint2uint_new(unsigned int icol) { @@ -234,9 +236,9 @@ static unsigned int KX_Mcol2uint_new(MCol col) return out_color.integer; } -static void SetDefaultFaceType(Scene* scene) +static void SetDefaultLightMode(Scene* scene) { - default_face_mode = TF_DYNAMIC; + default_light_mode = false; Scene *sce_iter; Base *base; @@ -244,7 +246,7 @@ static void SetDefaultFaceType(Scene* scene) { if (base->object->type == OB_LAMP) { - default_face_mode = TF_DYNAMIC|TF_LIGHT; + default_light_mode = true; return; } } @@ -353,41 +355,41 @@ bool ConvertMaterial( // use lighting? material->ras_mode |= ( mat->mode & MA_SHLESS )?0:USE_LIGHT; + material->ras_mode |= ( mat->game.flag & GEMAT_BACKCULL )?0:TWOSIDED; + // cast shadows? material->ras_mode |= ( mat->mode & MA_SHADBUF )?CAST_SHADOW:0; MTex *mttmp = 0; numchan = getNumTexChannels(mat); int valid_index = 0; - // use the face texture if - // 1) it is set in the buttons - // 2) we have a face texture and a material but no valid texture in slot 1 + /* In Multitexture use the face texture if and only if + * it is set in the buttons + * In GLSL is not working yet :/ 3.2011 */ bool facetex = false; if(validface && mat->mode &MA_FACETEXTURE) facetex = true; - if(validface && !mat->mtex[0]) - facetex = true; - if(validface && mat->mtex[0]) { - MTex *tmp = mat->mtex[0]; - if(!tmp->tex || (tmp->tex && !tmp->tex->ima)) - facetex = true; - } + numchan = numchan>MAXTEX?MAXTEX:numchan; + if (facetex && numchan == 0) numchan = 1; // foreach MTex for(int i=0; i<numchan; i++) { // use face tex if(i==0 && facetex ) { + facetex = false; Image*tmp = (Image*)(tface->tpage); if(tmp) { material->img[i] = tmp; material->texname[i] = material->img[i]->id.name; - material->flag[i] |= ( tface->transp &TF_ALPHA )?USEALPHA:0; - material->flag[i] |= ( tface->transp &TF_ADD )?CALCALPHA:0; material->flag[i] |= MIPMAP; + material->flag[i] |= ( mat->game.alpha_blend & GEMAT_ALPHA_SORT )?USEALPHA:0; + material->flag[i] |= ( mat->game.alpha_blend & GEMAT_ALPHA )?USEALPHA:0; + material->flag[i] |= ( mat->game.alpha_blend & GEMAT_ADD )?CALCALPHA:0; + if(material->img[i]->flag & IMA_REFLECT) material->mapping[i].mapping |= USEREFL; else @@ -405,11 +407,6 @@ bool ConvertMaterial( material->mapping[i].mapping |= USEUV; } - if(material->ras_mode & USE_LIGHT) - material->ras_mode &= ~USE_LIGHT; - if(tface->mode & TF_LIGHT) - material->ras_mode |= USE_LIGHT; - valid_index++; } else { @@ -567,25 +564,31 @@ bool ConvertMaterial( material->ras_mode |= (mat->material_type == MA_TYPE_WIRE)? WIRE: 0; } - else { + else { // No Material int valid = 0; // check for tface tex to fallback on if( validface ){ - - // no light bugfix - if(tface->mode) material->ras_mode |= USE_LIGHT; - material->img[0] = (Image*)(tface->tpage); // ------------------------ if(material->img[0]) { material->texname[0] = material->img[0]->id.name; material->mapping[0].mapping |= ( (material->img[0]->flag & IMA_REFLECT)!=0 )?USEREFL:0; - material->flag[0] |= ( tface->transp &TF_ALPHA )?USEALPHA:0; - material->flag[0] |= ( tface->transp &TF_ADD )?CALCALPHA:0; + + /* see if depth of the image is 32bits */ + if(BKE_image_has_alpha(material->img[0])) { + material->flag[0] |= USEALPHA; + material->alphablend = GEMAT_ALPHA; + } + else + material->alphablend = GEMAT_SOLID; + valid++; } } + else + material->alphablend = GEMAT_SOLID; + material->SetUsers(-1); material->num_enabled = valid; material->IdMode = TEXFACE; @@ -598,6 +601,9 @@ bool ConvertMaterial( material->matcolor[2] = 0.5f; material->spec_f = 0.5f; material->ref = 0.8f; + + // No material - old default TexFace properties + material->ras_mode |= USE_LIGHT; } MT_Point2 uv[4]; MT_Point2 uv2[4]; @@ -606,13 +612,10 @@ bool ConvertMaterial( uv2[0]= uv2[1]= uv2[2]= uv2[3]= MT_Point2(0.0f, 0.0f); + /* No material, what to do? let's see what is in the UV and set the material accordingly + light and visible is always on */ if( validface ) { - - material->ras_mode |= (tface->mode & TF_INVISIBLE)?0:POLY_VIS; - - material->transp = tface->transp; material->tile = tface->tile; - material->mode = tface->mode; uv[0].setValue(tface->uv[0]); uv[1].setValue(tface->uv[1]); @@ -625,31 +628,26 @@ bool ConvertMaterial( } else { // nothing at all - material->ras_mode |= (POLY_VIS| (validmat?0:USE_LIGHT)); - material->mode = default_face_mode; - material->transp = TF_SOLID; + material->alphablend = GEMAT_SOLID; material->tile = 0; uv[0]= uv[1]= uv[2]= uv[3]= MT_Point2(0.0f, 0.0f); } + if (validmat && validface) { + material->alphablend = mat->game.alpha_blend; + } + // with ztransp enabled, enforce alpha blending mode - if(validmat && (mat->mode & MA_TRANSP) && (mat->mode & MA_ZTRANSP) && (material->transp == TF_SOLID)) - material->transp = TF_ALPHA; + if(validmat && (mat->mode & MA_TRANSP) && (mat->mode & MA_ZTRANSP) && (material->alphablend == GEMAT_SOLID)) + material->alphablend = GEMAT_ALPHA; // always zsort alpha + add - if((material->transp == TF_ALPHA || material->transp == TF_ADD || texalpha) && (material->transp != TF_CLIP)) { + if((ELEM3(material->alphablend, GEMAT_ALPHA, GEMAT_ALPHA_SORT, GEMAT_ADD) || texalpha) && (material->alphablend != GEMAT_CLIP )) { material->ras_mode |= ALPHA; - material->ras_mode |= (material->mode & TF_ALPHASORT)? ZSORT: 0; + material->ras_mode |= (mat && (mat->game.alpha_blend & GEMAT_ALPHA_SORT))? ZSORT: 0; } - // collider or not? - material->ras_mode |= (material->mode & TF_DYNAMIC)? COLLIDER: 0; - - // these flags are irrelevant at this point, remove so they - // don't hurt material bucketing - material->mode &= ~(TF_DYNAMIC|TF_ALPHASORT|TF_TEX); - // get uv sets if(validmat) { @@ -706,8 +704,8 @@ bool ConvertMaterial( unsigned int rgb[4]; GetRGB(type,mface,mmcol,mat,rgb[0],rgb[1],rgb[2], rgb[3]); - // swap the material color, so MCol on TF_BMFONT works - if (validmat && type==1 && (tface && tface->mode & TF_BMFONT)) + // swap the material color, so MCol on bitmap font works + if (validmat && type==1 && (mat->game.flag & GEMAT_TEXT)) { rgb[0] = KX_rgbaint2uint_new(rgb[0]); rgb[1] = KX_rgbaint2uint_new(rgb[1]); @@ -864,10 +862,6 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene, ConvertMaterial(bl_mat, ma, tface, tfaceName, mface, mcol, layers, converter->GetGLSLMaterials()); - visible = ((bl_mat->ras_mode & POLY_VIS)!=0); - collider = ((bl_mat->ras_mode & COLLIDER)!=0); - twoside = ((bl_mat->mode & TF_TWOSIDE)!=0); - /* vertex colors and uv's were stored in bl_mat temporarily */ bl_mat->GetConversionRGB(rgb); rgb0 = rgb[0]; rgb1 = rgb[1]; @@ -885,7 +879,7 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene, if (kx_blmat == NULL) kx_blmat = new KX_BlenderMaterial(); - kx_blmat->Initialize(scene, bl_mat); + kx_blmat->Initialize(scene, bl_mat, (ma?&ma->game:NULL)); polymat = static_cast<RAS_IPolyMaterial*>(kx_blmat); } else { @@ -893,37 +887,59 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene, Image* bima = (tface)? (Image*)tface->tpage: NULL; imastr = (tface)? (bima? (bima)->id.name : "" ) : ""; - char transp=0; - short mode=0, tile=0; + char alpha_blend=0; + short tile=0; int tilexrep=4,tileyrep = 4; - + + /* set material properties - old TexFace */ + if (ma) { + alpha_blend = ma->game.alpha_blend; + /* Commented out for now. If we ever get rid of + * "Texture Face/Singletexture" we can then think about it */ + + /* Texture Face mode ignores texture but requires "Face Textures to be True "*/ + /** + if ((ma->mode &MA_FACETEXTURE)==0 && (ma->game.flag &GEMAT_TEXT)==0) { + bima = NULL; + imastr = ""; + alpha_blend = GEMAT_SOLID; + } + else + alpha_blend = ma->game.alpha_blend; + */ + } + /* check for tface tex to fallback on */ + else { + if (bima) { + /* see if depth of the image is 32 */ + if (BKE_image_has_alpha(bima)) + alpha_blend = GEMAT_ALPHA; + else + alpha_blend = GEMAT_SOLID; + } + else { + alpha_blend = GEMAT_SOLID; + } + } + if (bima) { tilexrep = bima->xrep; tileyrep = bima->yrep; } - /* get tface properties if available */ + /* set UV properties */ if(tface) { - /* TF_DYNAMIC means the polygon is a collision face */ - collider = ((tface->mode & TF_DYNAMIC) != 0); - transp = tface->transp; - tile = tface->tile; - mode = tface->mode; - - visible = !(tface->mode & TF_INVISIBLE); - twoside = ((tface->mode & TF_TWOSIDE)!=0); - uv0.setValue(tface->uv[0]); uv1.setValue(tface->uv[1]); uv2.setValue(tface->uv[2]); if (mface->v4) uv3.setValue(tface->uv[3]); + + tile = tface->tile; } else { - /* no texfaces, set COLLSION true and everything else FALSE */ - mode = default_face_mode; - transp = TF_SOLID; + /* no texfaces */ tile = 0; } @@ -964,16 +980,20 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene, if (mface->v4) rgb3 = KX_rgbaint2uint_new(color); } - + // only zsort alpha + add - bool alpha = (transp == TF_ALPHA || transp == TF_ADD); - bool zsort = (mode & TF_ALPHASORT)? alpha: 0; + bool alpha = ELEM3(alpha_blend, GEMAT_ALPHA, GEMAT_ADD, GEMAT_ALPHA_SORT); + bool zsort = (alpha_blend == GEMAT_ALPHA_SORT); + bool light = (ma)?(ma->mode & MA_SHLESS)==0:default_light_mode; + + // don't need zort anymore, deal as if it it's alpha blend + if (alpha_blend == GEMAT_ALPHA_SORT) alpha_blend = GEMAT_ALPHA; if (kx_polymat == NULL) kx_polymat = new KX_PolygonMaterial(); kx_polymat->Initialize(imastr, ma, (int)mface->mat_nr, tile, tilexrep, tileyrep, - mode, transp, alpha, zsort, lightlayer, tface, (unsigned int*)mcol); + alpha_blend, alpha, zsort, light, lightlayer, tface, (unsigned int*)mcol); polymat = static_cast<RAS_IPolyMaterial*>(kx_polymat); if (ma) { @@ -987,6 +1007,19 @@ RAS_MeshObject* BL_ConvertMesh(Mesh* mesh, Object* blenderobj, KX_Scene* scene, } } + // set render flags + if (ma) + { + visible = ((ma->game.flag & GEMAT_INVISIBLE)==0); + twoside = ((ma->game.flag & GEMAT_BACKCULL)==0); + collider = ((ma->game.flag & GEMAT_NOPHYSICS)==0); + } + else{ + visible = true; + twoside = false; + collider = true; + } + /* mark face as flat, so vertices are split */ bool flat = (mface->flag & ME_SMOOTH) == 0; @@ -2035,7 +2068,7 @@ void BL_ConvertBlenderObjects(struct Main* maggie, logicmgr->RegisterActionName(curAct->id.name + 2, curAct); } - SetDefaultFaceType(blenderscene); + SetDefaultLightMode(blenderscene); // Let's support scene set. // Beware of name conflict in linked data, it will not crash but will create confusion // in Python scripting and in certain actuators (replace mesh). Linked scene *should* have diff --git a/source/gameengine/Ketsji/BL_BlenderShader.cpp b/source/gameengine/Ketsji/BL_BlenderShader.cpp index 4ae937cdcd6..6680e9556b9 100644 --- a/source/gameengine/Ketsji/BL_BlenderShader.cpp +++ b/source/gameengine/Ketsji/BL_BlenderShader.cpp @@ -27,7 +27,7 @@ BL_BlenderShader::BL_BlenderShader(KX_Scene *scene, struct Material *ma, int lig mGPUMat(NULL) { mBlenderScene = scene->GetBlenderScene(); - mBlendMode = GPU_BLEND_SOLID; + mAlphaBlend = GPU_BLEND_SOLID; ReloadMaterial(); } @@ -148,12 +148,12 @@ void BL_BlenderShader::Update(const RAS_MeshSlot & ms, RAS_IRasterizer* rasty ) GPU_material_bind_uniforms(gpumat, obmat, viewmat, viewinvmat, obcol); - mBlendMode = GPU_material_blend_mode(gpumat, obcol); + mAlphaBlend = GPU_material_alpha_blend(gpumat, obcol); } -int BL_BlenderShader::GetBlendMode() +int BL_BlenderShader::GetAlphaBlend() { - return mBlendMode; + return mAlphaBlend; } bool BL_BlenderShader::Equals(BL_BlenderShader *blshader) diff --git a/source/gameengine/Ketsji/BL_BlenderShader.h b/source/gameengine/Ketsji/BL_BlenderShader.h index 2f22e121b8c..f187d93d648 100644 --- a/source/gameengine/Ketsji/BL_BlenderShader.h +++ b/source/gameengine/Ketsji/BL_BlenderShader.h @@ -63,7 +63,7 @@ private: struct Scene *mBlenderScene; struct Material *mMat; int mLightLayer; - int mBlendMode; + int mAlphaBlend; GPUMaterial *mGPUMat; bool VerifyShader() @@ -86,7 +86,7 @@ public: void SetAttribs(class RAS_IRasterizer* ras, const BL_Material *mat); void Update(const class RAS_MeshSlot & ms, class RAS_IRasterizer* rasty); void ReloadMaterial(); - int GetBlendMode(); + int GetAlphaBlend(); void SetScene(KX_Scene *scene) { diff --git a/source/gameengine/Ketsji/BL_Material.cpp b/source/gameengine/Ketsji/BL_Material.cpp index 25fd5467e93..fd0756d067d 100644 --- a/source/gameengine/Ketsji/BL_Material.cpp +++ b/source/gameengine/Ketsji/BL_Material.cpp @@ -52,12 +52,11 @@ void BL_Material::Initialize() speccolor[0] = 1.f; speccolor[1] = 1.f; speccolor[2] = 1.f; - transp = 0; + alphablend = 0; hard = 50.f; spec_f = 0.5f; alpha = 1.f; emit = 0.f; - mode = 0; material = 0; tface = 0; materialindex = 0; diff --git a/source/gameengine/Ketsji/BL_Material.h b/source/gameengine/Ketsji/BL_Material.h index c0440e66501..2c6316ea32b 100644 --- a/source/gameengine/Ketsji/BL_Material.h +++ b/source/gameengine/Ketsji/BL_Material.h @@ -68,7 +68,7 @@ public: float matcolor[4]; float speccolor[3]; - short transp, pad; + short alphablend, pad; float hard, spec_f; float alpha, emit, color_blend[MAXTEX], ref; @@ -76,7 +76,6 @@ public: int blend_mode[MAXTEX]; - int mode; int num_enabled; BL_Mapping mapping[MAXTEX]; @@ -151,14 +150,16 @@ enum BL_flag // BL_Material::ras_mode enum BL_ras_mode { - POLY_VIS=1, + // POLY_VIS=1, COLLIDER=2, ZSORT=4, ALPHA=8, // TRIANGLE=16, USE_LIGHT=32, WIRE=64, - CAST_SHADOW=128 + CAST_SHADOW=128, + TEX=256, + TWOSIDED=512 }; // ------------------------------------- diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp index 33da17cc505..1a1e046f54c 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.cpp +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.cpp @@ -34,6 +34,8 @@ #include "DNA_meshdata_types.h" #include "BKE_mesh.h" // ------------------------------------ +#include "BLI_utildefines.h" + #define spit(x) std::cout << x << std::endl; BL_Shader *KX_BlenderMaterial::mLastShader = NULL; @@ -56,21 +58,24 @@ KX_BlenderMaterial::KX_BlenderMaterial() } void KX_BlenderMaterial::Initialize( - KX_Scene *scene, - BL_Material *data) + KX_Scene *scene, + BL_Material *data, + GameSettings *game) { RAS_IPolyMaterial::Initialize( - data->texname[0], - data->matname, - data->materialindex, - data->tile, - data->tilexrep[0], - data->tileyrep[0], - data->mode, - data->transp, - ((data->ras_mode &ALPHA)!=0), - ((data->ras_mode &ZSORT)!=0) - ); + data->texname[0], + data->matname, + data->materialindex, + data->tile, + data->tilexrep[0], + data->tileyrep[0], + data->alphablend, + ((data->ras_mode &ALPHA)!=0), + ((data->ras_mode &ZSORT)!=0), + ((data->ras_mode &USE_LIGHT)!=0), + ((data->ras_mode &TEX)), + game + ); mMaterial = data; mShader = 0; mBlenderShader = 0; @@ -99,7 +104,7 @@ void KX_BlenderMaterial::Initialize( for(int i=0; i<mMaterial->num_enabled; i++) { m_multimode += (mMaterial->flag[i] + mMaterial->blend_mode[i]); } - m_multimode += mMaterial->IdMode+ (mMaterial->ras_mode & ~(COLLIDER|USE_LIGHT)); + m_multimode += mMaterial->IdMode+ (mMaterial->ras_mode & ~(USE_LIGHT)); } KX_BlenderMaterial::~KX_BlenderMaterial() @@ -231,7 +236,7 @@ void KX_BlenderMaterial::OnExit() } if( mMaterial->tface ) - GPU_set_tpage(mMaterial->tface, 1); + GPU_set_tpage(mMaterial->tface, 1, mMaterial->alphablend); } @@ -247,7 +252,7 @@ void KX_BlenderMaterial::setShaderData( bool enable, RAS_IRasterizer *ras) mLastShader = NULL; } - ras->SetBlendingMode(TF_SOLID); + ras->SetAlphaBlend(TF_SOLID); BL_Texture::DisableAllTextures(); return; } @@ -268,11 +273,11 @@ void KX_BlenderMaterial::setShaderData( bool enable, RAS_IRasterizer *ras) } if(!mUserDefBlend) { - ras->SetBlendingMode(mMaterial->transp); + ras->SetAlphaBlend(mMaterial->alphablend); } else { - ras->SetBlendingMode(TF_SOLID); - ras->SetBlendingMode(-1); // indicates custom mode + ras->SetAlphaBlend(TF_SOLID); + ras->SetAlphaBlend(-1); // indicates custom mode // tested to be valid enums glEnable(GL_BLEND); @@ -283,7 +288,7 @@ void KX_BlenderMaterial::setShaderData( bool enable, RAS_IRasterizer *ras) void KX_BlenderMaterial::setBlenderShaderData( bool enable, RAS_IRasterizer *ras) { if( !enable || !mBlenderShader->Ok() ) { - ras->SetBlendingMode(TF_SOLID); + ras->SetAlphaBlend(TF_SOLID); // frame cleanup. if(mLastBlenderShader) { @@ -297,7 +302,7 @@ void KX_BlenderMaterial::setBlenderShaderData( bool enable, RAS_IRasterizer *ras } if(!mBlenderShader->Equals(mLastBlenderShader)) { - ras->SetBlendingMode(mMaterial->transp); + ras->SetAlphaBlend(mMaterial->alphablend); if(mLastBlenderShader) mLastBlenderShader->SetProg(false); @@ -314,14 +319,14 @@ void KX_BlenderMaterial::setTexData( bool enable, RAS_IRasterizer *ras) BL_Texture::DisableAllTextures(); if( !enable ) { - ras->SetBlendingMode(TF_SOLID); + ras->SetAlphaBlend(TF_SOLID); return; } BL_Texture::ActivateFirst(); if( mMaterial->IdMode == DEFAULT_BLENDER ) { - ras->SetBlendingMode(mMaterial->transp); + ras->SetAlphaBlend(mMaterial->alphablend); return; } @@ -331,7 +336,7 @@ void KX_BlenderMaterial::setTexData( bool enable, RAS_IRasterizer *ras) mTextures[0].ActivateTexture(); mTextures[0].setTexEnv(0, true); mTextures[0].SetMapping(mMaterial->mapping[0].mapping); - ras->SetBlendingMode(mMaterial->transp); + ras->SetAlphaBlend(mMaterial->alphablend); } return; } @@ -354,11 +359,11 @@ void KX_BlenderMaterial::setTexData( bool enable, RAS_IRasterizer *ras) } if(!mUserDefBlend) { - ras->SetBlendingMode(mMaterial->transp); + ras->SetAlphaBlend(mMaterial->alphablend); } else { - ras->SetBlendingMode(TF_SOLID); - ras->SetBlendingMode(-1); // indicates custom mode + ras->SetAlphaBlend(TF_SOLID); + ras->SetAlphaBlend(-1); // indicates custom mode glEnable(GL_BLEND); glBlendFunc(mBlendFunc[0], mBlendFunc[1]); @@ -393,15 +398,15 @@ KX_BlenderMaterial::ActivatShaders( else tmp->setShaderData(false, rasty); - if(mMaterial->mode & RAS_IRasterizer::KX_TWOSIDE) + if (mMaterial->ras_mode &TWOSIDED) rasty->SetCullFace(false); else rasty->SetCullFace(true); - if (((mMaterial->ras_mode &WIRE)!=0) || (mMaterial->mode & RAS_IRasterizer::KX_LINES) || + if ((mMaterial->ras_mode &WIRE) || (rasty->GetDrawingMode() <= RAS_IRasterizer::KX_WIREFRAME)) { - if((mMaterial->ras_mode &WIRE)!=0) + if (mMaterial->ras_mode &WIRE) rasty->SetCullFace(false); rasty->SetLines(true); } @@ -438,15 +443,15 @@ KX_BlenderMaterial::ActivateBlenderShaders( else tmp->setBlenderShaderData(false, rasty); - if(mMaterial->mode & RAS_IRasterizer::KX_TWOSIDE) + if (mMaterial->ras_mode &TWOSIDED) rasty->SetCullFace(false); else rasty->SetCullFace(true); - if (((mMaterial->ras_mode & WIRE)!=0) || (mMaterial->mode & RAS_IRasterizer::KX_LINES) || + if ((mMaterial->ras_mode &WIRE) || (rasty->GetDrawingMode() <= RAS_IRasterizer::KX_WIREFRAME)) { - if((mMaterial->ras_mode &WIRE)!=0) + if (mMaterial->ras_mode &WIRE) rasty->SetCullFace(false); rasty->SetLines(true); } @@ -487,15 +492,15 @@ KX_BlenderMaterial::ActivateMat( else tmp->setTexData( false,rasty); - if(mMaterial->mode & RAS_IRasterizer::KX_TWOSIDE) + if (mMaterial->ras_mode &TWOSIDED) rasty->SetCullFace(false); else rasty->SetCullFace(true); - if (((mMaterial->ras_mode &WIRE)!=0) || (mMaterial->mode & RAS_IRasterizer::KX_LINES) || + if ((mMaterial->ras_mode &WIRE) || (rasty->GetDrawingMode() <= RAS_IRasterizer::KX_WIREFRAME)) { - if((mMaterial->ras_mode &WIRE)!=0) + if (mMaterial->ras_mode &WIRE) rasty->SetCullFace(false); rasty->SetLines(true); } @@ -570,17 +575,17 @@ void KX_BlenderMaterial::ActivateMeshSlot(const RAS_MeshSlot & ms, RAS_IRasteriz mShader->Update(ms, rasty); } else if(mBlenderShader && GLEW_ARB_shader_objects) { - int blendmode; + int alphablend; mBlenderShader->Update(ms, rasty); /* we do blend modes here, because they can change per object * with the same material due to obcolor/obalpha */ - blendmode = mBlenderShader->GetBlendMode(); - if((blendmode == TF_SOLID || blendmode == TF_ALPHA) && mMaterial->transp != TF_SOLID) - blendmode = mMaterial->transp; + alphablend = mBlenderShader->GetAlphaBlend(); + if(ELEM3(alphablend, GEMAT_SOLID, GEMAT_ALPHA, GEMAT_ALPHA_SORT) && mMaterial->alphablend != GEMAT_SOLID) + alphablend = mMaterial->alphablend; - rasty->SetBlendingMode(blendmode); + rasty->SetAlphaBlend(alphablend); } } diff --git a/source/gameengine/Ketsji/KX_BlenderMaterial.h b/source/gameengine/Ketsji/KX_BlenderMaterial.h index 766e20be825..236bd6afdc8 100644 --- a/source/gameengine/Ketsji/KX_BlenderMaterial.h +++ b/source/gameengine/Ketsji/KX_BlenderMaterial.h @@ -38,7 +38,8 @@ public: KX_BlenderMaterial(); void Initialize( class KX_Scene* scene, - BL_Material* mat + BL_Material* mat, + GameSettings* game ); virtual ~KX_BlenderMaterial(); diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp index d32f267f0e0..098c136bfa3 100644 --- a/source/gameengine/Ketsji/KX_PolygonMaterial.cpp +++ b/source/gameengine/Ketsji/KX_PolygonMaterial.cpp @@ -78,10 +78,10 @@ void KX_PolygonMaterial::Initialize( int tile, int tilexrep, int tileyrep, - int mode, - int transp, + int alphablend, bool alpha, bool zsort, + bool light, int lightlayer, struct MTFace* tface, unsigned int* mcol) @@ -93,10 +93,12 @@ void KX_PolygonMaterial::Initialize( tile, tilexrep, tileyrep, - mode, - transp, + alphablend, alpha, - zsort); + zsort, + light, + (texname && texname != ""?true:false), /* if we have a texture we have image */ + ma?&ma->game:NULL); m_tface = tface; m_mcol = mcol; m_material = ma; @@ -168,7 +170,7 @@ void KX_PolygonMaterial::DefaultActivate(RAS_IRasterizer* rasty, TCachingInfo& c if (GetCachingInfo() != cachingInfo) { if (!cachingInfo) - GPU_set_tpage(NULL, 0); + GPU_set_tpage(NULL, 0, 0); cachingInfo = GetCachingInfo(); @@ -176,15 +178,15 @@ void KX_PolygonMaterial::DefaultActivate(RAS_IRasterizer* rasty, TCachingInfo& c { Image *ima = (Image*)m_tface->tpage; GPU_update_image_time(ima, rasty->GetTime()); - GPU_set_tpage(m_tface, 1); + GPU_set_tpage(m_tface, 1, m_alphablend); } else - GPU_set_tpage(NULL, 0); + GPU_set_tpage(NULL, 0, 0); - if(m_drawingmode & RAS_IRasterizer::KX_TWOSIDE) - rasty->SetCullFace(false); - else + if(m_drawingmode & RAS_IRasterizer::KX_BACKCULL) rasty->SetCullFace(true); + else + rasty->SetCullFace(false); if ((m_drawingmode & RAS_IRasterizer::KX_LINES) || (rasty->GetDrawingMode() <= RAS_IRasterizer::KX_WIREFRAME)) @@ -318,7 +320,7 @@ KX_PYMETHODDEF_DOC(KX_PolygonMaterial, setTexture, "setTexture(tface)") if (PyArg_ParseTuple(args, "O!:setTexture", &PyCapsule_Type, &pytface)) { MTFace *tface = (MTFace*) PyCapsule_GetPointer(pytface, KX_POLYGONMATERIAL_CAPSULE_ID); - GPU_set_tpage(tface, 1); + GPU_set_tpage(tface, 1, m_alphablend); Py_RETURN_NONE; } diff --git a/source/gameengine/Ketsji/KX_PolygonMaterial.h b/source/gameengine/Ketsji/KX_PolygonMaterial.h index 3520995def3..b09ddd39141 100644 --- a/source/gameengine/Ketsji/KX_PolygonMaterial.h +++ b/source/gameengine/Ketsji/KX_PolygonMaterial.h @@ -78,10 +78,10 @@ public: int tile, int tilexrep, int tileyrep, - int mode, - int transp, + int alphablend, bool alpha, bool zsort, + bool light, int lightlayer, struct MTFace* tface, unsigned int* mcol); diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp index 5a1b52489b4..9948f48d7f3 100644 --- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp +++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp @@ -36,6 +36,7 @@ #include "DNA_image_types.h" #include "DNA_meshdata_types.h" +#include "DNA_material_types.h" void RAS_IPolyMaterial::Initialize( const STR_String& texname, @@ -44,10 +45,12 @@ void RAS_IPolyMaterial::Initialize( int tile, int tilexrep, int tileyrep, - int mode, - int transp, + int alphablend, bool alpha, - bool zsort) + bool zsort, + bool light, + bool image, + struct GameSettings* game) { m_texturename = texname; m_materialname = matname; @@ -55,10 +58,10 @@ void RAS_IPolyMaterial::Initialize( m_tile = tile; m_tilexrep = tilexrep; m_tileyrep = tileyrep; - m_drawingmode = mode; - m_transp = transp; + m_alphablend = alphablend; m_alpha = alpha; m_zsort = zsort; + m_light = light; m_polymatid = m_newpolymatid++; m_flag = 0; m_multimode = 0; @@ -66,6 +69,7 @@ void RAS_IPolyMaterial::Initialize( m_specular.setValue(0.5,0.5,0.5); m_specularity = 1.0; m_diffuse.setValue(0.5,0.5,0.5); + m_drawingmode = ConvertFaceMode(game, image); } RAS_IPolyMaterial::RAS_IPolyMaterial() @@ -75,9 +79,10 @@ RAS_IPolyMaterial::RAS_IPolyMaterial() m_tilexrep(0), m_tileyrep(0), m_drawingmode (0), - m_transp(0), + m_alphablend(0), m_alpha(false), m_zsort(false), + m_light(false), m_materialindex(0), m_polymatid(0), m_flag(0), @@ -95,8 +100,7 @@ RAS_IPolyMaterial::RAS_IPolyMaterial(const STR_String& texname, int tile, int tilexrep, int tileyrep, - int mode, - int transp, + int alphablend, bool alpha, bool zsort) : m_texturename(texname), @@ -104,8 +108,7 @@ RAS_IPolyMaterial::RAS_IPolyMaterial(const STR_String& texname, m_tile(tile), m_tilexrep(tilexrep), m_tileyrep(tileyrep), - m_drawingmode (mode), - m_transp(transp), + m_alphablend(alphablend), m_alpha(alpha), m_zsort(zsort), m_materialindex(materialindex), @@ -128,9 +131,9 @@ bool RAS_IPolyMaterial::Equals(const RAS_IPolyMaterial& lhs) const this->m_multimode == lhs.m_multimode && this->m_flag == lhs.m_flag && this->m_drawingmode == lhs.m_drawingmode && - this->m_transp == lhs.m_transp && - this->m_texturename.hash() == lhs.m_texturename.hash() && - this->m_materialname.hash() == lhs.m_materialname.hash() + this->m_alphablend == lhs.m_alphablend && + this->m_texturename.hash() == lhs.m_texturename.hash() && + this->m_materialname.hash() == lhs.m_materialname.hash() ); return test; @@ -141,9 +144,10 @@ bool RAS_IPolyMaterial::Equals(const RAS_IPolyMaterial& lhs) const this->m_tile == lhs.m_tile && this->m_tilexrep == lhs.m_tilexrep && this->m_tileyrep == lhs.m_tileyrep && - this->m_transp == lhs.m_transp && + this->m_alphablend == lhs.m_alphablend && this->m_alpha == lhs.m_alpha && this->m_zsort == lhs.m_zsort && + this->m_light == lhs.m_light && this->m_drawingmode == lhs.m_drawingmode && this->m_texturename.hash() == lhs.m_texturename.hash() && this->m_materialname.hash() == lhs.m_materialname.hash() @@ -151,6 +155,21 @@ bool RAS_IPolyMaterial::Equals(const RAS_IPolyMaterial& lhs) const } } +int RAS_IPolyMaterial::ConvertFaceMode(struct GameSettings *game, bool image) const +{ + if (!game) return (image?GEMAT_TEX:0); + + int modefinal = 0; + + int orimode = game->face_orientation; + int alpha_blend = game->alpha_blend; + int flags = game->flag & (GEMAT_TEXT | GEMAT_BACKCULL); + + modefinal = orimode | alpha_blend | flags; + modefinal |= (image ? GEMAT_TEX : 0); + + return modefinal; +} void RAS_IPolyMaterial::GetMaterialRGBAColor(unsigned char *rgba) const { @@ -241,7 +260,7 @@ bool RAS_IPolyMaterial::UsesLighting(RAS_IRasterizer *rasty) const else if(rasty->GetDrawingMode() < RAS_IRasterizer::KX_SOLID); else if(rasty->GetDrawingMode() == RAS_IRasterizer::KX_SHADOW); else - dolights = (m_drawingmode & RAS_IRasterizer::KX_LIGHT)!=0; + dolights = m_light; return dolights; } diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h index 2a5c6a179b6..69d07713c49 100644 --- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h +++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h @@ -49,6 +49,7 @@ struct Material; struct Image; struct Scene; class SCA_IScene; +struct GameSettings; enum MaterialProps { @@ -78,10 +79,11 @@ protected: STR_HashedString m_materialname; //also needed for touchsensor int m_tile; int m_tilexrep,m_tileyrep; - int m_drawingmode; // tface->mode - int m_transp; + int m_drawingmode; + int m_alphablend; bool m_alpha; bool m_zsort; + bool m_light; int m_materialindex; unsigned int m_polymatid; @@ -102,9 +104,9 @@ public: // care! these are taken from blender polygonflags, see file DNA_mesh_types.h for #define TF_BILLBOARD etc. enum MaterialFlags { - BILLBOARD_SCREENALIGNED = 256, - BILLBOARD_AXISALIGNED = 4096, - SHADOW =8192 + BILLBOARD_SCREENALIGNED = 512, /* GEMAT_HALO */ + BILLBOARD_AXISALIGNED = 1024, /* GEMAT_BILLBOARD */ + SHADOW =2048 /* GEMAT_SHADOW */ }; RAS_IPolyMaterial(); @@ -114,7 +116,6 @@ public: int tile, int tilexrep, int tileyrep, - int mode, int transp, bool alpha, bool zsort); @@ -124,10 +125,13 @@ public: int tile, int tilexrep, int tileyrep, - int mode, int transp, bool alpha, - bool zsort); + bool zsort, + bool light, + bool image, + struct GameSettings* game); + virtual ~RAS_IPolyMaterial() {}; /** @@ -174,6 +178,11 @@ public: virtual void Replace_IScene(SCA_IScene *val) {}; /* overridden by KX_BlenderMaterial */ + /** + * @return the equivalent drawing mode for the material settings (equivalent to old TexFace tface->mode). + */ + int ConvertFaceMode(struct GameSettings *game, bool image) const; + /* * PreCalculate texture gen */ diff --git a/source/gameengine/Rasterizer/RAS_IRasterizer.h b/source/gameengine/Rasterizer/RAS_IRasterizer.h index 877a7219a1c..2988aa4effb 100644 --- a/source/gameengine/Rasterizer/RAS_IRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_IRasterizer.h @@ -68,11 +68,7 @@ class RAS_IRasterizer public: RAS_IRasterizer(RAS_ICanvas* canv){}; virtual ~RAS_IRasterizer(){}; - /** - */ - enum { - RAS_RENDER_3DPOLYGON_TEXT = 16384 /* TF_BMFONT */ - }; + /** * Drawing types */ @@ -106,9 +102,9 @@ public: /** */ enum { - KX_TEX = 4, /* TF_TEX */ - KX_LIGHT = 16, /* TF_LIGHT */ - KX_TWOSIDE = 512, /* TF_TWOSIDE */ + RAS_RENDER_3DPOLYGON_TEXT = 64, /* GEMAT_TEXT */ + KX_BACKCULL = 16, /* GEMAT_BACKCULL */ + KX_TEX = 4096, /* GEMAT_TEX */ KX_LINES = 32768 }; @@ -417,7 +413,7 @@ public: virtual int GetMotionBlurState()=0; virtual void SetMotionBlurState(int newstate)=0; - virtual void SetBlendingMode(int blendmode)=0; + virtual void SetAlphaBlend(int alphablend)=0; virtual void SetFrontFace(bool ccw)=0; virtual void SetAnisotropicFiltering(short level)=0; diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp index 6ad9e591474..d9039a2a68d 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp @@ -89,7 +89,7 @@ RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas) m_motionblurvalue(-1.0), m_texco_num(0), m_attrib_num(0), - //m_last_blendmode(GPU_BLEND_SOLID), + //m_last_alphablend(GPU_BLEND_SOLID), m_last_frontface(true), m_materialCachingInfo(0) { @@ -126,8 +126,8 @@ bool RAS_OpenGLRasterizer::Init() glDisable(GL_BLEND); glDisable(GL_ALPHA_TEST); - //m_last_blendmode = GPU_BLEND_SOLID; - GPU_set_material_blend_mode(GPU_BLEND_SOLID); + //m_last_alphablend = GPU_BLEND_SOLID; + GPU_set_material_alpha_blend(GPU_BLEND_SOLID); glFrontFace(GL_CCW); m_last_frontface = true; @@ -303,8 +303,8 @@ bool RAS_OpenGLRasterizer::BeginFrame(int drawingmode, double time) glDisable(GL_BLEND); glDisable(GL_ALPHA_TEST); - //m_last_blendmode = GPU_BLEND_SOLID; - GPU_set_material_blend_mode(GPU_BLEND_SOLID); + //m_last_alphablend = GPU_BLEND_SOLID; + GPU_set_material_alpha_blend(GPU_BLEND_SOLID); glFrontFace(GL_CCW); m_last_frontface = true; @@ -873,10 +873,10 @@ void RAS_OpenGLRasterizer::IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi) // MCol *mcol = (MCol*)ms.m_pDerivedMesh->getFaceDataArray(ms.m_pDerivedMesh, CD_MCOL); /* UNUSED */ // handle two-side - if (current_polymat->GetDrawingMode() & RAS_IRasterizer::KX_TWOSIDE) - this->SetCullFace(false); - else + if (current_polymat->GetDrawingMode() & RAS_IRasterizer::KX_BACKCULL) this->SetCullFace(true); + else + this->SetCullFace(false); if (current_polymat->GetFlag() & RAS_BLENDERGLSL) { // GetMaterialIndex return the original mface material index, @@ -890,9 +890,9 @@ void RAS_OpenGLRasterizer::IndexPrimitivesInternal(RAS_MeshSlot& ms, bool multi) else memset(¤t_gpu_attribs, 0, sizeof(current_gpu_attribs)); // DM draw can mess up blending mode, restore at the end - int current_blend_mode = GPU_get_material_blend_mode(); + int current_blend_mode = GPU_get_material_alpha_blend(); ms.m_pDerivedMesh->drawFacesGLSL(ms.m_pDerivedMesh, CheckMaterialDM); - GPU_set_material_blend_mode(current_blend_mode); + GPU_set_material_alpha_blend(current_blend_mode); } else { //ms.m_pDerivedMesh->drawMappedFacesTex(ms.m_pDerivedMesh, CheckTexfaceDM, mcol); current_blmat_nr = current_polymat->GetMaterialIndex(); @@ -1204,36 +1204,36 @@ void RAS_OpenGLRasterizer::DisableMotionBlur() m_motionblurvalue = -1.0; } -void RAS_OpenGLRasterizer::SetBlendingMode(int blendmode) +void RAS_OpenGLRasterizer::SetAlphaBlend(int alphablend) { - GPU_set_material_blend_mode(blendmode); + GPU_set_material_alpha_blend(alphablend); /* - if(blendmode == m_last_blendmode) + if(alphablend == m_last_alphablend) return; - if(blendmode == GPU_BLEND_SOLID) { + if(alphablend == GPU_BLEND_SOLID) { glDisable(GL_BLEND); glDisable(GL_ALPHA_TEST); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } - else if(blendmode == GPU_BLEND_ADD) { + else if(alphablend == GPU_BLEND_ADD) { glBlendFunc(GL_ONE, GL_ONE); glEnable(GL_BLEND); glDisable(GL_ALPHA_TEST); } - else if(blendmode == GPU_BLEND_ALPHA) { + else if(alphablend == GPU_BLEND_ALPHA) { glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GREATER, 0.0f); } - else if(blendmode == GPU_BLEND_CLIP) { + else if(alphablend == GPU_BLEND_CLIP) { glDisable(GL_BLEND); glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GREATER, 0.5f); } - m_last_blendmode = blendmode; + m_last_alphablend = alphablend; */ } diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h index c0e02f6df77..cbfa49510a5 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h @@ -111,7 +111,7 @@ protected: TexCoGen m_attrib[RAS_MAX_ATTRIB]; int m_texco_num; int m_attrib_num; - //int m_last_blendmode; + //int m_last_alphablend; bool m_last_frontface; /** Stores the caching information for the last material activated. */ @@ -312,7 +312,7 @@ public: m_motionblur = newstate; }; - virtual void SetBlendingMode(int blendmode); + virtual void SetAlphaBlend(int alphablend); virtual void SetFrontFace(bool ccw); virtual void SetAnisotropicFiltering(short level); |